【Unity】【Mac】通过Mac App Store分发应用之签名过程

2 篇文章 0 订阅

这是一篇学习和实操笔记。

1、了解Mac 签名

1.1 公证Mac App

1)通过Mac App Store 分发的 Mac App,无须公证,因为在提交过程App Store已经对其进行了相同的安全检查。

image-20240411110347717.png

2)非Mac App Store 分发的 Mac App,需要公证,否则会提示用户“应用可能会损害电脑”等,

image-20240411110551377.png

3)问答:Mac 公证服务团队答疑

1.2 代码签名
  1. 所有的Mac App,都必须进行代码签名。

    • 如果使用Unity 编译导出.app文件,则需要手动为代码签名,也就是为.app进行签名
  2. 确定可执行文件

    根据file 指令,查看对应的文件是否为main executable,A main executable says Mach-O … executable.

    $ file /Applications/XXX.app/Contents/PlugIns/AkSoundEngine.bundle/Contents/MacOS/AkSoundEngine
    /Applications/XXX.app/Contents/PlugIns/AkSoundEngine.bundle/Contents/MacOS/AkSoundEngine: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64]
    /Applications/XXX.app/Contents/PlugIns/AkSoundEngine.bundle/Contents/MacOS/AkSoundEngine (for architecture x86_64): Mach-O 64-bit bundle x86_64
    /Applications/XXX.app/Contents/PlugIns/AkSoundEngine.bundle/Contents/MacOS/AkSoundEngine (for architecture arm64):  Mach-O 64-bit bundle arm64
    ​
    # 根据打印,可知AkSoundEngine不是main executable
    
  3. 决定签名顺序

    需要从内向外签署代码,也就是如果组件 A 依赖于组件 B,则先签署 B,然后再签署 A。

    举例:DaemonWithApp 产品有以下内容: ConfigApp.app, Core.framework, Share.appex, and Daemon,签名顺序应为:Core.frameworkShare.appexConfigApp.app,daemon是独立的,签名顺序随意。

  4. 配置权限文件

    代码签名可以包含App权限文件 .entitlements ,当 macOS 运行一个进程时,entitlements文件会授予该进程可执行文件在代码签名所包含的权限。

  5. 嵌入distribution provisioning profile

    在entitlements声明的权限,一般必须都需要在distribution provisioning profile中进行授权。当然也有一些不需要在distribution provisioning profile授权,就可以在entitlements中应用的权限。

    注意:一定要将distribution provisioning profile文件放在 XXX.app/Contents/ 路径下,且修改文件名为embedded.provisionprofile

image-20240411101319103.png

  1. 确定代码签名的正确性

    % codesign -d -vv <filePath>
    ​
    codesign -d -vv /Applications/XXX.app/Contents/PlugIns/unitypurchasing.bundle
    Executable=/Applications/XXX.app/Contents/PlugIns/unitypurchasing.bundle/Contents/MacOS/unitypurchasing
    Identifier=com.unity.purchasing.unitypurchasing
    Format=bundle with Mach-O universal (x86_64 arm64)
    CodeDirectory v=20500 size=1200 flags=0x10000(runtime) hashes=28+5 location=embedded
    Signature size=4844
    Authority=TestFlight Beta Distribution
    Authority=Apple Worldwide Developer Relations Certification Authority
    Authority=Apple Root CA
    Info.plist entries=26
    TeamIdentifier=XXX
    Runtime Version=11.0.0
    Sealed Resources version=2 rules=13 files=1
    Internal requirements count=1 size=116
    
  2. 为每一种代码类型签名

    % codesign -s <CodeSigningIdentity> <PathToExecutable>
    # 举例子:
    % codesign -f -s '3rd Party Mac Developer Application: XXX'  "/Users/taihe/Desktop/NTSDK.app/Contents/Frameworks/libmonobdwgc-2.0.dylib"
    /Users/XXX/Desktop/XXX.app/Contents/Frameworks/libmonobdwgc-2.0.dylib: replacing existing signature
    % codesign -f -s '3rd Party Mac Developer Application: XXX'  "/Users/XXX/Desktop/XXX.app/Contents/Frameworks/UnityPlayer.dylib"
    /Users/XXX/Desktop/XXX.app/Contents/Frameworks/UnityPlayer.dylib: replacing existing signature
    % codesign -f -s '3rd Party Mac Developer Application:XXX  "/Users/XXX/Desktop/XXX.app/Contents/Frameworks/libMonoPosixHelper.dylib"
    % codesign -f -o runtime -s '3rd Party Mac Developer Application: XXX' --entitlements "/Users/XXX/Desktop/App.entitlements" "/Users/XXX/Desktop/XXX.app"
    /Users/XXX/Desktop/XXX.app: replacing existing signature
    

    说明:

    1、不能对库代码进行包含权限文件(.entitlements)的代码签名,它会阻止可执行文件的程序运行,导致mac app打开就crash。

    2、不能使用sudo 运行 codesign,因为codesign在签署代码时依赖用户账户信息,使用sudo等工具会更改用户账户,从而造成一些意外情况.

    3、如果要签署包含权限的可执行文件,需要添加 --entitlements <entitlementsPath>,其中 <entitlementsPath> 是为该可执行文件创建的权限文件的路径。

    4、如果使用Developer ID 进行代码签名,需添加 --timestamp 选项,以包含安全时间戳。

    5、如果使用Developer ID 进行代码签名,需添加 -o runtime 选项,启用加固运行时。

  3. 避免使用--deep

    签署代码时,不要在 codesign 中使用--deep 选项。--deep会对其签署的每个代码项应用相同的entitlements。例如,如果你有一个内嵌命令行工具的应用程序,而应用程序和工具需要不同的权限,那么 codesign --deep 就会对两者应用相同的权限。

