如果你是 Manico 的用户,可能会知道 Manico 是一个双平台发布的 Mac App,即自有平台(官方版本)和 Mac App Store 平台。其中官方版本通过 Sparkle 工具来做自动更新,两个版本共享同一套代码库,通过 Xcode 的双 Target 来实现。
但是在去年年底的时候,Manico 发布了 2.0 版本时,紧接一周后发布了一个 2.0.1 版本,出现了一个比较严重的问题:即 2.0 版本无法通过 Sparkle 的自动更新升级到 2.0.1 版本,每次更新升级均失败。需要手动下载新版本再覆盖。每次当客服我也是这么回复给用户。今天我终于解决了这个困扰了几个月的问题,竟然是 Sandbox 引起的。
是这样的。
Manico 的 Xcode 项目一套源码 + 双 Target,一个叫 Manico,即官方版本,因为要通过 Sparkle 来支持自动更新,所以不能启用 Sandbox(Sparkle 不支持 Sandbox),另一个叫 Manico-MAS,去除了 Sparkle 等相关东西,但是有 IAP 支持,是用于提交给 Mac App Store。具体代码里就是用具体的宏来控制编译和相关功能了。
之前 Manico 1.0 的版本我也是这样用一套代码达到目标的,2.0 版本因为用 Swift 重写了,我就新开了一个库。就这样在重新配置的过程中出了点小差错,具体来说,还是 Xcode 的问题。请看下面两张图:
这两张图显示的很明白,第一张图:我选中了「Manico」这个 Target,右侧的 Capabilites 显示着 App Sandbox 是关闭状态。第二张图,我选中的是「Manico-MAS」这个 Target,右键显示 App Sandbox 和 IAP 是开启的。这些我都以为是正常工作的。
今天我又想起解决 Sparkle 不能自动更新的问题,于是查询了很多资料,发现这个异常是「launch path not accessible」,就是和 Sandbox 有关。但是我明明没有启用 Sandbox 啊,问题在哪里?原来在这里 Xcode 欺骗了我…我通过运行 [[NSProcessInfo processInfo] environment],发现 Manico 根本就是运行在 Sandbox 里的,那么为什么 Xcode 的配置界面没有显示出来?原来,最根本的一个决定选项在 Build Settings 里:
在 Build Settings 里的这个 Code Signing 里,有一个 Code Signing Entitlements,如果这里有具体指向一个文件,这个文件中描述了 Sandbox 开启,那么该 Target 就会运行在 Sandbox 下。所以 Manico 实际上是一直跑在 Sandbox 下的…
找到问题所在,我把这个选项给清空,然后重新编译了一个版本,终于跑起了 Sparkle 并且更新成功。困扰已久的问题终于解决。
结论:不要相信 Xcode 的 Capabilities 标签下的描述,也许在多 Target 下它自己都搞晕了,还是要多看看 Build Settings 里的设置~
什么时候才支持保存设置呢?