標籤:
背景故事
前兩天,本來一個運行正常、打包測試都沒問題的XCode工程突然爆出各種奇怪的Entitlement錯誤:
又或者
折騰了大半天時間以後,只發現一個地方,蘋果的開發人員認證被某同學重設了……雖然一再強調要小心,不要隨便點確定,但是,這種事情還是無法完全避免。我對那些不看資訊提示的同學已經是無語了。
然而,儘管我把認證重建,並更新了所有相關的設定檔(provisioning profile),卻還是各種莫名其妙的錯誤。
最後,我放棄了,找了一個專業做iOS開發的同學來幫忙,他指出:
XCode的緩衝有問題,有時候修改配置並不會生效。
在他的指導下,經過刪除帳號資訊->重啟XCode->重新登入->刪除設定檔->重啟XCode->重新下載設定檔->重新設定簽名。也不知道重啟了多少次XCode,總之,在所有錯誤消失的那一刻,我才長長鬆了一口氣:CAO~~~~~~~~~~~
老實說,XCode一切都好,就是這些簽名檔案的管理實在是有點反人類,跟itunes一樣,你好像永遠都無法理解它的邏輯。
隨後,我又google了一下我遇到的那個Entitlement錯誤,果然找到了一篇蘋果官方的文章《Entitlement問題定位指南》:
https://developer.apple.com/library/ios/technotes/tn2415/_index.html
本著“知其然,知其所以然”的精神,通讀了幾遍,終於對XCode管理設定檔的原理,有了稍微清晰一點的概念。以下是一些筆記:
什麼是Entitlement?
Entitlement(許可權),可以想象成App裡用於描述該App可以調用哪些服務的字串。蘋果的作業系統(mac os或者iOS)會通過檢查這個串,決定這個應用是否可以調用相關功能。比如iCloud許可權,推送服務,健康服務等。
常見的Entitlement錯誤
The executable was signed with invalid entitlements. The entitlements specified in your application‘s Code Signing Entitlements file do not match those specified in your provisioning profile. |
Could not install the application. Your code signing/provisioning profiles are not correctly configured ... you have an entitlement not supported by your current provisioning profile ... (error: 0xe8008016). |
Invalid Code Signing Entitlements. The entitlements in your app bundle signature do not match the ones that are contained in the provisioning profile. According to the provisioning profile, the bundle contains a key value that is not allowed: ‘[A1B2C3D4E5.com.appleseedinc.MyGreatApp ]‘ for the key "keychain-access-groups" in "Payload/MyGreatApp.app/MyGreatApp" |
entitlement ‘keychain-access-groups‘ has value not permitted by a provisioning profile |
查錯流程
是遇到Entitlement錯誤時,完整的檢查流程:
注意: PP = Provisioning Profile 設定檔
-
在Xcode裡設定目標應用的功能 (Target Capabilities)
-
蘋果開發人員使用者中心網站的 App ID服務
-
通過網站(與2相同)建立Provisioning Profile (預設定檔)
-
網站的預設定檔庫
-
檢查Provisioning Profile裡的使用權限設定
-
把Provisioning Profile安裝到Xcode裡
-
Xcode的本地Provisioning Profile檔案庫
-
在Xcode裡配置使用哪個Provisioning Profile檔案
-
在編譯日誌裡檢查哪個Provisioning Profile被使用
-
檢查打包好的應用裡包含的許可權
-
作業系統在安裝或者啟動時對App進行許可權檢查
第一步
Entitlement的產生,也就是一個App需要包含哪些許可權,可以通過Xcode自動化佈建也可以自己到開發人員網站上設定。
通過Xcode -> project -> Target -> Capabilities 開啟或者關閉指定功能
理論上,點了"Fix Issues",Xcode會自動做以下事情:
-
更新許可權需求
-
註冊App ID
-
為該App ID開啟或者關閉相關服務
-
建立或者更新Provisioning Profile
-
下載並安裝該Provisioning Profile檔案,因為後邊對應用進行簽名的時候需要用。
如果網路和運氣都好,那麼就什麼事都沒有了。
手動操作
但是,由於蘋果網站和中國網路的問題,可能不會那麼順利。如果Xcode沒法自動完成任務,那就需要手動進行相關操作:
有些服務會需要額外的資訊,比如推送服務,需要指定認證。
security cms -D -i /path/to/iOSTeamProfile.mobileprovision |
如果是從網站上下載的.mobileprovision,雙擊該檔案將自動安裝到Xcode指定的位置。
Xcode > Preferences > Accounts > (your account) > View Details
注意,這個是舊版的了,最新的7.3版本略有不同。其中最大的不同是,重新整理按鈕不見了!!取而代之的是“Download All”按鈕,大概是這樣子:
在Action一欄,如果這個檔案不在本地,會有“Download”下載按鈕,如果已經下載到本地了,就沒有了。
右鍵點已經下載的檔案,有2個選項:
1. 在Finder裡顯示
2. 刪除 (然後就可以重新下載了)
如果所需要的Provisioning Profile檔案都已經下載到本地,可以考慮讓Xcode自動選擇,具體的配置方法,參考蘋果的另外一個文檔:https://developer.apple.com/library/mac/qa/qa1814/_index.html
配置成功後,應該是這樣子:
當然,你也可以手動指定簽名標識(Code Signing Identity),和Provisioning Profile。
特別值得一提的是:如果Provisioning Profile檔案沒問題,當你指定了一個Profile以後,Code Sigining Identity的下拉式清單裡會提示這個Profile所屬的開發人員帳號。
如果沒有,則說明這個檔案有問題或者Xcode有問題。
(這也是我那個專業同事介紹的辦法,實測非常有用。)
到這一步,都正確的話,應該就沒問題了。
後邊是一些額外的檢查:
編譯順利的話,日誌裡會提示用到哪個Profile檔案:
命令列:
$ codesign -d --ent :- /path/to/the.app |
有幾個細節:
a. 在對App進行簽名的時候,相關的服務許可權就被從Profile檔案裡轉移到應用本身的簽名裡了。
b. Profile也會被內建到App裡。如果開啟App包查看,可以看到 embedded.mobileprovision
作業系統的檢查,就是基於剛剛說的兩個地方:應用自身的簽名,內建的Profile。當二者不一致時,就會報錯。除了許可權外,作業系統還會檢查App ID是否一致。
這是整個流程的最後一個可以檢查許可權是否錯誤的地方
其他
通常,Xcode會自動管理Entitlement檔案,所以我們並不需要在Xcode Project的Buidling Settings -> Code Signing -> Code Signing Entitlements 特意設定檔案。
舊版本的Xcode,你需要自己添加Entitlement檔案:
.entitlements檔案的格式(應該也是.plist格式)
-
Entitlement常見欄位介紹
-
beta-reports-active 是否可以通過TestFilight發布
-
team-identifier 開發帳號的團隊id,由10個數字和字母字元組成。這個值也是預設的App ID首碼。
-
get-task-allow Xcode是否可以對該應用進行調試。
-
application-identifier 應用的App ID,格式是 <prefix>.<bundle_id>
-
keychain-access-groups 鑰匙串許可權組 (更多可以參考 https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/)
-
push-notification 開啟推送服務後,會有這個欄位,它的值表示是生產環境(production)還是開發環境(development)。
作業系統還會對App ID的首碼(也就是團隊id)進行檢查,如果發現App簽名裡的首碼和profile檔案裡不一致,也會報錯。
App ID首碼的相關參考:
-
App ID首碼不一致錯誤: https://developer.apple.com/library/ios/qa/qa1879/_index.html
-
管理多個App ID首碼: https://developer.apple.com/library/ios/technotes/tn2311/_index.html
-
鑰匙串訪問警告: https://developer.apple.com/library/ios/qa/qa1726/_index.html
-
升級App時提示App ID與當前安裝的App不一致:https://developer.apple.com/library/ios/technotes/tn2319/_index.html#//apple_ref/doc/uid/DTS40013778-CH1-ERRORMESSAGES-UPGRADE_S_APPLICATION_IDENTIFIER_DOES_NOT_MATCH_THE_INSTALLED_APP
Xcode entitlement 問題定位和解決指南