Mac安装或者第一次打开软件,经常会出现下面对话框
从用户角度,有两种方法解决这个问题。
1.修改安全性与隐私设置,选择任何来源(系统偏好设置-安全性与隐私)
2.右键-打开
从开发者的角度,则要复杂一些了。
首先看看导致这种现象的原因。简单来说是Mac系统的GateKeeper在安装和打开软件时,对软件的来源和开发者进行校验。校验的内容是软件的签名,即软件内部的_CodeSignature目录内容。这是我的理解哈。
然后,就应该从软件的签名入手。
签名需要证书,有多种类型:Developer ID Application,Developer ID Installer,3rd Party Mac Developer Application,3rd Party Mac Developer Installer等。证书的生成,这里不做介绍,因为本人也不是很了解。
经验证,对于App,需要使用Developer ID Application进行签名,否则在第一次打开会提示未知开发者。而对于pkg安装包,则要使用Developer ID Installer进行签名,否则在安装的时候,会提示未知开发者。这里证书的选择还是比较重要的,不然,不管你签名是否成功,都过不了GateKeeper那关。LZ就是因为证书选择错了,浪费了好几天时间。
签名可以通过下面命令行实现(如果是Xcode项目,可以直接在Xcode中配置code sign):
# App签名
codesign --timestamp=none -f -v -s "Developer ID Application" test.app
# pkg签名
productsign --timestamp=none --sign "Developer ID Installer" ./test.pkg ./test_sign.pkg
官方给出了验证签名的方法,只有当结果为accepted的时候,软件才能正常呗打开或者安装
# App
spctl -a -v --type exec ./test.app
# pkg
spctl -a -v --type install ./test_sign.pkg
关于软件打包,这里有两个纠结的地方。
以前我都是用PackageManager来打包bundle,生成mpkg文件。虽然现在的Xcode没有附带PackageManager,不过还是可以通过下载旧版Xcode来获得。
我将mpkg文件进行签名,正常来说,安装包应该使用Developer ID Installer证书来签名,但是却一直报错。而当我用Developer ID Application证书来签名时,签名是成功了,却没能解决图一的问题。所以后来只能用命令行来打包。
一开始使用productbuild,将两个bundle作为组建,添加到一个pkg中很顺利,而且也可以正常安装这个pkg。但是,安装对话框中,没有标题显示。所以需要在外部包多一个pkg,通过distribution文件来定义标题和其他属性。
完整命令
export CODE_SIGN="Developer ID Installer"
productbuild --component ./a.bundle /Library/Internet\ Plug-Ins --component ./b.bundle /Library/Internet\ Plug-Ins --sign "${CODE_SIGN}" test.pkg
productbuild --distribution distribution.xml --sign "${CODE_SIGN}" ./installer.pkg
distribution.xml
<?xml version="1.0" encoding="UTF-8"?>
<installer-gui-script minSpecVersion="1">
<title>软件标题</title>
<organization>com.example</organization>
<options customize="never" allow-external-scripts="no" rootVolumeOnly="false"/>
<!-- List all component packages -->
<pkg-ref id="com.example.plugin" version="2005" auth="root" onConclusion="none">test.pkg</pkg-ref>
<!-- List them again here. They can now be organized as a hierarchy if you want. -->
<choices-outline>
<line choice="com.example.plugin"/>
</choices-outline>
<!-- Define each choice above -->
<choice id="com.example.plugin" visible="false" start_visible="false" title="plugin" description="plugin" enabled="false" start_selected="true" selected="true">
<!--customLocation="false"-->
<pkg-ref id="com.example.plugin"/>
</choice>
<pkg-ref id="com.example.plugin">
<bundle-version/>
</pkg-ref>
</installer-gui-script>
这时候,令人蛋疼的事情出现了:test.pkg could not be loaded。Google了很久都没有找到解决办法,也尝试在其他电脑上执行上面的命令,也不行。(如果有解决方案,请告诉我。。。)
所以后来混用pkgbuild和productbuild来解决这个问题
export CODE_SIGN="Developer ID Installer"
pkgbuild --identifier "com.example.plugin" --component ./a.bundle --install-location /Library/Internet\ Plug-Ins --component ./b.bundle --install-location /Library/Internet\ Plug-Ins --sign "${CODE_SIGN}" ./test.pkg
productbuild --distribution distribution.xml --sign "${CODE_SIGN}" ./installer.pkg
总结的时候,感觉不是很难,但是这个问题纠结了好几天,坑。Apple的官方文档说的不明不白的感觉,难道是我英文太差了吗。。。