FC2ブログ

絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(12)〜Appendix

2021. 01. 24
この記事は「絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】」(初版第1刷)を元に、Xcode 12.3(Swift 5.3.2)下における差異や覚書を記述しています。

手元にあって未読だったものを今頃読んでいるだけですので「絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応
2020年6月27日発売の最新版)」なら、この記事を読む必要も無駄な苦労をすることもないため、最新版の購入をお勧めします。



Appendix



●Appendix 01 公式ドキュメントの読み方


・ドキュメントの参照方法

現在は Xcode のメニューから Help → Developer Documentation になっています。

ap-01-01.png

またドキュメントビューアの構成も、ナビゲータエリアが無くなってドロップダウンリストになったりと異なっています。

ap-01-02.png


・ドキュメントの表示方法

現在は command + クリックするとポップアップメニューが開き、

 ap-01-05.png

Jump to Definition を選択するとエディタエリアで当該項目の定義が開きます。

ap-01-07.png  

option + クリックするとポップアップで宣言内容が表示されます。

ap-01-06.png

本書では option + ダブルクリックでドキュメントビューアが開くとありますが、現在は option + クリックで開いたポップアップの右下にあるリンク「Open in Developer Documentation」をクリックするとドキュメントビューアが開きます。


・ドキュメントのダウンロード

以前は Xcode の Preferences の Downloads でシミュレータやドキュメントのダウンロードができましたが、現在はドキュメントが無くなりシミュレータのみになっています。

ap-01-08.png

ドキュメントは随時更新されるものですから、おそらく齟齬が発生しないようにオンラインでのみの提供になったのだと思われます。



●Appendix 02 その他の有益なサイト


・Apple 社の公式ドキュメント(日本語版)とサンプルコード

現在は「日本語ドキュメント」のページの URL( https://developer.apple.com/jp/documentation/ )が変更されています。


・iOS Dev Center

iOS Dev Center サイトは現在「Apple Developer」サイトとなっています。


・Apple Developer Forums

現在は「Apple Developer Forums」のページの URL(https://developer.apple.com/forums/)が変更されています。
(フォーラムについては「Apple Developer/サポート/デベロッパフォーラム」にて日本語で紹介されています)



●Appendix 03 アプリ開発で収益を上げる方法


・アプリから収益を得る方法は3つ

現在は様々な収益モデルがありますので、詳細は「Apple Developer/App Store/ビジネスモデルと収益化」をご覧ください。



SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

SBクリエイティブ/【ダウンロード】絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応


絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(11)〜Chapter 12

2021. 01. 23
この記事は「絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】」(初版第1刷)を元に、Xcode 12.3(Swift 5.3.2)下における差異や覚書を記述しています。

手元にあって未読だったものを今頃読んでいるだけですので「絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応
2020年6月27日発売の最新版)」なら、この記事を読む必要も無駄な苦労をすることもないため、最新版の購入をお勧めします。



CHAPTER 12 アプリのリリース



●12-01 契約手続き


・実習12-1 アプリの公開に向けて契約手続きを行おう!

アプリを App Store で公開するには Apple Developer Program への登録と、App Store Connect(旧 iTunes Connect)での手続きが必要なのですが、内容や手順が随時更新されていますので注意が必要です。
(以降の「12-02 アプリ情報の設定」や「12-03 アプリのアーカイブ」についても同様)

公式サイトの Apple Developer Program でも概要は日本語で説明がされているのですが登録サイト自体は英語ですので、不安な方は最新版である「絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応」の購入を検討するのも良いですし、親切な方がウェブ上で手続きの仕方を公開しているかもしれませんので探してみるのも良いでしょう。



SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

SBクリエイティブ/【ダウンロード】絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応


絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(10)〜Chapter 11

2021. 01. 22
この記事は「絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】」(初版第1刷)を元に、Xcode 12.3(Swift 5.3.2)下における差異や覚書を記述しています。

手元にあって未読だったものを今頃読んでいるだけですので「絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応
2020年6月27日発売の最新版)」なら、この記事を読む必要も無駄な苦労をすることもないため、最新版の購入をお勧めします。



CHAPTER 11 アプリ開発の仕上げ



●11-01 アプリアイコンを登録する


・アイコンの概要

冒頭に「ナビゲータエリアで [Images.xcassets] を選択して」とありますが、現在は Assets.xcassets という名称になっています。

11-01-01.png

「Fig アイコンの登録」において、登録できるアイコンの画像のサイズですが、現在は各アイコン枠内に「●●x●●px」とサイズのピクセル数が明記されています。

11-01-02.png


・実習11-1 アイコンを登録しよう!

