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