开发者证书在其它开发电脑的安装:
遇到的问题:在apple开发者官网下载的开发者证书安装后没有对应的私匙。
原因:只有在申请证书的那台MAC(标记A电脑)上下载证书,才有密钥,其他的电脑下载是没有。
解决方式:在A电脑的钥匙串中,导出证书(.p12),然后其他的电脑导入那个证书
info.plist 设置支持系统最低版本
info.plist一定要添加的最低支持版本号,否则上传App Store Connect时将会被机审拒绝。
正确地组织Bundle(软件包)
正确地组织即将发布的软件包,MacOS的软件需要构建在一个带.app后缀的文件夹内(注意“.app”这个后缀一般是被隐藏的),且该文件夹内根目录只应该有Contents这一文件夹。Contents/MacOS文件夹下只能放主程序的可执行文件。否则会导致签名失败。
Contents/MacOS文件夹下不能存在除可执行文件外的其它文件,否则签名会显示成功,公证也显示,但是用户启动软件时会提示“软件已损坏”,用命令行工具spctl进行包验证时会显示“a sealed resource is invalid”的错误。
所有代码都需要签名
所有将要发布的代码都要签名。项目里的代码包括:app,frameworks,app extensions,plugins 。
经过完整签名的包,如果没有公证,在其它电脑上运行时将提示包由未知开发者发布,将不允许通过一般方式运行(无法双击应用启动,但fn+鼠标右键选择运行也可以启动)。
Apple 商店包签名注意事项
要点1:对于嵌套的代码签名,在签名父文件夹(包)之前必须保证子文件夹(包)已正确签名;
要点2:macOS 10.10.4及以后的版本,GateKeeper将拒绝加载使用@rpath或绝对路径的包外的动态链接库(不包括使用/System, /Library和/usr/的绝对路径);
要点3:info.plist中需设置最低支持系统;
要点4:codesign的--deep参数并不被官方推荐,它被推荐用于紧急维修或临时调整中。所以显式的对每个代码签名将是一个明智的选择(论签名脚本的重要性);
要点5: 在签名可执行程序时需添加 -o runtime 参数,使运行时允许额外的安全检查。
注意:出现签名权限错误时,先使用ls -lR命令查看文件的所属用户,如果是属于root用户,重新复制一份,新复制的文件即是本地用户
关于公证Mac 公证一般流程:
- 确认权限文件内没有 “com.apple.security.get-task-allow”,有则去除;
- 包签名,且确保可执行文件的签名都加上了 “-o runtime” 选项(强化运行);
- 用自己喜欢的方式生成自己喜欢的格式的包(dmg,zip,pkg);
- 使用xcrun altool 命令将上传apple的公证服务器(xcrun altool的一般使用方法如下:xcrun altool --notarize-app -f app.dmg --primary-bundle-id my-app.myapp -u username -p password);
- 上传成功后会返回RequestUUID(公证要挂号排队的,这个就是排队的号码)。xcrun altool --notarization-info RequestUUID -u username -p password 可以查询公证进度,如果公证失败了,将会返回一个带有详细错误网页的url;
- 如果公证成功了,可以使用xcrun stapler staple app.dmg命令将公证票据放入dmg内,当dmg被装载时系统将不再请求公证服务器获取包的相关信息,而是会使用包内的公证票据进行验证,这样在离线的情况下安装软件将不会再报“无法验证的第三方”的错误。
- 最后可以使用xcrun stapler validate app.dmg验证公证结果;8、使用xattr -w com.apple.quarantine myapp.app可以再次弹出Gatekeeper弹窗(即提示用户是否启动第三方软件的弹窗);
命令行创建DMG的方法
MacOS系统自带的命令行工具 hdiutil 可创建 DMG 格式的文件。
其中可以选用的 DMG 格式有 UDZO(压缩格式,默认)、UDRO(只读格式)、UDBZ(Better compressed image)、UDRW(可读写格式)UDTO(DVD 格式)。
直接使用hdiutil不太方便,可以使用基于hdiutil的python的第三方库:DmgBuild。推荐使用UDZO格式。
验证dmg包
验包时不要在.dmg内运行app,需要将app拖动到/Applications目录内(或其它的本地文件夹)再启动。因为从磁盘映像(或/Downloads目录)中运行新下载的app ,将导致GateKeeper把app隔离在一个未指明的只读文件系统中,可能会引起一些使用相对路径的资源无法被正确引用。
macOS对系统资源的控制十分严格,对于使用第三方开发工具来构建app的人来说,许多限制或规则需要手动去适配,有些繁琐。
Qt WebEngine不兼容Mac App Store
因为:
1、Chromium的部分代码使用了几个私有API,非公共API是不允许在App Store使用的。
2、提交到App Store的应用必须开启沙盒功能,而应用沙盒功能的开启会干扰Chromium自带的沙盒初始化,从而导致Chromium初始化失败,这也关系到了私有API的使用。此外,独立的Chromium本身并未正式测试过启用沙盒功能时的表现,即使成功绕过App Store的限制,这也不能保证库的功能正常。
使用Clang混合编译C++与Obj-C
在Qt中使用Objective -C的代码:Clang编译器允许混合C++和Objective -C代码,在源文件中添加.mm后缀启用此模式,然后将.mm文件添加到.pro文件的OBJECTIVE_SOURCES项中(SOURCES项中不需要再添加)。
一个遇到的问题:Clang编译器一直将OBJ-C的.h文件认成C++的头文件,导致无法完成编译。通过简单测试发现可以将OBJ-C的.h文件内容放到.mm文件中通过编译,因为.mm文件可以进行OBJ-C与C++混合的编程,但是.h文件似乎只能纯C++或者纯OBJ-C。
Mac App Store 内购参考链接:blog.csdn.net/u011574810/…
在Xcode中测试StoreKit参考链接:
developer.apple.com/documentati…
App Store 服务器类型内购的标准流程:
1.程序向服务器发送请求,获得一份产品列表。
2. 服务器返回包含产品标识符的列表。
3. 程序向App Store发送请求,得到产品的信息。
4. App Store返回产品信息。
5. 程序把返回的产品信息显示给用户(App的store界面)
6. 用户选择某个产品
7. 程序向App Store发送支付请求
8. App Store处理支付请求并返回交易完成信息。
9. 程序从信息中获得数据,并发送至服务器。
10. 服务器纪录数据,并进行审(我们的)查。
11. 服务器将数据发给App Store来验证该交易的有效性。
12. App Store对收到的数据进行解析,返回该数据和说明其是否有效的标识。
13. 服务器读取返回的数据,确定用户购买的内容。
14. 服务器将购买的内容传递给程序。
App Store 内购的一些注意事项:
Apple建议在服务器端存储产品标识,而不要将其存储在plist中。 这样就可以在不升级程序的前提下添加新的产品。(但我们mindmaster的商品似乎是固定不变的,所以可以写死在程序,但为了最求灵活,最好还是向服务器请求);主要依靠c++与oc混合编译完成相应功能;
由于用户可以在设置程序中禁用购买的功能,所以在请求支付之前,程序应该首先检查支付是否可以被处理。 调用SKPaymentQueue的canMakePayments方法来检查。
内购代码经过简单修改即可复用(appurchasehelper.mm)
关于沙盒运行下的文件操作权限的问题:
部分关键:
1、可执行文件的权限签名加上com.apple.security.files.user-selected.read-write;
2、用户使用Mac原生的文件选择对话框选择文件后,软件将在关闭前都能获取到该文件的操作权限;
3、缓存的文件均生成于对应bundle id的沙盒路径下;
部分参考网站:
| developer.apple.com/library/arc… | macOS Code Signing In Depth |
|---|---|
| developer.apple.com/forums/thre… | Signing a Mac Product For Distribution |
| developer.apple.com/library/arc… | macOS Code Signing In Depth |
| doc.qt.io/qt-5.9/osx-… | Qt for macOS - Deployment |
| mediaarea.net/blog/2018/0… | WebEngine使用sanbox需要做的事前准备 |
\
杂项:
- MacOS文件夹下不能存在除可执行文件外的其它文件,否则签名会显示成功,公证也显示,但是用户启动软件时会提示“软件已损坏”,用命令行工具spctl进行包验证时会显示“a sealed resource is invalid”的错误;
- buildmg工具自动生成dmg时,默认格式是‘UDBZ’,该格式生成的dmg包体积较小,但是会破环.app的签名,该用‘UDZO’格式(该格式也是“磁盘工具”转换功能的默认格式)虽然较大(MindMaster 8.5.4会大30mb)但可以解决签名问题;
- 当运行软件时,出现错误日志:Cannot mix incompatible Qt library (version 0xxxxx) with this library (version 0xxxxx)的解决方法是,删除包内所有Qt相关的库,使用deployqt命令重新发布一次;
- 签完名后,打开软件出现崩溃,崩溃日志内关键信息为“code signing blocked mmap()” MacOS签名后打开软件出现崩溃弹窗,其中的关键信息为“code signing blocked mmap()”,MacOS拒绝加载目标lib,自检步骤如下:
1、使用codesign -v -vvv somelib.dylib检查文件是否损坏;
2、使用codesign -d -vvv somelib.dylib检查该文件的数字签名;如果步骤2出现有”Library validation warning=OS X SDK version before 10.9 does not support Library Validation”的警告,则说明生成的lib没有设置最低系统支持版本号。可尝试在info.plit中指定最低支持系统(Minium system version)如果是使用文本编辑器打开info.plit的话则使用(LSMinimumSystemVersion)指定(其实都是对info.plit这个xml格式的文件修改)。如果还是没有解决问题,考虑对可执行文件(比如dylib.app等)使用上完整权限文件的签名(codesign --entitlements)。
\