STEP3 において、画像ファイルは「SBクリエイティブ/【ダウンロード】絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】」にあるダウンロードデータをダウンロードして展開し、生成された「978-4-7973-8126-9/chapter11/実習11_1_Icon/Icon/Images.xcassets/AppIcon.appiconset」フォルダ内に アイコンの PNG 画像ファイルがあります。

用意されている画像は9種類ですが、現在は13種類必要なので残り4種は自作する必要があります。
ここではテスト目的で品質は問わないので、既存の画像を Mac のプレビューアプリなどで拡大縮小して作るのが手っ取り早いでしょう。

ピクセルサイズ用意されている画像用途
20 x 20px-iPad Notifications iOS 7-14 20pt (1x)
29 x 29pxiPad Settings iOS 7-14 29pt (1x)
40 x 40pxiPhone Notification iOS 7-14 20pt (2x)
iPad Notifications iOS 7-14 20pt (2x)
iPad Spotlight iOS 7-14 40pt (1x)
58 x 58pxiPhone Settings iOS 7-14 29pt (2x)
iPad Settings iOS 7-14 29pt (2x)
60 x 60px-iPhone Notification iOS 7-14 20pt (3x)
76 x 76pxiPad App iOS 7-14 76pt (1x)
80 x 80pxiPhone Spotlight iOS 7-14 40pt (2x)
iPad Spotlight iOS 7-14 40pt (2x)
87 x 87pxiPhone Settings iOS 7-14 29pt (3x)
120 x 120pxiPhone Spotlight iOS 7-14 40pt (3x)
iPhone App iOS 7-14 60pt (2x)
152 x 152pxiPad App iOS 7-14 76pt (2x)
167 x 167px-iPad Pro (12.9-inch) App iOS 9-14 83.5pt (2x)
180 x 180pxiPhone App iOS 7-14 60pt (3x)
1024 x 1024px-App Store iOS 1024pt



●11-02 起動画面を作成する


・起動画面の概要

現在はプロジェクト作成時にデフォルトで用意されている起動画面はまっさらなビューのみで、アプリ名やコピーライトのラベルはありません。


・デフォルトの起動画面

冒頭に「起動画面は、ナビゲータエリアにある [LaundhScreen.xib] に登録されています」とありますが、現在は「LaunchScreen.storyboard」になっています。

前述の通り、アプリ名やコピーライトを表示するラベル(およびラベルの Auto Layout の設定)はありません。

11-02-01.png


・実習11-2 起動画面を作成しよう

STEP3 において、上記の通りビューにラベルは配置されていないのでこの工程は不要になります。

STEP5 において、Navigation Bar のタイトルと Toolbar のボタンを削除するようにとありますが、現在は多少問題があります。

Navigation Bar および Toolbar 共に配置時点ではバーの背景が薄いグレーで表示されていますが、

11-02-05.png

Toolbar はボタンを削除しても背景は変わらないものの、Navigation Bar はタイトルを削除すると背景色が透明になってしまいます。

11-02-06.png

(View の背景色を黒にした場合)

11-02-07.png

これですと Navigation Bar の存在が分からないので、ドキュメントアウトラインで Title を選択し、ユーティリティエリアで Show the Attributes inspector を開き、Navigation Item の Title の文字列 Title を削除します。

11-02-08.png

こうすることでタイトルを非表示にしつつ Navigation Bar の背景色を維持することができます。

11-02-09.png

STEP6 において、「絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(7)〜Chapter 08」で述べたように無用の混乱を避けるため Add Missing Constraints は適用しないでください。

STEP7 において、先述の通り Pin は Add New Constraints と表示され、アイコンも変更されています。

また Update Frames のプルダウンメニューは無いので、Height を 64 に変更後に Add 1 Constraint をクリックします。

11-02-02.png

すると Navigation Bar を囲う枠線が赤色になり、ドキュメントアウトラインの View Controller Scene の右端に赤地白矢印のアイコンが出てきて、Missing Constraints(制約不足)として Need constraints for: X position, width(X 軸の制約が必要)と Need constraints for: Y position(Y 軸の制約が必要)だと示されています。

11-02-03.png

Navigation Bar の制約には、ドキュメントアウトラインで Navigation Bar を選択し、Add New Constraints を開いて Spacing to nearest neighbor の上と左右の赤い破線をクリックして有効にし、Add 3 Constraints をクリックして適用します。

11-02-04.png

これで予定通りの動作にはなるのですが、

11-02-10.png

(数秒後に Navigation Bar と Toolbar が消える)

11-02-11.png

画面上部にノッチが無い iPod touch 7th generation では問題ありませんが、 iPhone 12 などノッチのある機種に対応するため本来は高さ指定にマージンを加える必要があります。