1.3 决定以什么样的格式分发Mac App

在Mac 上安装的应用支持四种格式:

  1. 从 Mac App Store上下载的直接就是.app

  2. 从非 Mac App Store上下载安装的可能是:

    以下3种格式可以嵌套

4、Entitlements

描述可执行文件的权限信息的文件,我一般叫它权限文件,内容以key-value形式展示。在对应用程序进行代码签名时,Xcode 会将权限文件、开发者账户中的信息以及其他项目信息结合起来,为应用程序应用一组最终的权限。

2、签名过程

注意:如果使用Xcode直接上传到Mac App Store则不用签名和公证。

2.1、使用unity编译后修改info.plist文件

1)App Uses Non-Exempt Encryption :设置为 NO,这样在Apple Connect Strore - App - 构建版本处,就不需要每次都确认“出口合规证明”;

  <key>ITSAppUsesNonExemptEncryption</key>
  <false/>

2)检查 Bundle OS Type code 的值:其value值是一个四字母的代码,用于指示包类型。对于应用程序,代码是APPL;对于框架,是FMWK;对于捆绑包,则是BNDL。默认值是从捆绑扩展名中推导出来的,如果无法推导,则默认值是BNDL。

  <key>CFBundlePackageType</key>
  <string>APPL</string>

3)App Category(LSApplicationCategoryType) :设置应用程序的类型

  <key>LSApplicationCategoryType</key>
  <string>public.app-category.games</string>

4)LSMinimumSystemVersion:设置App在 macOS 中运行所需的最低操作系统版本。

  <key>LSMinimumSystemVersion</key>
  <string>13.0.0</string>
2.2、创建并修改.entitlements文件

使用Xcode创建一个和你项目同名的Mac 工程,不需要配置该项目的描述文件和证书,仅仅只需要添加App Sandbox Capability。

我们项目是一个游戏项目,所以按照项目功能,勾选了网络和文件读写。

image-20240412102234556.png
打开生成的App.entitlements,添加TeamID和AppID

  <key>com.apple.developer.team-identifier</key>
  <string>TeamID</string>
  <key>com.apple.application-identifier</key>
  <string>AppID</string>

补充:上传到Mac App Store应用都必须开启沙盒功能,验证签名后的app是否开启沙盒功能,苹果提供了两种方式

1)活动监视器查看

image-20240322154747030.png

2)命令行查看

% codesign -dvvv --entitlements - <path to your app>

image-20240322154412751.png

2.3、在.app/Contents路径下添加发布环境的.provisionprofile文件

注意: 必须.app/Contents路径下,文件名也必须是embedded.provisionprofile

从Mac App Store 或 TestFlight下载后的应用,.app/Contents就不会显示embedded.provisionprofile文件了。

image-20240412105522970.png

