Xcode中 Target -> General
中的bundle identifier
;php
info.plist
中的Bundle identifier
;html
證書中心的Identifiers
中App IDs
新建App時的Explicit App ID
;ios
以及iTunes Connect
中App信息的套裝ID
必須保持一致!!json
在info.plist或者Xcode裏的各類設置中,有不少$(XXX)
這樣的像腳本同樣的東西,因此補充一點Xcode中的環境變量xcode
蘋果的證書體系一直都是iOS初學者無盡的夢魘,什麼開發證書、發佈證書、推送證書,什麼ad hoc、內測分發、真機調試……我想每個iOS初學剛開始接觸Apple的證書體系的時候心裏是絕壁崩潰而且被心中的草泥馬踐踏的體無完膚的……。服務器
其實蘋果的證書其實沒那麼玄乎,不少朋友弄不懂或者過了一段時間又不知道怎麼弄了,本質的緣由是由於對非對稱加密(公開密鑰加密)的不理解~~致使的~~,因此爲了徹底的駕馭蘋果的證書,這些基礎的知識就是坑你的坎,必須跨過去的。微信
網上有各類解釋證書中內心面每一種證書做用是什麼、怎麼建立、怎麼使用的,可是這也只能授人以魚,因此博主不會介紹每一種證書是幹嗎的,由於你看前年多了一個Pass Type ID Certificate
,去年又有了WatchKit Services Certificate
,今年又來一個Apple Pay Certificate
……根本就解釋這些證書不完嘛~,因此理解這些證書的統一規律纔是王道!所謂架構
萬變不離其宗app
不少資料都把證書分紅兩種,分爲開發證書(development)、以及發佈證書(distribution)。可是博主認爲這樣分類不是很不科學的,博主的理解的分類是這樣的socket
圖1
根證書
是與開發者或者企業對應的,只要是被根證書
簽名的App均可以理解爲是這個證書對應的開發者開發的。因此一個根證書
能夠簽名多個App。
其餘證書
呢是與具體的App對應的,一個App的推送證書是沒法給另外一個App使用的,因此一個其餘證書
只能爲一個App簽名,更確切的說是這個App須要使用某一項Apple的服務而去產生這個其餘證書
。
因此其實蘋果每一年都添加的證書屬於其餘證書
,這些其餘證書並非非必須的,而是使用了蘋果的某一項服務時才須要提供的憑證。而根證書
是必須的,它簽名的APP是屬於這個證書的全部者的。
圖2
圖中個人這個帳號默認會有兩個不一樣用途的根證書
,有兩個App,分別爲App一、APP2,以及它們對應的兩種用途的推送證書(屬於其餘證書
)。
假如我如今須要真機調試App1的推送,那麼我只要下載開發根證書
以及App1的開發推送證書
而後雙擊打開導入鑰匙串,而後建立相應profile便可真機調試了;
假如如今我要發佈APP2,那麼我只要下載發佈根證書
以及APP2的發佈推送證書
,而後建立相應地profile便可打包上傳App Strore了。(這裏由於發佈的特殊性,因此發佈的電腦必須是建立這個發佈根證書
的電腦)。
profile(描述文件)下文還有篇幅介紹。
我TM都繞暈了,確實有點麻煩有點複雜,果真iOS開發門檻就是高啊,可是哥就喜歡。
在相應地App的edit中能夠添加多套APNs推送證書(其餘的證書也相似的)
圖3
在這裏聲明一下,其餘證書
其餘證書生成的時候,使用的certSigningRequest
文件能夠和產生根證書
的certSigningRequest
的不一致,也就是說產生其餘證書
時不必定須要產生根證書
的電腦,因此這裏也坑了無數的人調試推送,這個在下文推送的那些事詳細填坑。
圖4
我想這個界面一彈出來的時候,蛋蛋憂傷迎面撲來。而後怒點 Fix issue
,而後大家團隊負責管理證書的基友忽然發現證書中心多了好多好亂的證書以及描述文件,而後他爆了一句:what the huck!刪掉了帶有Xcode *
的證書以及描述文件,而後本身又暴力的點了一發Fix issue
,而後你忽然調試不了了,再暴擊Fix issue
鍵,最後整個團隊都只有經過Fix issue
來真機調試了……。
因此慎點Fix issue
,若是點擊這個選項,聰明的(~~蠢哭的~~)Xcode就會本身管理描述文件,而後各類莫名其妙的帶有Xcode *
的證書以及描述文件……
其實只要堅信一點,證書、設備ID、AppID、描述文件都弄對了就絕逼不會出問題的!
描述文件工做原理
圖5
keyChain
查找有沒有相應地證書(因此證書要下載好,而且導入keyChain
)額外地,若是公司新增了測試機,而且在證書中心的Devices
中添加了新測試機的ID,這樣描述文件也要相應地更新,而後從新下載,下載完以後能夠先刪除舊的描述文件(博主直接覆蓋的方式貌似描述文件沒有更新啊),大家能夠本身作實驗咯,描述文件的路勁/Users/XXX/Library/MobileDevice/Provisioning\ Profiles
XXX
你的用戶名。
不要覆蓋!記得先刪除,能夠免除不少問題。
若是說億萬級用戶的微信推送服務並非企鵝本身定製的而都是由蘋果APNs推送的話,那蘋果的推送就真的牛逼了,可是有時候測試推送,常常APNs要死不活的,推了半天才到,有一次在APNs沙箱環境怒推1000多條,而後這條隊列持續了半個月才推完~~。因此微信、扣扣確定是定製的推送,有錢就是討厭,那麼任性。
可是蘋果推送的開發是比較簡單地,若是沒有高級推送需求基本就不用寫代碼了,只要配置好證書一切OK。
如今經常使用的後臺server中,通常將推送證書以及推送證書的私鑰導出p12交給後臺人員便可。
PHP有點調皮,還須要轉換成pem
生成PHP須要的Pem證書
準備:
第三步根證書的私鑰這裏是一個坑!由於一個App的推送證書的建立能夠和根證書建立的電腦不一樣,也就是keyChain產生的certSigningRequest
不同,因此私鑰也是不同的,在這裏生成Pem時,注意要使用推送證書的私鑰!
操做過程:
把推送證書(.cer)轉換爲.pem文件,執行命令:
openssl x509 -in 推送證書.cer -inform der -out 推送證書.pem
把推送證書導出的私鑰(.p12)文件轉化爲.pem文件:
openssl pkcs12 -nocerts -out 推送證書私鑰.pem -in 推送證書私鑰.p12
對生成的這兩個pem文件再生成一個pem文件,來把證書和私鑰整合到一個文件裏:
cat 推送證書.pem 推送證書私鑰.pem >PHPPush.pem
而後把這個PHPPush.pem給後臺基友們,就能夠下班啦。
固然測試推送也比較麻煩,須要模擬真實的推送環境,通常須要後臺提供幫助,可是遇到一些後臺同事,他們有強烈地信仰着鄙視鏈的話,很鄙視iOS,內心早就稱呼你「死前段」多年了,還那麼多事……
因此關於調試推送,博主教你本身推本身!不麻煩別人。
只要拷貝這段代碼
<?php // devicetoken $deviceToken = '你的deviceToken'; // 私鑰密碼,生成pem的時候輸入的 $passphrase = '123456'; // 定製推送內容,有一點的格式要求,詳情Apple文檔 $message = array( 'body'=>'你收到一個新訂單' ); $body['aps'] = array( 'alert' => $message, 'sound' => 'default', 'badge' => 100, ); $body['type']=3; $body['msg_type']=4; $body['title']='新訂單提醒'; $body['msg']='你收到一個新消息'; $ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', 'push.pem');//記得把生成的push.pem放在和這個php文件同一個目錄 stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); $fp = stream_socket_client( //這裏須要特別注意,一個是開發推送的沙箱環境,一個是發佈推送的正式環境,deviceToken是不通用的 'ssl://gateway.sandbox.push.apple.com:2195', $err, //'ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); if (!$fp) exit("Failed to connect: $err $errstr" . PHP_EOL); echo 'Connected to APNS' . PHP_EOL; $payload = json_encode($body); $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; $result = fwrite($fp, $msg, strlen($msg)); if (!$result) echo 'Message not delivered' . PHP_EOL; else echo 'Message successfully delivered' . PHP_EOL; fclose($fp); ?>
將上面的代碼複製,保存成push.php
而後根據上面「生成PHP須要的Pem證書」的步驟生成push.pem
兩個文件放在同一目錄
執行下面的命令
DavidDay$ php push.php
結果爲
Connected to APNS Message successfully delivered
是否是就推送成功了呢?呵呵噠
關於打包是有不少姿式的,每一個人都有各自的喜愛,大部分規矩的作法都是使用Xcode的一條龍服務的:
選擇相應地描述文件、證書
選擇ARM架構機型(模擬器是Intel架構的,真機是ARM架構的,不能通用)
product -> archive
而後就能夠選擇導出ipa在第三方平臺分發測試或者上傳App Stroe審覈了
這樣的作法比較保險,由於archive
只會編譯出真機的二進制碼,因此不用擔憂導出的ipa真機裝不起。
另外一種姿式是使用xcodebuild
工具,純Shell編譯,比較很差處理錯誤,可是逼格滿滿啊,想詳細瞭解這種姿式的能夠看看官方文檔 ,或者參考這位同窗的分享
固然嘛,博主做爲拖拖派的忠實擁躉,博主打包ipa的時候是這樣的:
圖6
隨時build隨時轉ipa。
分發內測通常都會使用第三方的平臺,fir、蒲公英 都很好呀~
關於提交審覈這裏,通常archive過去了,證書正確都沒問題的,固然仍是要檢查項目是否調用了私有API,以前用reveal ,提交應用的時候忘了移除,千不應萬不應的仍是用了Xcode的upload工具,也不報錯,在iTunesConnect中構建版本也出現了,只是狀態「正在處理」,通常這個狀態持續10分鐘~2個小時就會經過了,而後博主自信關機下班,想不到次日構建版本仍是「正在處理」,而後猜測是否是iTunes出問題了又怒傳了N個包,依然是「正在處理」,後來準備發郵件,打開郵箱,尼瑪!
圖7
原來調用了私有接口,忘記移除reveal了~,回顧起來這裏有三個大坑,
Application Loader
,速度快,錯誤報告也精準。打包項目證書選擇必須正確 (Xcode7如下 選擇項目編譯target爲Iphone Device 不要鏈接手機 不然會 ,Xcode7中不須要拔出真機,由於多了一個build only device
的選項)
編譯target選錯了 報錯
ITMS-90530 "Invalid MinimumOSVersion. Apps that only support 64-bit devices must specify a deplyment target of 8.0 or later" IMTS-90208 "Invalid Bundle. The bundle xxx.app does not support the minimum OS version specified in the Info.plist" IMTS-90502 "Invalid Bundle. Apps that only contain the arm64 slice must also have'arm64' in the list of UIRequiredDeviceCapabilities in Info.plist ")