11-02-13.png  



●11-03 外国語に対応する


・実習11-3 多言語化のためのサンプルアプリを作ろう!

STEP3 において、繰り返しになりますが「絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(7)〜Chapter 08」で述べたように無用の混乱を避けるため Add Missing Constraints は適用しないでください。

代わりに手動でラベルとボタンに制約を設定します。

まずボタンをビューに対して水平・垂直方向ともに中央に配します。

ドキュメントアウトラインで View と Button を選択し、

11-03-01.png

Align で Horizontal Centers と Vertical Centers にチェックを入れ、Add 2 Constraints をクリックして適用します。

11-03-02.png

ドキュメントアウトラインの View Controller Scene の右端に黄地白矢印のアイコンが出て、ラベルの制約が無いと警告されるので設定します。

11-03-03.png

11-03-04.png

ドキュメントアウトラインで View と Label を選択し、

11-03-05.png

Align で Horizontal Centers と Vertical Centers にチェックを入れ、Vertical Centers の値を -100 に設定し、Add 2 Constraints をクリックして適用します。
(iOS の座標系は左上が原点となっているので、水平方向の中央、垂直方向の中央から 100pt 上に配することになります)

11-03-06.png


・実習11-4 日本語の設定を追加しよう!

STEP5 において、現在は Include 項目が無くなり、Languages 項目は Localizations と変更されて Japanese の他に English--Development Language が追加されています。

11-03-07.png

また Tranlation フォルダにエクスポートされるファイルは ja.xliff ファイルだけでなく、Xcode 10 から導入された Xcode Localization Catalog 形式になっています。

Xcode Localization Catalog については「Apple Developer/Videos/WWDC 2018/New Localization Workflows in Xcode 10」で概要を把握することができます。
(「Apple Developer/ローカリゼーション」参照)

STEP7 において、インポートは(XLIFFファイルを直接指定するのではなく)生成された Translation フォルダ下の ja.xcloc フォルダを指定し Import をクリックします。
(ちなみに ja.xliff ファイルは Translation/ja.xcloc/Localized Contents/ フォルダ内にあります)

STEP9 において、Main.strings (Japanese) と LaunchScreen.strings (Japanese) ファイルはナビゲータエリアで確認できますが、

11-03-08.png

iOS アプリ開発 | スマホ・アプリの作り方入門/[iPhone] 多言語対応、Localizationの設定」によると InfoPlist.strings ファイルは現在手動で作る必要があるようです。


・アプリ名の多言語化

上記サイトの「アプリ名をローカライズ」の項に倣い、Info.plist の編集と InfoPlist.strings ファイルの追加と編集を行います。

ナビゲータエリアで Info.plist を選択します。

11-03-09.png

Key の項目上にカーソルを合わせ + ボタンをクリックし、新たに作られた項目の Key 欄に「Bundle display 〜」などと入力し、入力候補に「Bundle display name」が出てきたら選択します。
(入力時に大文字・小文字が区別されるので注意してください。「bundle 〜」と小文字で入力すると入力候補が絞り込まれません)

11-03-10.png

Value を英語版のアプリ名「Localization」と設定します。

11-03-11.png

次に InfoPlist.strings ファイルを作成します。

Xcode の File メニューから New → File... を選択し、iOS テンプレートから Resource カテゴリにある Strings File を選択して Next をクリックします。

11-03-12.png

ファイル名を InfoPlist.strings とし Create をクリックします。

11-03-13.png

ナビゲータエリアで InfoPlist.strings を選択し、本書にあるように日本語のアプリ名として「CFBundleDisplayName = "日本語アプリ";」と記述します。

11-03-14.png

ユーティリティエリアで Show the File inspector を選択し、ライブラリインスペクタの Localization カテゴリにある Localize... をクリックし、ダイアログで Japanese を選択します。

11-03-15.png

これで InfoPlist.strings ファイルが日本語用になります。

11-03-16.png

実行すると英語環境ではアプリ名が「Localization」に、

11-03-17.png

日本語環境では「日本語アプリ」になります。

11-03-18.png


・ストーリーボードの多言語化

ObjectID はXcode が自動で割り振っているものなので、本書と異なっていても気にすることはありません。

11-03-19.png

「ストーリーボードのプレビュー機能」において、「元文系大学生iOSアプリ開発ブログ/Xcode11 MacOS Catalina 10.15.2でのストーリボードのPreviewの仕方」によると現在はプレビューを表示する手順が変更されているようです。

まずナビゲータエリアで Main.storyboard を選択して、エディタエリアの右上にある Adjust Editor Options ボタンをクリックし、

11-03-20.png

ナビゲーションバーから Preview を選択します。

