Swift初心者がアプリ開発を行い学んだこと・感じたこと

## はじめに
[アイスタイル Advent Calendar2024](https://qiita.com/advent-calendar/2024/istyle)の24日目の記事です。🎄

24卒のエンジニア職として4月に入社しました髙橋柊吾です。
時間が経つのは早いもので8月にアプリチームへ配属され早くも12月となってしまいました。

さて、本題です。

アプリチームに配属されるまでアプリ開発をしたことがない、MacBookすらも触ったことがなかった私がアプリチームに配属されて思ったことや感じたことをお話ししていきます。

## Swiftの特徴と開発手法の違い
[Swift](https://developer.apple.com/jp/swift/)とはApple社が開発したオープンソースのプログラミング言語です。主にApple社製品向けのiOSアプリやMacアプリの開発に使用されています。Swiftが使われる理由としては、Apple製品との相性が良く、他のプログラミング言語を使うよりも開発が容易になるからです。

iOSの[@cosmeアプリ](https://apps.apple.com/jp/app/cosme-%E3%82%A2%E3%83%83%E3%83%88%E3%82%B3%E3%82%B9%E3%83%A1-%E5%8C%96%E7%B2%A7%E5%93%81-%E3%82%B3%E3%82%B9%E3%83%A1%E3%83%A9%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0-%E3%81%8A%E8%B2%B7%E7%89%A9/id793054713)もこのSwiftがメインで使用されています。

Swiftには大きく分けて2つの開発方法があります。SwiftUIとUIKit(UIKitのInterface BuilderとしてStoryboardやXIBがある)です。

簡単にですが、今回はSwiftUIとStoryboardについて下記に特徴を述べます。

### SwiftUI
- コードで作成でき、プレビューで確認しながら部品を作ることができる
- iOS13以降のサポート

![SwiftUI開発のイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938513/62dd1c5f-eb61-7219-2791-561c75109539.png)

*▲ SwiftUIの開発イメージ（コードでUIを記述します）*

### Storyboard
- GUIエディタでドラッグ&ドロップを用いて作成可能なので直感的に使いやすい
- 同じUIを複数の画面で使いたい場合は、別のXIBファイルを生成するか、手動でコピーが必要なので、コンポーネントの再利用に手間がかかる
- iOS5以降全てのバージョンに対応

![Storyboardの開発のイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3938513/5e03a59c-a467-538b-865c-afa90137dae6.png)

*▲ Storyboardの開発イメージ(GUIエディタで作成可能)*

### StoryboardとViewControllerの関係性
ViewControllerとは、iOSアプリにおける1つの画面を制御するためのクラスです。
各画面のUIロジックやデータ処理を担当し、ユーザーの操作に応じた動作（ボタン押下など）を定義します。
StoryboardはUIを視覚的に作成する場所で、ViewControllerはそのUIを管理するクラスです。

__開発の流れ__

1.StoryboardでUI作成
- Storyboard上で、1つの画面にボタンやラベル等を配置

2.ViewControllerの作成
- そのクラス内で、ボタンがタップされた時にラベルのテキストを更新する等のロジックを記述
```swift
class ViewController: UIViewController {
    @IBOutlet weak var label: UILabel!  // Storyboardで設定したラベル
    
    @IBAction func buttonTapped(_ sender: UIButton) {
        label.text = "Hello, World!"  // ボタンがタップされたらラベルのテキストを変更
    }
}
```

3.StoryboardとViewControllerの接続
- Storyboardのボタンとラベルに、それぞれ@IBOutlet(StoryboardのUI要素（ボタン、ラベル、テキストフィールドなど）とViewControllerのコードを接続するためのプロパティ)と@IBAction(Storyboard上のUI要素（ボタン、スイッチ、スライダーなど）のアクション（タップ、値の変更）をViewControllerのコードに通知するためのメソッド)を接続
- ViewControllerクラスとStoryboard上のViewController

以上のような違いがあります。
個人的に最初はStoryboardが視覚的にわかりやすくて良いなと感じていたのですが、複雑なコードになってくるとSwiftUIのようにコードで書いてある方がすんなり頭に入ってくるなという印象があります。

まだまだこの2つの開発方法を上手に使いこなせていないと思うので日々精進していきます。

## よく使うSwiftのコードパターン
次にアプリ開発をこの数ヶ月間取り組んでいく中でこのコード頻繁に使われているな〜と感じたものを紹介します。

### Optional (オプショナル)
オプショナル型とは値があるかもしれないし、ないかもしれないという状況を安全に扱うための仕組みです。オプショナル型を宣言するときは、変数の型の後ろに"？"(クエスチョン)をつけます。

Swiftでは、Optionalの導入により、nilの可能性がある場合にコンパイル時にエラーが発生するため、バグを未然に防ぐことができます。そのため、Xcode（Appleが提供している統合開発環境）で、Optional関連のエラーが頻繁に表示されることがあります。

Swiftでは空の状態をnilで表します。
(過去に学んだことのあるPHPではnullだったので最初は違和感がありました)

⇩型が違うとコンパイルエラーになる。
```swift
var name: String? = "takahashish"
let upperName: String = name   //エラーになる
```
```swift
var name: String? = "takahashish"
let upperName: String = name ?? "unknown"   //OK
```

### guard let
初めてguard let構文を見たときは「なんだこれ」となった記憶があります。
guard letはSwiftで使われる、変数がnilかどうかをチェックし、nilならその場で関数から抜ける構文の「早期リターンのための安全なアンラップ方法」です。
これにより関数の途中で条件を満たさなければ早めに処理を中断し、エラー処理や例外処理をシンプルに記述できます。

先ほど述べたOptionalをアンラップ(値を取り出す)する方法の1つです。Optionalのnilチェックを必ず実行するため、クラッシュを防ぐことができます。
```swift
func getUserID(id: Int?) {
    guard let unwrappedID = id else {
        print("IDがnilです")
        return
    }
    print("ユーザーIDは\(unwrappedID)です")
}

getUserID(id: 42)  // ユーザーIDは 42 です
getUserID(id: nil) // IDがnilです
```

### if let
if let構文はguard let構文と同じでどちらもOptionalのアンラップに使用されるが、使い方や目的が異なります。

対象のプロパティの値がnulかどうかをチェックし,nilではない場合(値が存在する場合)はそのプロパティをアンラップしてくれます。
```swift
var name: String? = "takahashish"

if let unwrappedName = name {
    print("こんにちは、\(unwrappedName)さん！") // nameがnilでなければここが実行される
} else {
    print("名前が設定されていません。") // nameがnilならここが実行される
}
```

__違い__

__if let構文__

使用する変数の範囲：ifの中だけ

nil時の動き：elseで別の処理をする

__guard let構文__

使用する変数の範囲：関数全体で使える

nil時の動き：必ず関数を抜ける(returnやthrowが必要)

### UIViewControllerのライフサイクル
UIViewControllerのライフサイクルと聞くと一見難しそうに聞こえますが、簡単に言うと画面を表示させる時に呼ばれるメソッドの一連の流れのことです。UIViewControllerを継承したクラスを作成した時に自動生成されるviewDidLoad()は、ライフサイクルの1つです。

ライフサイクルを呼び出す時には、UIViewControllerを継承する必要があります。UIViewControllerを継承しないと使えません。
```sw
class ViewController: UIViewController
```

ライフサイクルメソッドの基本的なメソッドは5つあります。
- viewDidLoad()：Viewが読み込まれた時
- viewWillAppear()：Viewが表示される直前
- viewDidAppear()：Viewが表示された時
- viewWillDisappear()：Viewが非表示になる直前
- viewDidDisappear()：Viewが非表示になった時

適切なタイミングで処理を行わなければ、バグが発生してしまうので、ライフサイクルを意識してコードの理解を深めていきます。

## まとめと感想
簡単ではありますが、Swiftについてやよく見かけるコードについてのお話を行ってみました。記事の作成が初めてだったので読みづらい部分もあったとは思いますが、ここまで読んでくださりありがとうございます。

アプリチームに配属され自分が担当した部分が実際にリリースされて自分のスマホでその部分を見れた時はとても感動しやりがいを感じました。これからもっと成長できるように頑張っていこうと思います！

それではメリークリスマス🎄＆良いお年を🧧

## 参考
- https://hnavi.co.jp/knowledge/blog/swift/
- https://note.com/s01r0/n/n7e8d34812cfc
- https://www.sejuku.net/blog/35070
- https://www.sejuku.net/blog/32607
- https://ios-docs.dev/life-cycle/