Swift実践入門 増補改訂第3版
[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)
技術評論社
著者:石川洋資、西山勇世
はじめに
謝辞
増補改訂第3版での更新点
サポートページ
第1章 Swiftはどのような言語か
1.1 言語の特徴
静的型付き言語
nilの許容性をコントロール可能
型推論による簡潔な記述
ジェネリクスによる汎用的な記述
Objective-Cと連携可能
1.2 開発環境
ツールチェインのインストール
macOS
Linux
ライブラリ
標準ライブラリ ── 言語の一部となるライブラリ
コアライブラリ ── 高機能な汎用ライブラリ
開発ツール
Swift Package Manager ── パッケージ管理ツール
LLDB ── デバッグツール
1.3 プログラムの実行方法
コマンドラインによる実行方法
REPLによるインタラクティブな実行
単一ファイルのプログラムの実行
複数のファイルから構成されるプログラムの実行
Xcodeにおける実行方法
Playgroundによるインタラクティブな実行
複数のファイルから構成されるプログラムの実行
1.4 本書のサンプルコードの実行方法
1.5 命名規則
名前に使用可能な文字
単語の区切り方
単語の選び方
1.6 本書の構成
1.7 まとめ
第2章 変数と定数と式
2.1 変数と定数による値の管理
2.2 変数と定数の基本
宣言方法
値の代入方法
代入可能な値
代入による型推論
定数への再代入
値の利用方法
初期化前の変数や定数の利用
型の確認方法
2.3 スコープ ── 名前の有効範囲
ローカルスコープ ── 局所的に定義されるスコープ
グローバルスコープ ── プログラム全体から参照できるスコープ
スコープの優先順位
2.4 式の組み立て
値の返却のみを行う式
変数や定数の値を返却する式
リテラル式 ── 値をプログラムに直接表記する式
メンバー式 ── 型のメンバーにアクセスする式
クロージャ式 ── 呼び出し可能な処理を定義する式
演算を行う式
算術演算子 ── 算術を行う演算子
符号演算子 ── 数値の符号を指定する演算子
否定演算子 ── 論理値の反転を行う演算子
処理を呼び出す式
関数を呼び出す式
イニシャライザを呼び出す式
2.5 まとめ
第3章 基本的な型
3.1 型による値の表現
3.2 Bool型 ── 真理値を表す型
真理値リテラル
論理演算
否定
論理積
論理和
3.3 数値型 ── 数値を表す型
数値リテラル
数値型の種類
整数型
浮動小数点型
数値型どうしの相互変換
数値型の操作
比較
算術
Foundationによる高度な操作
3.4 String型 ── 文字列を表す型
文字列リテラル
特殊文字の表現
文字列リテラル内での値の展開
複数行の文字列リテラル
数値型との相互変換
String型の操作
比較
結合
Foundationによる高度な操作
3.5 Optional
Optional
型推論
Optional
nilリテラルの代入による.noneの生成
イニシャライザによる.someの生成
値の代入による.someの生成
Optional
オプショナルバインディング ── if文による値の取り出し
??演算子 ── 値が存在しない場合のデフォルト値を指定する演算子
強制アンラップ ── !演算子によるOptional
オプショナルチェイン ── アンラップを伴わずに値のプロパティやメソッドにアクセス
map(_:)メソッドとflatMap(_:)メソッド ── アンラップを伴わずに値の変換を行うメソッド
暗黙的にアンラップされたOptional
値の取り出し方法の使い分け
3.6 Any型 ── 任意の型を表す型
Any型への代入による型の損失
3.7 タプル型 ── 複数の型をまとめる型
要素へのアクセス
インデックスによるアクセス
要素名によるアクセス
代入によるアクセス
Void型 ── 空のタプル
3.8 型のキャスト ── 別の型として扱う操作
アップキャスト ── 上位の型として扱う操作
ダウンキャスト ── 下位の型として扱う操作
型の判定
3.9 値の比較のためのプロトコル
Equatableプロトコル ── 同値性を検証するためのプロトコル
Comparableプロトコル ── 大小関係を検証するためのプロトコル
3.10 まとめ
第4章 コレクションを表す型
4.1 値の集まりの表現
4.2 Array
配列リテラル
型推論
要素にできる型
Array
要素へのアクセス
要素の更新、追加、結合、削除
4.3 Dictionary
辞書リテラル
型推論
キーと値にできる型
Dictionary
値へのアクセス
値の更新、追加、削除
4.4 範囲型 ── 範囲を表す型
範囲演算子 ── 範囲を作る演算子
..<演算子 ── 末尾の値を含まない範囲を作る演算子
...演算子 ── 末尾の値を含む範囲を作る演算子
型推論
境界に使用可能な型
範囲型の操作
境界の値へのアクセス
値が範囲に含まれるかどうかの判定
4.5 コレクションとしてのString型
Character型 ── 文字を表す型
String.Index型 ── 文字列内の位置を表す型
4.6 シーケンスとコレクションを扱うためのプロトコル
Sequenceプロトコル ── 要素への順次アクセス
forEach(_:)メソッド ── 要素に対して順次アクセスする
filter(_:)メソッド ── 要素を絞り込む
map(_:)メソッド ── 要素を変換する
flatMap(_:)メソッド ── 要素をシーケンスに変換し、それを1つのシーケンスに連結する
compactMap(_:)メソッド ── 要素を、失敗する可能性のある処理を用いて変換する
reduce(_:_:)メソッド ── 要素を1つの値にまとめる
Collectionプロトコル ── サブスクリプトによる要素へのアクセス
4.7 まとめ
第5章 制御構文
5.1 プログラムの実行フローの制御
5.2 条件分岐
if文 ── 条件の成否による分岐
条件式に使用できる型
else節 ── 条件不成立時の処理
if-let文 ── 値の有無による分岐
guard文 ── 条件不成立時に早期退出する分岐
guard文のスコープ外への退出の強制
guard文で宣言された変数や定数へのアクセス
if文との使い分け
switch文 ── 複数のパターンマッチによる分岐
ケースの網羅性チェック
defaultキーワード ── デフォルトケースによる網羅性の保証
whereキーワード ── ケースにマッチする条件の追加
break文 ── ケースの実行の中断
ラベル ── break文の制御対象の指定
fallthrough文 ── switch文の次のケースへの制御の移動
5.3 繰り返し
繰り返し文の種類
for-in文 ── シーケンスの要素の列挙
while文 ── 継続条件による繰り返し
repeat-while文 ── 初回実行を保証する繰り返し
実行文の中断
break文 ── 繰り返しの終了
continue文 ── 繰り返しの継続
ラベル ── break文やcontinue文の制御対象の指定
5.4 遅延実行
defer文 ── スコープ退出時の処理
5.5 パターンマッチ ── 値の構造や性質による評価
パターンの種類
式パターン ── ~=演算子による評価
バリューバインディングパターン ── 値の代入を伴う評価
オプショナルパターン ── Optional
列挙型ケースパターン ── ケースとの一致の評価
is演算子による型キャスティングパターン ── 型の判定による評価
as演算子による型キャスティングパターン ── 型のキャストによる評価
パターンマッチが使える場所
if文
guard文
for-in文
while文
do文のcatch節
5.6 まとめ
第6章 関数とクロージャ
6.1 処理の再利用
6.2 関数 ── 名前を持ったひとまとまりの処理
定義方法
実行方法
引数
仮引数と実引数
外部引数名と内部引数名
外部引数名の省略
デフォルト引数 ── 引数のデフォルト値
インアウト引数 ── 関数外に変更を共有する引数
可変長引数 ── 任意の個数の値を受け取る引数
コンパイラによる引数チェック
戻り値
戻り値がない関数
コンパイラによる戻り値チェック
暗黙的なreturn
6.3 クロージャ ── スコープ内の変数や定数を保持したひとまとまりの処理
定義方法
型推論
実行方法
引数
簡略引数名 ── 引数名の省略
戻り値
クロージャによる変数と定数のキャプチャ
引数としてのクロージャ
属性の指定方法
escaping属性 ── 非同期的に実行されるクロージャ
autoclosure属性 ── クロージャを用いた遅延評価
トレイリングクロージャ ── 引数のクロージャを()の外に記述する記法
クロージャとしての関数
クロージャ式を利用した変数や定数の初期化
6.4 まとめ
第7章 型の構成要素 ── プロパティ、イニシャライザ、メソッド
7.1 型に共通するもの
7.2 型の基本
定義方法
インスタンス化の方法
型の内部でのインスタンスへのアクセス
型の内部での型自身へのアクセス
7.3 プロパティ ── 型に紐付いた値
定義方法
紐付く対象による分類
インスタンスプロパティ ── 型のインスタンスに紐付くプロパティ
スタティックプロパティ ── 型自身に紐付くプロパティ
ストアドプロパティ ── 値を保持するプロパティ
プロパティオブザーバ ── ストアドプロパティの変更の監視
レイジーストアドプロパティ ── アクセス時まで初期化を遅延させるプロパティ
コンピューテッドプロパティ ── 値を保持せずに算出するプロパティ
ゲッタ ── 値の返却
セッタ ── 値の更新
セッタの省略
7.4 イニシャライザ ── インスタンスの初期化処理
定義方法
失敗可能イニシャライザ ── 初期化の失敗を考慮したイニシャライザ
コンパイラによる初期化チェック
7.5 メソッド ── 型に紐付いた関数
定義方法
紐付く対象による分類
インスタンスメソッド ── 型のインスタンスに紐付くメソッド
スタティックメソッド ── 型自身に紐付くメソッド
オーバーロード ── 型が異なる同名のメソッドの定義
引数によるオーバーロード
戻り値によるオーバーロード
7.6 サブスクリプト ── コレクションの要素へのアクセス
定義方法
セッタの省略
オーバーロード ── 型が異なるサブスクリプトの定義
7.7 エクステンション ── 型の拡張
定義方法
メソッドの追加
コンピューテッドプロパティの追加
イニシャライザの追加
7.8 型のネスト
定義方法
7.9 まとめ
第8章 型の種類 ── 構造体、クラス、列挙型
8.1 型の種類を使い分ける目的
8.2 値の受け渡し方法による分類
値型 ── 値を表す型
変数と定数への代入とコピー
mutatingキーワード ── 自身の値の変更を宣言するキーワード
参照型 ── 値への参照を表す型
値の変更の共有
値型と参照型の使い分け
8.3 構造体 ── 値型のデータ構造
定義方法
ストアドプロパティの変更による値の変更
定数のストアドプロパティは変更できない
メソッド内のストアドプロパティの変更にはmutatingキーワードが必要
メンバーワイズイニシャライザ ── デフォルトで用意されるイニシャライザ
メンバーワイズイニシャライザのデフォルト引数
8.4 クラス ── 参照型のデータ構造
定義方法
継承 ── 型の構成要素の引き継ぎ
定義方法
オーバーライド ── 型の構成要素の再定義
finalキーワード ── 継承とオーバーライドの禁止
クラスに紐付く要素
クラスプロパティ ── クラス自身に紐付くプロパティ
クラスメソッド ── クラス自身に紐付くメソッド
スタティックプロパティ、スタティックメソッドとの使い分け
イニシャライザの種類と初期化のプロセス
指定イニシャライザ ── 主となるイニシャライザ
コンビニエンスイニシャライザ ── 指定イニシャライザをラップするイニシャライザ
2段階初期化
デフォルトイニシャライザ ── プロパティの初期化が不要な場合に定義されるイニシャライザ
クラスのメモリ管理
デイニシャライザ ── インスタンスの終了処理
値の比較と参照の比較
8.5 列挙型 ── 複数の識別子をまとめる型
定義方法
ローバリュー ── 実体の定義
ローバリューのデフォルト値
連想値 ── 付加情報の付与
CaseIterableプロトコル ── 要素列挙のプロトコル
コンパイラによるallCasesプロパティのコードの自動生成
allCasesプロパティのコードが自動生成されない条件
8.6 まとめ
第9章 プロトコル ── 型のインタフェースの定義
9.1 型のインタフェースを定義する目的
9.2 プロトコルの基本
定義方法
準拠方法
クラス継承時の準拠方法
エクステンションによる準拠方法
コンパイラによる準拠チェック
利用方法
プロトコルコンポジション ── 複数のプロトコルの組み合わせ
9.3 プロトコルを構成する要素
プロパティ
定義方法
ゲッタの実装
セッタの実装
メソッド
定義方法
メソッドの実装
mutatingキーワード ── 値型のインスタンスの変更を宣言するキーワード
連想型 ── プロトコルの準拠時に指定可能な型
定義方法
型制約の追加
デフォルトの型の指定
プロトコルの継承
クラス専用プロトコル
9.4 プロトコルエクステンション ── プロトコルの実装の定義
定義方法
デフォルト実装による実装の任意化
型制約の追加
9.5 まとめ
第10章 ジェネリクス ── 汎用的な関数と型
10.1 汎用的なプログラム
10.2 ジェネリクスの基本
定義方法
特殊化方法
仮型引数と実型引数
汎用性と型安全性の両立
Any型との比較
10.3 ジェネリック関数 ── 汎用的な関数
定義方法
特殊化方法
引数からの型推論による特殊化
戻り値からの型推論による特殊化
型制約 ── 型引数に対する制約
スーパークラスや準拠するプロトコルに対する制約
連想型のスーパークラスや準拠するプロトコルに対する制約
型どうしの一致を要求する制約
10.4 ジェネリック型 ── 汎用的な型
定義方法
特殊化方法
型引数の指定による特殊化
型推論による特殊化
型制約 ── 型引数に対する制約
型の定義で使用できる型制約
ジェネリック型の型制約付きエクステンション
プロトコルへの条件付き準拠
10.5 まとめ
第11章 モジュール ── 配布可能なプログラムの単位
11.1 再利用可能かつ配布可能なプログラム
11.2 モジュールの作成と利用
ビルドターゲットの定義
ビルドターゲットの依存関係の定義
外部パッケージの利用
11.3 名前空間 ── 名前が一意となる範囲
import文 ── モジュールのインポートを行う文
名前の衝突の回避
11.4 アクセスコントロール ── 外部からの使用の制限
アクセスレベル ── 公開範囲の分類
指定方法
デフォルトのアクセスレベル
エクステンションのアクセスレベル
モジュールヘッダ ── モジュール外から参照可能なインタフェース
閲覧方法
モジュールヘッダに記述される情報
ドキュメントコメント ── コードの意図や使用方法の説明
11.5 まとめ
第12章 型の設計指針
12.1 クラスに対する構造体の優位性
参照型のクラスがもたらすバグ
値型の構造体がもたらす安全性
コピーオンライト ── 構造体の不要なコピーを発生させない最適化
クラスを利用するべきとき
参照を共有する
インスタンスのライフサイクルに合わせて処理を実行する
12.2 クラスの継承に対するプロトコルの優位性
クラスの継承がもたらす期待しない挙動
プロトコルによるクラスの継承の問題点の克服
クラスの継承を利用するべきとき
複数の型の間でストアドプロパティの実装を共有する
12.3 オプショナル型の利用指針
Optional
値の不在が想定される
ただし、必然性のないOptional
暗黙的にアンラップされたOptional
初期化時にのみ値が決まっていない
サブクラスの初期化より前にスーパークラスを初期化する
Optional
12.4 まとめ
第13章 イベント通知
13.1 Swiftにおけるイベント通知のパターン
13.2 デリゲートパターン ── 別オブジェクトへの処理の委譲
実装方法
命名規則
弱参照による循環参照への対処
利用するべきとき
2つのオブジェクト間で多くの種類のイベント通知を行う
外部からのカスタマイズを前提としたオブジェクトを設計する
13.3 クロージャ ── 別オブジェクトへのコールバック時の処理の登録
実装方法
キャプチャリスト ── キャプチャ時の参照方法の制御
weakキーワード ── メモリ解放を想定した弱参照
unownedキーワード ── メモリ解放を想定しない弱参照
キャプチャリストの使い分け
escaping属性によるselfキーワードの必須化
typealiasキーワードによる複雑なクロージャの型への型エイリアス
利用するべきとき
処理の実行とコールバックを同じ箇所に記述する
13.4 オブザーバパターン ── 状態変化の別オブジェクトへの通知
実装方法
Selector型 ── メソッドを参照するための型
利用するべきとき
1対多のイベント通知を行う
13.5 まとめ
第14章 非同期処理
14.1 Swiftにおける非同期処理
14.2 GCD ── 非同期処理のための低レベルAPI群
実装方法
ディスパッチキューの種類
既存のディスパッチキューの取得
新規のディスパッチキューの生成
ディスパッチキューへのタスクの追加
利用するべきとき
シンプルな非同期処理を実装する
14.3 Operation、OperationQueueクラス ── 非同期処理を抽象化したクラス
実装方法
タスクの定義
キューの生成
キューへのタスクの追加
タスクのキャンセル
タスクの依存関係の設定
利用するべきとき
複雑な非同期処理を実装する
14.4 Threadクラス ── 手動でのスレッド管理
実装方法
利用するべきとき
特になし
14.5 非同期処理の結果のイベント通知
14.6 まとめ
第15章 エラー処理
15.1 Swiftにおけるエラー処理
15.2 Optional
実装方法
利用するべきとき
値の有無だけで結果を十分に表せる
15.3 Result
実装方法
利用するべきとき
エラーの詳細を提供する
成功か失敗のいずれかであることを保証する
非同期処理のエラーを扱う
15.4 do-catch文によるエラー処理 ── Swift標準のエラー処理
実装方法
Errorプロトコル ── エラー情報を表現するプロトコル
throwsキーワード ── エラーを発生させる可能性のある処理の定義
rethrowsキーワード ── 引数のクロージャが発生させるエラーの呼び出し元への伝播
tryキーワード ── エラーを発生させる可能性のある処理の実行
try!キーワード ── エラーを無視した処理の実行
try?キーワード ── エラーをOptional
defer文によるエラーの有無に関わらない処理の実行
利用するべきとき
エラーの詳細を提供する
成功か失敗のいずれかであることを保証する
連続した処理のエラーをまとめて扱う
エラー処理を強制する
15.5 fatalError(_:)関数によるプログラムの終了 ── 実行が想定されていない箇所の宣言
実装方法
Never型 ── 値を返さないことを示す型
利用するべきとき
想定外の状況ではプログラムを終了させる
15.6 アサーションによるデバッグ時のプログラムの終了 ── 満たすべき条件の宣言
実装方法
assert(_:_:)関数 ── 条件を満たさない場合に終了するアサーション
assertionFailure(_:)関数 ── 必ず終了するアサーション
コンパイルの最適化レベル ── デバッグとリリースの切り替え
利用するべきとき
デバッグ時に想定外の状況を検出する
リリース時は想定外の状況でもプログラムの実行を継続する
15.7 エラー処理の使い分け
15.8 まとめ
第16章 Webサービスとの連携
16.1 連携のための取り決め
16.2 データの取り扱い
Data型 ── バイト列を表す型
エンコードとデコード
JSONEncoderクラス、JSONDecoderクラス ── JSONをエンコード、デコードする
Encodable、Decodable、Codableプロトコル ── 型をエンコード、デコードに対応させる
コンパイラによるコードの自動生成
16.3 HTTPによるWebサービスとの通信
URLRequest型 ── リクエスト情報の表現
HTTPURLResponse型 ── HTTPレスポンスのメタデータ
URLSessionクラス ── URL経由でのデータの送信、取得
3種類のタスク ── 基本、アップロード用、ダウンロード用
タスクの実行
16.4 まとめ
第17章 ユニットテスト
17.1 ユニットテストの目的
17.2 ユニットテストのセットアップ
テストターゲットの構成
テストの実行
Linux用のテストの列挙
17.3 テストコードの基本
定義方法
テスト対象のモジュールのインポート
アサーション ── 値の検証
単一の式を評価するアサーション
2つの式を比較するアサーション
エラーの有無を評価するアサーション
無条件に失敗するアサーション
17.4 テストケース ── テストをまとめる
テストの事前処理と事後処理
setUp()メソッド ── テストの事前処理を行うメソッド
tearDown()メソッド ── テストの事後処理を行うメソッド
テストの実行のコントロール
失敗時のテストの中断
エラーによるテストの中断
非同期処理の待ち合わせ
17.5 スタブ ── テスト対象への入力を置き換える
プロトコルによる実装の差し替え
依存先のプロトコル化
プロトコルに準拠したスタブの実装
テストにおけるスタブの使用
17.6 まとめ
第18章 実践的なSwiftアプリケーション ── Web APIクライアントを作ろう
18.1 GitHub Search APIクライアントを作ろう
18.2 実装の下準備
API仕様と動作の確認
コマンドラインアプリケーションのパッケージの作成
実装方針の確認
18.3 API仕様のモデル化
レスポンス ── サーバ上のリソースの表現
構造体の定義
JSONから構造体へのマッピング
JSONから構造体へのマッピングに対するテスト
ジェネリック型による検索結果の表現
JSONからジェネリック型へのマッピングに対するテスト
エラー ── APIクライアントで発生するエラーの表現
エラーの分類
エラーを表すレスポンスのモデル化
JSONからエラーの型へのマッピングに対するテスト
リクエスト ── サーバに対する要求の表現
ベースURLとパスの定義
HTTPメソッドの定義
パラメータの定義
リクエストとレスポンスの紐付け
リポジトリ検索APIの実装
18.4 APIクライアント ── Web API呼び出しの抽象化
API仕様をモデル化した型とFoundationの型の変換
リクエストを表す型のURLRequest型へのマッピング
Data型とHTTPURLResponse型のレスポンスを表す型へのマッピング
APIクライアントの構成要素間の接続
HTTPクライアントの実装
APIクライアントのインタフェースの定義
HTTPリクエストの送信
HTTPレスポンスの処理
通信結果の処理に対するテスト
18.5 プログラムの実行
エントリポイントの準備
実行ファイルのビルドと実行
18.6 まとめ
あとがき
索引
著者プロフィール