11-03-21.png

するとエディタエリアが左右に分割されて右側に(デフォルトである英語版の)プレビューが表示されます。

11-03-22.png

STEP2 の説明通り、エディタエリア右下の English と表記されている Language ボタンで Japanese を選択すると、日本語版のプレビューが表示されます。

11-03-23.png

11-03-24.png


・実習11-5 コード内の文字列を多言語化しよう!

「技術メモ NSLocalizedString() 関数の引数」において、現在の関数 NSLocalizedString(_:tableName:bundle:value:comment:) の引数は型やデフォルト値が若干異なるようです。

public func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String

STEP4 において、現在は Group に Supporting Files がありませんのでデフォルトの Localization のまま Create ボタンをクリックします。

11-03-25.png

「Columun NSLocalizedString() 関数の comment 引数の使い方」において、「List コード内の文字列の外国語対応」で文字列を指定する "" の前に @ が付いていますが、これは Objective-C の書式なので Swift では @ は不要です。



Apple Developer/Videos/WWDC 2018/New Localization Workflows in Xcode 10

iOS アプリ開発 | スマホ・アプリの作り方入門/[iPhone] 多言語対応、Localizationの設定

元文系大学生iOSアプリ開発ブログ/Xcode11 MacOS Catalina 10.15.2でのストーリボードのPreviewの仕方

SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

SBクリエイティブ/【ダウンロード】絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応


絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(9)〜Chapter 10

2021. 01. 13
この記事は「絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】」(初版第1刷)を元に、Xcode 12.3(Swift 5.3.2)下における差異や覚書を記述しています。

手元にあって未読だったものを今頃読んでいるだけですので「絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応
2020年6月27日発売の最新版)」なら、この記事を読む必要も無駄な苦労をすることもないため、最新版の購入をお勧めします。



CHAPTER 10 カメラアプリ開発で学ぶプロトコルとデリゲート



●10-01 カメラアプリは最適な実習課題


・実習10-1 カメラアプリを作ってみよう!

STEP3 において、イメージビューを画面いっぱいに広げる方法や制約を加える方法については「絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(7)〜Chapter 08」を参照してください。

STEP7 において、「絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(7)〜Chapter 08」で述べたように無用の混乱を避けるため Add Missing Constraints は適用しないでください。

STEP13 において、追加するコードの2行目の列挙体(列挙型) UIImagePickerControllerSourceType は UIImagePickerController.SourceType に、値名(ケース) Camera は camera に改名されています。

let camera = UIImagePickerControllerSourceType.Camera
// 'UIImagePickerControllerSourceType' has been renamed to 'UIImagePickerController.SourceType'
// 'Camera' has been renamed to 'camera'


let camera = UIImagePickerController.SourceType.camera

また先述の通り、7行目のインスタンスメソッド presentViewController(_:animated:completion:) は present(_:animated:completion:) に改名されています。

self.presentViewController(picker, animated: true, completion: nil)
// 'presentViewController(_:animated:completion:)' has been renamed to 'present(_:animated:completion:)'

self.present(picker, animated: true, completion: nil)

STEP14 において、インスタンスメソッド imagePickerController(_:didFinishPickingMediaWithInfo:) の第1仮引数が引数ラベルを指定しない設定に、第2引数が [UIImagePickerController.InfoKey : Any] 型になっています。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])

2行目のタイププロパティ UIImagePickerControllerOriginalImage は UIImagePickerController.InfoKey.originalImage に改名されています。

また「SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】」にあるように、UIImage 型へのキャスティングは as ではなく as! の誤りです。

let image = info[UIImagePickerControllerOriginalImage] as UIImage
// 'UIImagePickerControllerOriginalImage' has been renamed to 'UIImagePickerController.InfoKey.originalImage'

let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage

5行目のインスタンスメソッド dismissViewControllerAnimated(_:completion:) は dismiss(animated:completion:) に改名されています。

self.dismissViewControllerAnimated(true, completion: nil)
// 'dismissViewControllerAnimated(_:completion:)' has been renamed to 'dismiss(animated:completion:)'

self.dismiss(animated: true, completion: nil)

STEP15 において、プロジェクト作成時にチームを設定すると実行時にエラーが出る場合があるようです。

10-01-01.png

TICKLECODE/Xcode10で「Failed to register bundle identifier」エラーへの対応」によると、Bundle Identifier が重複して登録できないためとあるので、Budle Identifier が一意になるように日付を追加します。

Bundle Identifier 修正後に再度実行する際は、実行前にエラー「Failed to register bundle identifier」欄にある「Try Again」をクリックしてから実行しないと修正が適用されないので注意してください。

10-01-02.png

実行してアプリは起動しますが、カメラボタンをタップしてもカメラが起動せず、Xcode にエラーが2つ出力されます。

10-01-03.png

1つ目の「[Camera] Failed to read exposureBiasesByMode dictionary 〜」に関しては、「Stack Overflow/ios - Xcode Camera: Failed to read exposureBiasesByMode dictionary」や「GitHub/[Camera] Failed to read exposureBiasesByMode dictionary · Issue #1424」によると iPhone が iOS 14 の場合に起こるらしく、いくつか解決法も示されていますが対処療法のような感じなので、(このエラーを無視してもカメラは動かせるため)今回はスルーします。

2つ目の「[access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. 〜」は、「Qiita/【エラー】This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.」や「Qiita/iOS10ではカメラアクセスなどの目的を明示しないと強制終了する」によるとユーザの許諾を得ずにプライバシーに関わるデータや機能(カメラや写真)へアクセスしたために強制終了したということです。

現在はカメラや写真アルバムなどへアクセスする理由を明示することが必須になったため、Info.plist を編集する必要があります。
(「Developers.IO/[iOS 10] 各種ユーザーデータへアクセスする目的を記述することが必須になるようです」参照)

まずナビゲータエリアで Info.plist を選択し、リスト最下部にある Key の項目上にカーソルを合わせ + ボタンをクリックします。

10-01-05.png  

新たに作られた項目の Key 欄に「Privacy - Camera 〜」などと入力し、入力候補に「Privacy - Camera Usage Description」が出てきたら選択します。
(入力時に大文字・小文字が区別されるので注意してください。「privacy 〜」と小文字で入力すると入力候補が絞り込まれません)

10-01-06.png

Key の選択が済んだら Value 欄に「写真を撮影し、画面に表示します」と入力します。
この文字列はカメラ使用の許諾を取る際に出るダイアログのメッセージとなります。

10-01-07.png

同様に Key「Privacy - Photo Library Usage Description」、Value「撮影した写真を保存します」を追加します。

10-01-08.png

なお「iOS アプリ開発 | スマホ・アプリの作り方入門/iOSアプリCamera撮影, UIImagePickerController」によると、iOS11 から NSPhotoLibraryAddUsageDescription も追加する必要があるようです。
(今回のアプリに関しては無くても動作はします)

STEP16 において、アプリを実行しカメラボタンをタップすると、カメラのアクセス許可を求められます。
(「Privacy - Camera Usage Description」で設定した文字列が反映されています)
「OK」をタップして写真を撮影します。

10-01-09.png

STEP17 において、撮影後は確認画面になります。
「Retake」で再撮影することができますが、ここでは「Use Photo」で確定します。

10-01-10.png

「写真」アプリに保存するためのアクセス許可を求められますが、テストなので上2つの選択肢のどちらでも構いません。
(「Privacy - Photo Library Usage Description」で設定した文字列が反映されています)
この時点でダイアログの後ろにあるイメージビューに撮影した写真が反映されています。

10-01-11.png

アプリが待機状態に戻ります。
「写真」アプリに撮影した写真が追加されています。

10-01-12.png


・特定機能の実装手順を調べる方法

「最終的には API リファレンスだが、まずは検索」において、iOS Dev Center サイトは現在「Apple Developer」サイトとなっています。

また「Apple Developer Forumshttps://developer.apple.com/forums/)」の URL が変更されています。
(フォーラムについては「Apple Developer/サポート/デベロッパフォーラム」にて日本語で紹介されています)


・カメラを起動するコード

先述の通り、列挙体(列挙型) UIImagePickerControllerSourceType は UIImagePickerController.SourceType に、値名(ケース) Camera は camera に改名されていますが、「Table 画像の取得方法」にある値名 photoLibrarysavedPhotosAlbum は現在非推奨になっています。


・画像を表示するコード

先述の通り、インスタンスメソッド imagePickerController(_:didFinishPickingMediaWithInfo:) の第2引数 info は辞書 [UIImagePickerController.InfoKey : Any] 型になっており、「Table 辞書である引数 info の主なキー」で示されているキーとなる構造体 UIImagePickerController.InfoKey のタイププロパティは次のようになっています。

UIImagePckerControllerOriginalImage   → originalImage
UIImagePckerControllerCropRect          → cropRect
UIImagePckerControllerMediaMetadata → mediaMetadata



●10-02 プロトコル


・複数のプロトコルを批准させる

「List 複数プロトコルがある場合の書式」の記述法は現在エラーとなります。
Swift 3 からアンパサンド(&)でプロトコルのリストを区切る書式に変更されています。
(「RIP Tutorial/swift Tutorial/Swift Language - プロトコルの基本」参照)

var country: protocol<KyotoProtocol, WashingtonConvention>
// error: 'protocol<...>' composition syntax has been removed; join the protocols using '&'

var country: KyotoProtocol & WashingtonConvention


・実習の解説

「Fig delegate プロパティに代入できるインスタンスの型の確認」において、上記の通り delegate の型名が (UIImagePickerControllerDelegate & UINavigationControllerDelegate)? と & 区切りになっています。

10-02-01.png



●10-03 列挙体


・列挙体とは

「列挙体の宣言」において、「値名も慣例的には大文字で始まる英字を指定します」とありますが、Swift 3 から列挙体(列挙型)の値名(ケース)は小文字で始まる英字を指定するように変更されました。
(「GitHub/apple/swift-evolution/swift-evolution/0005-objective-c-name-translation.md at master」参照)

したがって「List 列挙体 Week の宣言」は以下のようになります。

enum Week {
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday
    case saturday
    case sunday
}


・実習の解説

先述の通り、列挙体 UIImagePickerControllerSourceType は UIImagePickerController.SourceType に、値名 Camera は camera に改名、値名 photoLibrarysavedPhotosAlbum は現在非推奨になっています。

UIImagePickerController.SourceType の定義は以下のようになっています。

public enum SourceType : Int {
    @available(iOS, introduced: 2, deprecated: 100000, message: "Will be removed in a future release, use PHPicker.")
    case photoLibrary = 0
    case camera = 1
    @available(iOS, introduced: 2, deprecated: 100000, message: "Will be removed in a future release, use PHPicker.")
    case savedPhotosAlbum = 2
}

「技術メモ 列挙体の値に割り振られた番号」において、現在の定義では自動割り当てではなく各値名に整数が設定されています。


・isSourceTypeAvailable() メソッド

クラスメソッド isSourceTypeAvailable(_:) の引数の型は UIImagePickerController.SourceType になっています。



●10-05 デリゲート

「List [ViewController.swift] に追加したコード」において、本文では「imageSelectController.delegate = self」とありますが、正しくは「picker.delegate = self」です。


・弁護士を Swift で書いてみる

「List 裁判を行うコード」において、変数 delegate はオプショナル Lawyer 型のインスタンスなので、メソッド defend() を実行するには(オプショナルチェーンなどで)開示する必要があります。

taro.delegate.defend()
// Value of optional type 'Lawyer?' must be unwrapped to refer to member 'defend' of wrapped base type 'Lawyer'

taro.delegate?.defend()


・実習の解説

前述の通り「List [ViewController.swift] に追加したコード」において、本文では「imageSelectController.delegate = self」とありますが、正しくは「picker.delegate = self」です。

また「List UIImagePickerController クラスの delegate プロパティの宣言箇所」において、参照方法が unowned(非所有参照)から weak(弱い参照)に、アクセス制御が open になっています。

weak open var delegate: (UIImagePickerControllerDelegate & UINavigationControllerDelegate)?



●10-06 型キャスティング


・辞書 info の値が AnyObject 型である理由

先述の通り、インスタンスメソッド imagePickerController(_:didFinishPickingMediaWithInfo:) の第2引数 info が [UIImagePickerController.InfoKey : Any] 型になっていますが、これは AnyObject がクラスのインスタンスしか扱えないのに対し、Any は構造体や値型も全て扱えるため、Swift 3 から変更になったようです。
(「Developers.IO/SwiftのAnyObjectとAnyについて」参照)

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])


