Apple Notarization Service に対応させて、アプリの公証を受けるためには、いくつかの方法があります。
この記事では、複雑なケースも含めて、公証を受けるためのXcodeのプロジェクトの設定方法を解説します。
公証が始まる前にリリースしたアプリについては以下の記事で解説しています。
公証を得るための条件とは
公証を得るための条件は次の通りです。
2023年11月1日以降はnotarytool、もしくは、Xcode 14以降への移行が必要です。altoolやXcode 14未満はApple公証サービスにアップロードできなくなります。
- 実行ファイルが全てコードサイニングされている。
- アプリとコマンドラインツール (CLI) が全て Hardened Runtime が有効化されている。
- コードサイニング署名は “Developer ID Application 証明書”, “Developer ID Kernel Extension 証明書”, “Developer ID Installer 証明書”のいずれかが使用されている。
- コードサイニング署名にセキュアタイムスタンプが入っている。
- “com.apple.security.get-task-allow”や関連する設定がエンタイトルメントに含まれていない。
- macOS 10.9 SDK 以降のSDKを使用している。
- Xcode 14以降を使用する
実行ファイルにコードサイニングを行う
実行ファイルにコードサイニングをように設定します。コードサイニングの設定は、アプリ及びCLIと、埋め込むフレームワークで異なります。
アプリとCLIの設定
アプリやCLIのターゲットでは、次のような設定を行います。
- “Code Signing Identity” を “Developer ID Application” 証明書に設定する。
更に、 “Code Signing Style” を “Manual” にするときは、”Development Team”を空にし、”Provisioning Profile” は “none” に設定します。
フレームワークを埋め込む設定
アプリのターゲットで、フレームワークを埋め込むときにコードサイニングするように設定します。以下のいずれかの方法で設定します。
方法1 : Generalタブで設定する
GeneralタブのFrameworks, Libraries, and Embedded Content で、”Embed”の設定を”Embed & Sign”に設定する。
方法2 : Copy Files フェーズで設定する
Build PhasesタブのCopy Filesフェーズで、”Code Sign On Copy” をオンにする。
フレームワークをビルドする設定
フレームワークをビルドするターゲットでは、コードサイニングを行わないようにします。次のように設定します。
- “Code Signing Identity” を “Sign to Run Locally” に設定する
バンドルリソースの設定
バンドルリソースの場合、”Copy Bundle Resources” フェーズの場合は、特に設定は必要ないです。
しかし、”Copy Files”フェーズでファイルをコピーしている場合は、”Code Sign On Copy” をオンにする必要があります。
ヘルパープログラムの設定
ヘルパープログラムは、CLIとアプリパッケージとで異なります。
CLIは埋め込むときにコードサイニングします。アプリパッケージの場合は、アプリパッケージをビルドするときにコードサイニングして、埋め込むときは行いません。
Copy Filesフェーズのコピー先は “Contents/Helpers” フォルダにする必要があります。
Hardened Runtimeを有効化する
Hardened Runtimeを有効化します。Hardend Runtimeを有効化するには、次のように操作します。
- アプリのターゲット設定のSigning & Capabilitiesタブの”Capability”ボタンをクリックする
- “Hardened Runtime”をダブルクリックする
Sandboxが自動的にオンになることがあります。Sandboxまではオンにしたくない場合には、エンタイトルメントを編集します。
追加されたエンタイトルメント( .entitlements ファイル ) を開きます。
“App Sandbox”という項目があるので、NOに変更します。項目がないときは、Sandboxはオフのままになっています。
セキュアタイムスタンプを含める
セキュアタイムスタンプは、Xcodeでコードサイニングするときは自動的に埋め込まれます。但し、埋め込まれるタイミングは、”Archive”を実行したときです。
セキュアタイムスタンプが入っているかの確認方法
セキュアタイムスタンプが入っているかどうかの確認は、codesignコマンドで行います。
codesign -dvv アプリパッケージ.app
実行すると色々な項目が出力されます。その中に、次のように “Signed Time”という項目があるときは、セキュアタイムスタンプは入っていません。
Signed Time=Feb 23, 2020 15:46:07
セキュアタイムスタンプが含まれているときは、”Signed Time”という項目がなく、代わりに”Timestamp”という項目が現れます。
Timestamp=Feb 23, 2020 15:51:27
“com.apple.security.get-task-allow” 関連の設定を含めない
次にビルド設定の”Code Signing Inject Base Entitlements”を次のように設定します。
Debug : YesRelease : No
macOS 10.9 SDK以降のSDKを使用する
macOS 10.9 SDK以降のSDKを使用するのは、Xcodeのバージョンを適切なバージョン以降にすれば対応できます。
Xcode 6以降を使って開発すればmacOS 10.9 SDK以降のバージョンにリンクします。但し、これは、埋め込むヘルパープログラムやフレームワークについての話です。
公証を得るための開発環境の条件
公証を得るアプリの開発には、Xcode 10以降を使用する必要があります。Xcode 10の動作環境は、macOS High Sierra 10.13.6以降です。
Xcodeの動作環境については、次の記事にまとめています。
ビルド済みのライブラリなどを確認する方法
サードパーティのライブラリなど、バイナリしか持っていないものを埋め込んでいるときは、それらのリンクしているSDKや動作環境(Deployment Target)を調べる必要があります。
調べるには、otoolコマンドを使用します。
otool -l Example.framework/Example
otoolの調べる対象はフレームワークのディレクトリではなく、中に入っているバイナリファイルを指定します。
すると、色々な項目が出力されますが、”sdk”と”minos”という項目を探します。
Load command 7
cmd LC_BUILD_VERSION
cmdsize 32
platform 1
sdk 10.15
minos 10.15
“sdk”はリンクしているSDK、”minos”は”Deployment Target”の設定です。この例の場合は、macOS 10.15 SDKにリンクしていて、Deployment Targetは10.15になっています。
古いものがいるとどうなるの?
ちなみに、macOS 10.8 SDKなど、macOS SDK 10.9よりも古いSDKとリンクしているライブラリがあると、アプリが起動しなくなります。
ソースファイルを持っていないライブラリが古いSDKとリンクしているときは、開発元にお願いする他ありません。既に開発元が存在しない場合には、諦めましょう。そのライブラリを使わないようにするしかありません。
自分たちで同じ機能を持ったライブラリを開発するか、その機能を全く異なる方法で再実装するか、その機能を削減するかです。
条件を満たしているか確認する方法
最後に問題がないかをチェックします。チェックするには次のようにcodesignツールを使用します。
codesign --verify --deep --verbose --strict Example.app
問題がなければ、次のように出力されます。
Example.app: valid on disk
Example.app: satisfies its Designated Requirement
a sealed resource is missing or invalid
何かファイルがなくなっているときに出力されます。
埋め込んだフレームワークやヘルパーアプリに問題があるときは、”In Subcomponent” という情報も出ます。
MiddleSizeApp.app: a sealed resource is missing or invalid
In subcomponent: /Users/Example/Desktop/MiddleSizeApp 2020-02-23 15-52-15/Products/Applications/MiddleSizeApp.app/Contents/Helpers/HelperApp.app
file missing: /Users/Example/Desktop/MiddleSizeApp 2020-02-23 15-52-15/Products/Applications/MiddleSizeApp.app/Contents/Helpers/HelperApp.app/Contents/Resources/Base.lproj/Main.storyboardc/Info.plist
file missing: /Users/Example/Desktop/MiddleSizeApp 2020-02-23 15-52-15/Products/Applications/MiddleSizeApp.app/Contents/Helpers/HelperApp.app/Contents/Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib
file missing: /Users/Example/Desktop/MiddleSizeApp 2020-02-23 15-52-15/Products/Applications/MiddleSizeApp.app/Contents/Helpers/HelperApp.app/Contents/Resources/Base.lproj/Main.storyboardc/MainMenu.nib
file missing: /Users/Example/Desktop/MiddleSizeApp 2020-02-23 15-52-15/Products/Applications/MiddleSizeApp.app/Contents/Helpers/HelperApp.app/Contents/Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib