因为MacOS10.15以后,app store以外的MacOS应用是需要苹果的签名公证的。对于pyinstaller打包生成的MacOS应用,该如何进行MacOS应用的签名公证?(其实就是苹果要收钱,做签名公证必须每年要交大约700人民币的开发者订阅费)
jerkzhang
准备工作:
1、注册苹果开发者账号,不管是个人的还是公司的苹果开发者账号都行;
2、保证已经安装了Xcode,如尚未安装,自己去app store中下载Xcode即可;
3、保证已经安装了Xcode Command Line Tools,如尚未安装,在terminal终端命令行中输入“xcode-select --install”即可开始安装;
4、选择合适版本的pyinstaller,尽量新一点,别用太老的pyinstaller,好像是必须大于4.5版本。
第一步:配置开发者证书,并进行签名
打开“启动台 - 其他 - 钥匙串访问”;
如下图所示,在“ 钥匙串访问”的菜单中选择 “证书助理 - 从证书颁发机构请求证书...”;
在弹窗中填写信息,填写信息完成后保存到本地,
文件名为“CertificateSigningRequest.certSigningRequest”
注意,选择“存储到磁盘”。
登录苹果开发者账号 https://developer.apple.com/account/
点击左边侧栏上的“Certificates, Identifiers & Profiles”,进入Certificates, Identifiers & Profiles页面。
点击添加证书按钮(加号或者是“Create a certificate”按钮都是创建新证书的功能按钮)
选择如下选项:
Developer ID Application This certificate is used to code sign your app for distribution outside of the Mac App Store.
意思是这个证书就是为了分发在Mac APP Store外的MacOS应用的;上传之前请求生成并保存在本地的“CertificateSigningRequest.certSigningRequest”文件即可。
上传的时候,会有选择“G2 Sub-CA (Xcode 11.4.1 or later)”还是“Previous Sub-CA”,选择“Previous Sub-CA”即可,如果你的Xcode足够新,选择前者也可以。这类证书只要保持开发者账户每年成功扣费,证书都会有效,但是注意一下“Any certificates created after Feb 01, 2022 and associated to the previous Sub-CA will expire on Feb 01, 2027.”这句话,意思就是2022年2月1日之后,如果是选择Previous Sub-CA证书进行公证的应用,在2027年2月1日以后都会失效的,所以如果环境条件允许的话,建议采用G2吧。不过,也没关系,大不了2027年以后再换证书呗……
上传成功后,会生成证书供下载,下载即可,会得到一个叫“developerID_application.cer”的证书。
双击下载好的证书,先点击“查看证书”,把证书名的完整版给记下来,再点击“添加”。证书名大概就是类似Developer ID Application: XXX (XXX)的字符串,之后会用到,但XXX记得补全成自己的证书名。
回到苹果开发者网站的“Certificates, Identifiers & Profiles”页面左边栏的“Identifiers”,为APP创建ID,即Bundle ID,也叫“Bundle identifier”,就是APP ID。
APP ID分为两种,
如果没有要用通知等功能的需求,可以创建一张野卡(Wildcard)方便一点,不需要以后每次都创建即可。但如果有明确需求要通知等功能,那就创建Explicit APP ID即可。总之创建成功后,记住该APP ID,之后打包的时候要用。
在原有pyinstaller打包app的基础上加入如下两个参数:
--osx-bundle-identifier BUNDLE_IDENTIFIER Mac OS .app bundle identifier is used as the default unique program name for code signing purposes. The usual form is a hierarchical name in reverse DNS notation. For example: com.mycompany.department.appname (default: first script's basename) --codesign-identity IDENTITY Code signing identity (macOS only). Use the provided identity to sign collected binaries and generated executable. If signing identity is not provided, ad- hoc signing is performed instead.
--osx-bundle-identifier对应的是APP ID,
也就是上述生成的“Bundle ID”,也就是上述类似“com.domainname.* ”的字符串;
--codesign-identity 对应的是上述的证书名,
即类似Developer ID Application: XXX (XXX)的字符串。
加上后的pyinstaller命令类似如下示例:
pyinstaller -w -D --icon xxx.icns --osx-bundle-identifier "com.domainname.*" --codesign-identity "Developer ID Application: XXX (XXX)" target.py
上述只是一个例子,但osx-bundle-identifier和codesign-identity参数要带上。
登录开发者账户对应的APPLE ID账户中,生成一个“APP专用密码”。
因为之后要用到这个专用密码。
接下来对生成的MacOS的APP进行公证。
xcrun altool --notarize-app -t osx -f "XXX.zip" --primary-bundle-id "com.domainname.*" -u "开发者账户登录名" --password "APP专用密码"
注意,要在上传前,把.app文件打包成.zip文件。zip文件上传成功后会提示成功上传的。一般几分钟-1小时就能公证完成了(通常情况下是几分钟就ok了),届时会自动发邮件通知的。
另外建议打包成zip的方式参考如下这种方式,避免报错。
ditto -c -k --sequesterRsrc --keepParent "XXX.app" "XXX.app.zip"
也可以主动查询结果:
xcrun altool --notarization-info "上传成功后返回的一串ID用于查询结果" -u 开发者账户名称 --password "APP专用密码"
主动查询结果的最大作用是公证失败时,主动查询可以查到失败的原因。
自我验证一下该应用是否成功公证:
spctl --verbose=4 --assess --type execute XXX.app
如果结果说到accepted这类积极的词汇,那就是公证成功了。