・型キャスティングとは

SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】」にあるように、次節「実習の解説」も含め以降の本文やコードに出てくるキーワード as は as! の誤りです。


・実習の解説

先述の通り、辞書 info は [UIImagePickerController.InfoKey : Any] 型になっており、構造体 UIImagePickerController.InfoKey のタイププロパティ originalImage をキーに指定すると UIImage オブジェクトが取り出されますが、値が Any 型なので as! で UIImage 型にダウンキャスティングするということになります。



TICKLECODE/Xcode10で「Failed to register bundle identifier」エラーへの対応

Stack Overflow/ios - Xcode Camera: Failed to read exposureBiasesByMode dictionary

GitHub/[Camera] Failed to read exposureBiasesByMode dictionary · Issue #1424

Qiita/【エラー】This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

Qiita/iOS10ではカメラアクセスなどの目的を明示しないと強制終了する

Developers.IO/[iOS 10] 各種ユーザーデータへアクセスする目的を記述することが必須になるようです

iOS アプリ開発 | スマホ・アプリの作り方入門/iOSアプリCamera撮影, UIImagePickerController

RIP Tutorial/swift Tutorial/Swift Language - プロトコルの基本

GitHub/apple/swift-evolution/swift-evolution/0005-objective-c-name-translation.md at master

