はじめに
これまでXcode10でビルドしたmacOSアプリのNotarizationの対応は行ったことがあるのですが、
Xcode11では実施したことがありませんでした。
実施にあたり色々とつまづいたので備忘のためドキュメントに残します。
前提条件
ビルド環境
- OS: macOS 10.14.6
- Xcode: 11.3 (11C29)
ビルドするアプリ
ネットワーク周りの設定を行うアプリで、下記の前提を含みます。
- macOS 10.15より導入されたNetworkExtensionを利用する
- Sparkleといったサードパーティのフレームワークを利用する
- Cocoa.frameworkといったApple謹製のフレームワークを利用する
ビルドするアプリがこれら前提を含まない場合は一部手順は不要となります。
Notarizationの取得までの概要
そもそもNotarizationとは何か、具体的にどのような手順で取得するのかについては過去の投稿を参考にしてください。
ざっくりと説明すると、
- 署名なしの状態でビルドする
- ビルド物にNotarizationに必要なビルドオプションをつけてcodesignで署名を付ける
- xcrun altoolを使ってNotarization Serviceに申請を行う
- 受理されたらxcrun staplerを使ってビルド物に公証をくっ付ける
という手順になります。
Xcode10ではこの手順で上手くいったのですが、Xcode11では後述する理由で上手く行きませんでした。
つまづいた点① Xcodeの時点で署名が必要
Xcode11ではmacOSアプリのビルドもiOSライクとなり、ビルド時にProvisioningProfileと証明書の指定が必要となります。
これについてはAppleDeveloperで証明書とProvisioningProfileを発行してXcodeで指定すれば良いのですが、次の点に注意してください。
ProvisioningProfile作成時には、DistributionのDeveloper IDを選択する
DevelopmentのmacOS App Developmentや、DistributionのMac App StoreでビルドするとNotarizationで下記のエラーが発生します。
The binary is not signed with a valid Developer ID certificate.
The signature of the binary is invalid.
そのため、必ずDistributionのDeveloper IDを選択してください。
つまづいた点② Xcodeで署名したものにcodesignで再署名してはいけない
当初私は、Xcode上でDevelopmentのmacOS App DevelopmentのProvisioningProfileと証明書で署名をして、codesignを使って「Developer ID Application XXX」の証明書で署名を付け直していました。
この方法だと、Notarizationは通るのですが、アプリを起動すると必ずTermination Reason: Namespace CODESIGNING, Code 0x1
というエラーが発生し、アプリが落ちてしまいます。
恐らく、再署名したことでアプリが改ざんされたと見なされて起動ができなくなっているのだと思われます。
尚、codesignには再署名する際に過去の署名時の属性を引き継ぐ--preserve-metadata
というオプションがありますが、これをフルで指定したとしても結果は変わりませんでした。
--preserve-metadata=list When re-signing code that is already signed, reuse some information from the old signature. If new data is specified explicitly, it is preferred. You still need to specify the -f (--force) option to enable overwriting signatures at all. If this option is absent, any old signature has no effect on the signing process. This option takes a comma-separated list of names, which you may reasonably abbreviate: identifier Preserve the signing identifier (--identifier) instead of generating a default identifier. entitlements Preserve the entitlement data (--entitlements). requirements Preserve the internal requirements (--requirements option), including any explicit Designated Require- ment. Note that all internal requirements are preserved or regenerated as a whole; you cannot pick and choose individual elements with this option. runtime Preserve the hardened runtime version (-o runtime flag, --runtime-version option) instead of overriding or deriving the version. For historical reasons, this option can be given without a value, which preserves all of these values as presently known. This use is deprecated and will eventually be removed; always specify an explicit list of preserved items
そのため、必ずXcodeのみで署名を完結するようにしてください。
つまづいた点③ XcodeでNotarizationに必要なビルドオプションを付ける
Apple公式のガイドに従って、これまではcodesignに次のオプションをつけて署名を行っていました。
- Secure Timestampを付けるため
--timestamp
オプションを付ける - Hardened Runtimeを有効化するため
--options=runtime
オプションを付ける - entitlementsが消えないように
--entitlements {entitlementファイル}
オプションを付ける
※指定するentitlementファイルはXcodeのプロジェクト設定に含まれているもの
全て、Xcode上で完結させるためこれらのオプション指定をXcode上に施します。
-
--timestamp
と--options=runtime
→ Build Settings > Signing > Other Code Signing Flags に設定 -
--entitlements {entitlementファイル}
→ Build Settings > Signing > Code Signing Entitlements に設定
つまづいた点④ Apple謹製フレームワークはEmbed Without Signingに指定する
Apple謹製のフレームワークをBuild PhasesのLink Binary With Librariesに指定すると、それらをアプリにスタティックで同梱するか、同梱せずダイナミックで利用するかをGeneralのFrameworks, Libraries, and Embedded Contentで選択する必要があります。
Notarizationを受けるためには同梱するライブラリーは署名をつけなければいけないため、「Enbed & Sign」を選択するように思えますが、ここは「Do Not Embed」を選択してください。
「Enbed & Sign」を選択すると、署名がつけられないとビルド時にエラーが発生します。
「Do Not Embed」を選択した場合利用するフレームワークに対応するdylibがContents/Frameworks配下に設置されますが、ビルド時に自動で署名をつけてくれます。
つまづいた点⑤ サードパーティフレームワークはEnbed & Signに指定する
Apple謹製のフレームワークとは異なり、「Enbed & Sign」を指定する必要があります。
この指定をしないと、NotarizationのタイミングでThe binary is not signed with a valid Developer ID certificate.
やThe signature of the binary is invalid.
が発生します。
最後に
以上の点を押さえれば、Xcode11でビルドしたアプリもNotarizationが受けられるようになるはずです。
お疲れ様でした。