『たった2日でマスターするiPhoneアプリ開発集中講座』読書メモ

# 概要

以下の書籍を読み進めた際の読書メモです。
所要時間は約15時間でした。
超詳細に示された手順を辿りながら、アプリ開発の基本的な流れを分かりやすく学べました。
主要なコンポーネントの使い方からWebAPIを使ったデータ取得まで、サンプルアプリを作りながら学べるので、1冊やるだけでもちょっとしたアプリなら作れるようになると思いました。

# 書籍概要

- 書籍名：たった2日でマスターするiPhoneアプリ開発集中講座
- 著者　：藤治仁・小林加奈子・小林由憲
- 発刊日：2019/10/23
- 頁数　：424ページ

# 読書ノート

## 開発方法・ビルド

- 主な開発の流れ
    - Xcode上にパーツを配置し画面レイアウトを作る
    - パーツとコードを接続（connect）し、動作を記述する
    - シミュレータや実機で動作を確認する

- 実機で動作確認する場合、Xcodeに登録されたApple IDと、実機に設定されているApple IDが同じである必要がある
    - Xcodeには複数のApple IDを登録できるが、その中に実機と同じApple IDがあれば良い
    - ビルド時に選択するTeamは、実機と異なるApple IDのものでも問題ない

- プロジェクト設定でTeamを選択時に「Failed to register bundle identifier.」エラーが出た場合の対応
    - 「Bundle Indentifier」の値を変更すれば良い（末尾に日時を入れる等）
        - [Xcode10で「Failed to register bundle identifier」エラーへの対応 | TickleCode](https://ticklecode.com/failed_to_register_bundle_identifier/)

<img width="404" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628482/470dcfb5-2589-5f3a-ee93-a8675448d0b4.png">

## レイアウト

- AutoLayoutを使うと画面パーツの配置やレイアウトを整えることができる
    - 色々な端末の画面サイズに対応するためには重要な機能

## IBOutlet・IBAction

- IBOutletについて
    - ```@IBOutlet weak var answerImageView: UIImageView!```
        - ```IBOutlet修飾子```Interface Builderにあるパーツとコードを連結することを示すキーワード
        - ```weak var answerImageView```：変数の定義（```answerImageView```が変数名）
        - ```: UIImageView```：クラス（型）の指定（```変数名:データ型```）
        - このコードで、UIパーツのImageViewを、コード上でanswerImageViewという名前で参照・設定できるようになる

- IBActionについて
    - ```@IBAction func shuffleAction(_ sender: Any) { ... }```
        - 紐付いたパーツがユーザによって何かしら操作された際、実行するプログラムを連結するキーワード

## 変数・定数

- ```let```で定義した値は一度値を設定したら変更できない（＝定数）
    - 変数は```var```で定義する
    - 上手く使い分けることでコードの安全性が向上する

## アクセス修飾子

- Swiftのアクセス修飾子
    - public：どこからでもアクセス可能
    - internal：同じモジュール内であればアクセス可能
    - fileprivate：ファイル内でのみアクセス可能
    - private：現在の定義の中でのみアクセス可能

## Storyboard・パーツ

- パーツとコードの関連付けを解除する場合、コードを削除するだけではダメ
    - StoryboardのView Controllerから解除する必要がある
        - 再度関連付けする場合、コード横の白丸を対象パーツにD&Dする

- Storyboard上にパーツを配置する際、コピペはしないようにする
    - 特に、アクションを設定するボタン等をコピペした場合、コードとの関連付けが上手くいかなくなる場合がある

## 値の参照渡し

- メソッド呼び出し時、引数の先頭に```&```を付けると参照渡しが可能
    - 引数に指定した変数やインスタンスそのもの（同アドレス）にメソッド内で変更を加えたい場合は参照渡しを使う
        - 変数のコピーではなく変数のアドレス情報を渡すので、メソッド内での変更が元の値に影響する
    - 先頭に何も付けなければ値渡しになる
        - コピーを渡すだけなのでコピー先で変更があっても元の値には影響がない

## 例外処理

- 例外処理
    - 例外処理は```do-catch```ブロックで行う
    - メソッド呼び出しの前に```try```文を記述する
        - ```sample = try AVAudioPlayer(contentsOf: cymbalPath, fileTypeHint: nil)```

## Delegate・DataSource

- Delegate機能を使うと、特定の操作（文字入力等）が完了したタイミングでプログラムを動作させることができる
    - あるクラスで行いたい処理の一部を他のクラスに任せたり、任せた処理を指定したクラスに通知したりする仕組み
    - Delegateが行われる時に登場するものは大きく3つ
        - 処理を依頼するクラス（例：```inputeText.delegate = self```）
            - 処理結果の通知先を自分自身（ViewController）とし、TextFieldクラスから作ったinputTextにdelegateを設定
        - 依頼する・依頼されるクラスを取り持つプロトコル（例：```UITextFieldDelegate```）
            - return操作が行われたら、設定された通知先に結果を通知するよう、UITextFieldクラスに依頼する
        - 処理を依頼されるクラス（例：```UITextField```）
            - UITextFieldDelegateから通知を受けたら、通知先（ViewControllerのtextFieldShouldReturn）に結果を通知する
            - 通知先はプロトコルが処理してくれるので、このクラスは通知先を知らなくても良い（汎用的に利用できる）
    - ViewControllerの宣言に記述を追加する
        - 例：```class ViewController: UIViewController, UITextFieldDelegate { ... }```

- TextFieldのDelegate
    - ```textFieldShouldReturn() { ... }```：Return操作（「検索」ボタンを押す等）が行われたら実行されるメソッド
        - メソッド名はあらかじめ決まっている

- DataSource
    - UIパーツとコード間でデータのやり取りを行うために定義する

## オプショナル・アンラップ・オプショナルチェイニング

- オプショナル
    - 値がない状態を許すデータ型のこと
    - 変数宣言時のクラス名の後に```?```または```!```を指定する（一般的なオプショナル型は```?```を付ける）
        - これらが無い宣言は、「非オプショナル型」になる（値がない状態を許さない）

- アンラップ
    - ```if let ...```を使うと、値がある場合のみif文内が実行されるとともに、変数に値が格納される
        - オプショナル型の変数やメソッドを安全に取り扱う手法のこと
        - 例：```if let searchKey = textField.text { print(searchKey) }```
            - 値があれば、```print(searchKey)```が実行されるとともに、```searchKey```に値が格納される
        - アンラップ処理は入れ子にして使うことも出来る

- オプショナルチェイニング
    - アンラップの手法の一つで、値がある場合のみ、続くメソッドが実行される
        - 例：```_ = navigationController?.popViewController(animated: true)```
            - ```navigationController```に値が入っている場合のみ、```popViewController```が実行される

- ```guard let ```を使うとオプショナル変数の値を安全に取り出せる
    - ```if let ```は「アンラップできたら」だが、```guard let```は「アンラップできないときは」という条件で分岐する
        - 例：```guard let アンラップ変数 = オプショナル変数　else { オプショナル変数に値がない時の処理 }```
            - オプショナル変数に値がない時の処理には、```return```などのプログラムが終了するコードのみ記述可能

## クロージャ

- クロージャ
    - 引数などに```{}```でまとめて処理を渡して実行させる方法のこと
        - 例えば```CLGeocoder.geocodeAddressString()```などに渡して、位置情報取得後の処理を第2引数に書いたりする
    - 主な記述方法：

```
{ (引数:引数の型) -> (戻り値の型) in
    何らかの処理
    return 戻り値
}
```

## UserDefaults

- UserDefaults
    - UserDefaultsを使うと、アプリで利用する値を保存できる
        - 異なる画面間で値をやり取りする時などに使う
        - 値はKVで保存され、アプリを停止・再起動しても保存されている（永続的）
            - 永続化は定期的に実行されているが、即座に永続化するには```synchronize```を利用する
    - UserDefaultsにアクセスする場合、（必要に応じて）都度UserDefaultsインスタンスを生成してから値を呼び出す

## Segue（セグエ）

- Segueを使って画面遷移する際に```prepare```メソッドが実行される
    - ```override func prepare(for segue: UIStoryboardSegue, sender: Any?) { ... }```

## 画像の取り扱い

- Appleが提供している画像処理フレームワーク「Core Image」を使うと、簡単に画像にフィルタをかけたりできる

## 音声の取り扱い

- 音を扱うためには「AVFoundation」というフレームワークを読み込む必要がある

## マップの取り扱い

- ```CLGeocoder```クラスを使うと、緯度経度から住所を検索、またはその逆を行うことができる
    - ```CLGeocoder.geocodeAddressString()```：郵便番号や住所等から様々な情報を取得して```placemarks```に格納する
        - ```placemarks```は```CLPlacemarks```クラスのインスタンス

## ラベル（名前付き引数）

- メソッドのラベル（名前付き引数）について
    - メソッドのラベルは、メソッドの呼び出し側でより引数を分かりやすくするために使う
        - メソッド名から引数の意味が分かるような場合、引数ラベル省略「```_```」を利用して呼び出し側でラベルを省略可能
            - ラベルを省略した場合は引数名がラベルとして扱われる

```
// ラベルを付与する場合

// 合計値を計算
func calcSum(quantity qt: Int, price pc: Int) -> Int {
    // メソッド内ではラベルではなく引数を使う
    return qt * pc
}

// メソッド呼び出し（ラベルを使って引数を指定できる）
calcSum(quantity: 2, price: 300)
```

```
// ラベルを省略する場合

// デバッグエリアに文字を表示する
func debugMessage(_ message: String) {
    print("\(message)")
}

// メソッド呼び出し（引数のラベルを省略できる）
debugMessage("デバッグエリアに表示する文字")
```

## JSON

- ```Codable```プロトコルを利用すると、JSONの項目名とコード中の変数名を同じにした場合に、JSON変換時に一括して変数にデータを格納してくれる

## ATS

- ATSを有効化すると、HTTPでインターネットに接続できなくなる
    - また、HTTPSを使っていても、Appleが推奨するセキュリティ要件を満たしていなければ同様に接続できなくなる
    - 無効化すればHTTPやセキュリティ要件を満たさないHTTPSでも接続できるようになる

## タプル

- タプルを用いると、複数の値を一つの変数として扱うことができる（KVを一つにまとめカンマで区切る）
    - タプルは配列のように値の追加・削除・データの個数変更等はできない
    - 例：```(key1:String, key2:String, key3:Int)```

## その他

- ```viewDidLoad ```メソッドはアプリ起動時に一度だけ動くようにあらかじめ作られている
    - この中に書いたコードもアプリ起動時に一度だけ動作する

- 引数のデータ型に```inout```を指定すると、引数として受け取り、かつ戻り値としてその値を返す
    - return文を書かなくても戻り値を返してくれる

- Objective-Cで書かれたクラスをSwiftで利用する場合、宣言の先頭に```@objc```を付ける必要がある

- 戻り値のあるメソッドを呼び出してかつその戻り値を利用しない場合、「```_```」に代入する
    - 例：```_ = updateTimer()```（```updateTimer()```はInt型の値を返す）

- 文字列の中に定数や変数を埋め込む場合、「```\(定数 or 変数)```」と記述する
    - 例：```label.text = "残り時間：\(remainCount)秒"```

- 既存のクラスを拡張する場合は「Extension」を用いる