Developers.IO/SwiftのAnyObjectとAnyについて

SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

SBクリエイティブ/【ダウンロード】絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応


絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(8)〜Chapter 09

2021. 01. 03
この記事は「絶対に挫折しない iPhoneアプリ開発「超」入門【Swift & iOS8.1以降 完全対応】」(初版第1刷)を元に、Xcode 12.3(Swift 5.3.2)下における差異や覚書を記述しています。

手元にあって未読だったものを今頃読んでいるだけですので「絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応
2020年6月27日発売の最新版)」なら、この記事を読む必要も無駄な苦労をすることもないため、最新版の購入をお勧めします。



CHAPTER 09 iPhone 本体へのインストールと設定



●09-01 有料会員に登録する

以前は開発中のアプリを iPhone 実機でテストするには有料の iOS Developer Program に登録する必要がありましたが、現在は個人的な実機テスト目的であれば(Mac Developer Program と統合された)Apple Developer Program に登録する必要なく、Apple ID を開発者登録すれば実機テストを行うことができます。
(「Qiita/【Xcode】無料の実機ビルドでどこまでできるのか」、「iOS アプリ開発 | スマホ・アプリの作り方入門/実機でアプリを確認する, iOSアプリ作成準備」参照)

ただしテスト目的の限られた人数のユーザへのインストールや配信、または App Store で配信するには Developer Program への登録が必要です。



●09-02 iPhone を開発用に設定し、アプリをインストールする


・実習9-2 iPhone にアプリをインストールしよう!

実行する環境にも依るかと思いますが、実際に実機テストを行おうとしたところ2、3つまずいたところがありましたのでここに示します。
(Mac 環境:macOS Catalina 10.15.7、Xcode 12.3。iPhone 環境:iPhone XS、iOS 14.3)

なおスクリーンショットは前章の SNS アプリで試したもので、かつ問題解決後に撮影したのでエラー発生時の状況ではないことをご了承ください。

今回の場合、以前 Xcode で Apple ID を既に登録してしばらく放置していた状態で、Xcode の Preferences の Accounts では Apple ID は登録されていたもののサインアウト状態でしたので、まず Apple ID のパスワードでサインインしました。

09-01-01.png

その後「iOS アプリ開発 | スマホ・アプリの作り方入門/実機でアプリを確認する, iOSアプリ作成準備」を参考に左下にある Manage Certificates で Apple Development の証明書を作成しました。

09-01-02.png

しかしスキームから実機を選択して実行したところ、Team が設定されていないというエラーがでたので、プロジェクトの Signing & Capabilities にて、Team を None から自身の Personal Team に設定し直しました。

09-01-03.png

その後には以下のようなエラーが出ました。

「The operation couldn’t be completed. Unable to launch com.example.SNS- because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.」
(操作を完了できませんでした。com.example.SNS- を起動できません。無効なコード署名、不適切な権限、またはそのプロファイルがユーザーによって明示的に信頼されていないためです。)

詳細を見ると、

「Could not launch “SNS_”
Domain: IDEDebugSessionErrorDomain
Code: 3
Failure Reason: The operation couldn’t be completed. Unable to launch com.example.SNS- because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.」
(SNS_を起動できませんでした。
ドメイン:IDEDebugSessionErrorDomain
コード:3
失敗理由:操作を完了できませんでした。com.example.SNS- が無効なコード署名を持っているか、不十分なエンタイトルメントを持っているか、またはそのプロファイルがユーザーによって明示的に信頼されていないため、起動できません。)

とあり、デバイスでアプリの開発元が信頼されていないようでしたので、「MICRO FOCUS/Silk4J ユーザー ガイド/特定の環境のテスト/モバイルアプリケーションのテスト/iOS/パーソナル チーム プロファイルを使用した物理 iOS デバイス上でのテスト」や「TICKLECODE/Xcode・SwiftでのiPhone実機テストエラー、ビルドエラーの一覧と解決方法」を参考に iPhone の設定アプリの「一般/デバイス管理/Apple Development:〜」にて開発元を信頼するに設定したところ、無事に実機で動作させることができました。

09-01-04.png



Qiita/【Xcode】無料の実機ビルドでどこまでできるのか

iOS アプリ開発 | スマホ・アプリの作り方入門/実機でアプリを確認する, iOSアプリ作成準備

MICRO FOCUS/Silk4J ユーザー ガイド/特定の環境のテスト/モバイルアプリケーションのテスト/iOS/パーソナル チーム プロファイルを使用した物理 iOS デバイス上でのテスト