2.4、签名指令
# 1. 对~/XXX.app/Contents/PlugIns路径下的bundle进行代码签名,注意不可以使用--entitlements选项,注意这里使用的是:3rd Party Mac Developer Application证书
# codesign -f -s <CertificationName> <BundlePath>
$ codesign -f -s '3rd Party Mac Developer Application: AAA' "XXX.app/Contents/PlugIns/unitypurchasing.bundle"
# 终端会打印:XXX.app/Contents/PlugIns/unitypurchasing.bundle: replacing existing signature
​
# 2. 对~/XXX.app/Contents/Frameworks路径下的库文件进行代码签名,注意不可以使用--entitlements选项,注意这里使用的是:3rd Party Mac Developer Application证书
# codesign -f -s <CertificationName> <FrameworkPath>
$ codesign -f -s '3rd Party Mac Developer Application: AAA' "XXX.app/Contents/Frameworks/libmonobdwgc-2.0.dylib"
# 终端会打印:XXX.app/Contents/Frameworks/libmonobdwgc-2.0.dylib: replacing existing signature
​
# 3. 对.app进行代码签名,注意这里使用的是:3rd Party Mac Developer Application证书
# codesign -f -s <CertificationName> --entitlements <EntitlementsPath> <AppPath>
$ codesign -f -s '3rd Party Mac Developer Application: AAA' --entitlements "/Users/XXX/Desktop/App.entitlements" "/Users/XXX/Desktop/XXX.app"
# 终端会打印:XXX.app: replacing existing signature
​
# 4. 生成安装包并进行安装包签名,注意这里使用的是:3rd Party Mac Developer Installer证书
# productbuild --component <AppPath> /Applications --sign <CertificationName> <PkgPath>
$ productbuild --component /Users/XXX/Desktop/XXX.app /Applications --sign "3rd Party Mac Developer Installer: AAA" /Users/XXX/Desktop/XXX.pkg
​
# 终端会打印:
productbuild: Adding component at /Users/XXX/Desktop/XXX.app
productbuild: Signing product with identity "3rd Party Mac Developer Installer: AAA" from keychain /Users/XXX/Library/Keychains/login.keychain-db
productbuild: Adding certificate "Apple Worldwide Developer Relations Certification Authority"
productbuild: Adding certificate "Apple Root CA"
productbuild: Wrote product to /Users/XXX/Desktop/XXX.pkg
productbuild: Supported OS versions: [Min: 13.0.0, Before: None]

补充: 是在 “钥匙串访问“ 中复制粘贴的证书名称

image-20240412104540816.png

3. 签名过程遇到的问题

1、Asset validation failed (90869) Invalid bundle. The “XXX.app” bundle supports arm64 but not Intel-based Mac computers. Your build must include the x86_64 architecture to support Intel-based Mac computers. To support arm64 only, your macOS deployment target must be 12.0 or higher. For details, view: https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary.
原因: Apple要求如果应用只支持Apple Silicn,macOS deployment target必须 >=12.0,而Unity Build的Mac app设置是10.13.0。

解决: 修改Info.plist文件中, LSMinimumSystemVersion 对应的value值,按照需求设置,只要大于12.0就行。

        <key>LSMinimumSystemVersion</key>
        <string>13.0.0</string>

2、Asset validation failed (90236) Missing required icon. The application bundle does not contain an icon in ICNS format, containing both a 512x512 and a 512x512@2x image. For further assistance, see the Human Interface Guidelines at https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons/.

原因: 缺失应用图标

解决: 按照要求添加即可,在这里推荐一款 “免费生成iPhone、iPad、Mac OS平台应用Icon的Mac App:AppIcon Maker(xcAsset Creator)

3、ITMS-90889: Cannot be used with TestFlight because the bundle at ‘MyApp.app’ is missing a provisioning profile. Main bundles are expected to have provisioning profiles in order to be eligible for TestFlight.

原因: .app/Contents路径下缺失发布环境的.provisionprofile文件。

解决:

1)在.entitlements文件中添加TeamID和AppID

image-20240409154047012.png
2)在XXX.app/Contents/ 路径下添加 embedded.provisionprofile 文件

参考链接:

Packaging Mac software for distribution

Resolving Library Loading Problems

Creating Distribution-Signed Code for Mac

TestFlight, Provisioning Profiles, and the Mac App Store

  • 16
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值