Xcode 雙 Target 下 Sandbox 故障一例
如果你是 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 里的設置~
來自: http://imtx.me/archives/1949.html