TICKLECODE/Xcode・SwiftでのiPhone実機テストエラー、ビルドエラーの一覧と解決方法

SBクリエイティブ/正誤情報-絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

SBクリエイティブ/【ダウンロード】絶対に挫折しないiPhoneアプリ開発「超」入門【Swift&iOS8.1以降 完全対応】

絶対に挫折しない iPhoneアプリ開発「超」入門 第8版 【Xcode 11 & iOS 13】 完全対応




Calendar
12 | 2021/01 | 02
Sun Mon Tue Wed Thu Fri Sat
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
Recent Articles
Apple Music


Swift
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(1)〜Chapter 02
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(2)〜Chapter 03
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(3)〜Chapter 04
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(4)〜Chapter 05
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(5)〜Chapter 06
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(6)〜Chapter 07
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(7)〜Chapter 08
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(8)〜Chapter 09
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(9)〜Chapter 10
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(10)〜Chapter 11
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(11)〜Chapter 12
絶対に挫折しない iPhoneアプリ開発「超」入門 第1版(12)〜Appendix

詳解Swift第5版(01)〜Swiftでプログラミング
詳解Swift第5版(02)〜関数
詳解Swift第5版(03)〜構造体
詳解Swift第5版(04)〜オプショナル
詳解Swift第5版(05)〜プロトコル
詳解Swift第5版(06)〜基本的なデータ型
詳解Swift第5版(07)〜パターン
詳解Swift第5版(08)〜クラスと継承
詳解Swift第5版(09)〜メモリ管理
詳解Swift第5版(10)〜拡張
詳解Swift第5版(11)〜エラー処理
詳解Swift第5版(12)〜クロージャ
詳解Swift第5版(13)〜ジェネリクス
詳解Swift第5版(14)〜メモリへのアクセスとポインタ
詳解Swift第5版(15)〜カスタム属性とDSL記法
詳解Swift第5版(16)〜GUI との連携

詳解Swift第4版(01)〜Swiftでプログラミング
詳解Swift第4版(02)〜関数
詳解Swift第4版(03)〜構造体
詳解Swift第4版(06)〜基本的なデータ型
詳解Swift第4版(07)〜パターン
詳解Swift第4版(08)〜クラスと継承
詳解Swift第4版(09)〜メモリ管理
詳解Swift第4版(10)〜拡張
詳解Swift第4版(11)〜エラー処理
詳解Swift第4版(12)〜クロージャ
詳解Swift第4版(13)〜ジェネリクス

詳解Swift第3版(01)〜Swiftでプログラミング
詳解Swift第3版(02)〜関数
詳解Swift第3版(03)〜構造体
詳解Swift第3版(05)〜基本的なデータ型
詳解Swift第3版(06)〜パターン
詳解Swift第3版(07)〜演算子
詳解Swift第3版(08)〜クラスと継承
詳解Swift第3版(09)〜メモリ管理
詳解Swift第3版(10)〜プロトコル
詳解Swift第3版(11)〜拡張
詳解Swift第3版(12)〜エラー処理
詳解Swift第3版(13)〜クロージャ
詳解Swift第3版(14)〜ジェネリクス

詳解Swift改訂版(01)〜Swiftでプログラミング
詳解Swift改訂版(02)〜関数
詳解Swift改訂版(03)〜構造体
詳解Swift改訂版(04)〜オプショナル
詳解Swift改訂版(05)〜基本的なデータ型
詳解Swift改訂版(06)〜パターン
詳解Swift改訂版(07)〜演算子
詳解Swift改訂版(08)〜クラスと継承
詳解Swift改訂版(09)〜メモリ管理
詳解Swift改訂版(10)〜プロトコル
詳解Swift改訂版(11)〜拡張
詳解Swift改訂版(12)〜エラー処理
詳解Swift改訂版(13)〜クロージャ
詳解Swift改訂版(14)〜ジェネリクス

詳解Swift(1)〜Swiftでプログラミング
詳解Swift(2)〜関数
詳解Swift(3)〜構造体
詳解Swift(4)〜オプショナル
詳解Swift(5)〜基本的なデータ型
詳解Swift(6)〜パターン
詳解Swift(7)〜演算子
詳解Swift(8)〜クラスと継承
詳解Swift(9)〜メモリ管理
詳解Swift(10)〜プロトコル
詳解Swift(11)〜拡張
詳解Swift(12)〜クロージャ
詳解Swift(13)〜ジェネリクス
詳解Swift(14)〜C/Objective-Cとのデータ受け渡し

Swift 2における文字列
文字列と文字(Swift 4)
SwiftUIの要点〜ビューの作成と結合
Categories
Tips
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
Amazon


Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
QR Code
QR
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Visitors