iOS應用發布中的一些細節,iOS應用發布細節
iOS應用發布中的一些細節前言
這幾天最大的新聞我想就是巴黎恐怖襲擊
了,誒,博主每年跨年都那麼虔誠地許下“希望世界和平”的願望,想不到每年都無法實現,維護世界和平這麼難,博主真是有心無力啊,其實芸芸眾生的我們能做的大概就是不要闖紅燈、不搶小妹妹的甜筒、拉完屎記得沖水、打飯不逃票、不在澡堂小便、不挖人家牆角……其實就是維護世界和平了。
然而駭客組織Anonymous向ISIS宣戰了!
圖0
威武!
好吧迴歸這次文章主題,就列舉一些iOS應用發布中個人覺得還蠻容易忽略的一些細節。
再賣一次廣告,博主部落格已經搬家咯,新地址 ,排版布局更好,閱讀體驗更佳!!
Bundle identifier
Xcode中 Target -> General
中的bundle identifier
;
info.plist
中的Bundle identifier
;
認證中心的Identifiers
中App IDs
建立App時的Explicit App ID
;
以及iTunes Connect
中App資訊的套裝ID
必須保持一致!!
在info.plist或者Xcode裡的各種設定中,有很多$(XXX)
這樣的像指令碼一樣的東西,所以補充一點Xcode中的環境變數
Certificates認證
蘋果的認證體系一直都是iOS初學者無盡的夢魘,什麼開發認證、發布認證、推送認證,什麼ad hoc、內測分發、真機調試……我想每一個iOS初學剛開始接觸Apple的認證體系的時候內心是絕壁崩潰並且被心中的草泥馬踐踏的體無完膚的……。
其實蘋果的認證其實沒那麼玄乎,很多朋友弄不懂或者過了一段時間又不知道怎麼弄了,本質的原因是因為對非對稱式加密(公開祕密金鑰加密)的不理解~~導致的~~,所以為了完全的駕馭蘋果的認證,這些基礎的知識就是坑你的坎,必須跨過去的。
網上有各種解釋認證中心裏面每一種認證作用是什麼、怎麼建立、怎麼使用的,但是這也只能授人以魚,所以博主不會介紹每一種認證是幹嘛的,因為你看前年多了一個Pass Type ID Certificate
,去年又有了WatchKit Services Certificate
,今年又來一個Apple Pay Certificate
……根本就解釋這些認證不完嘛~,所以理解這些認證的統一規律才是王道!所謂
萬變不離其宗
很多資料都把認證分成兩種,分為開發認證(development)、以及發布認證(distribution)。但是博主認為這樣分類不是很不科學的,博主的理解的分類是這樣的
圖1
所以其實蘋果每年都添加的認證屬於其他認證
,這些其他認證並不是非必須的,而是使用了蘋果的某一項服務時才需要提供的憑證。而根憑證
是必須的,它簽名的APP是屬於這個認證的所有者的。
圖2
圖中我的這個帳號預設會有兩個不同用途的根憑證
,有兩個App,分別為App1、APP2,以及它們對應的兩種用途的推送認證(屬於其他認證
)。
假如我現在需要真機調試App1的推送,那麼我只要下載開發根憑證
以及App1的開發推送認證
然後雙擊開啟匯入鑰匙串,然後建立相應profile即可真機調試了;
假如現在我要發布APP2,那麼我只要下載發布根憑證
以及APP2的發布推送認證
,然後建立相應地profile即可打包上傳App Strore了。(這裡因為發布的特殊性,所以發布的電腦必須是建立這個發布根憑證
的電腦)。
profile(描述檔案)下文還有篇幅介紹。
我TM都繞暈了,確實有點麻煩有點複雜,果然iOS開發門檻就是高啊,但是哥就喜歡。
App IDs
在相應地App的edit中可以添加多套APNs推送認證(其他的認證也類似的)
圖3
在這裡聲明一下,其他認證
其他認證產生的時候,使用的certSigningRequest
檔案可以和產生根憑證
的certSigningRequest
的不一致,也就是說產生其他認證
時不一定需要產生根憑證
的電腦,所以這裡也坑了無數的人調試推送,這個在下文推送的那些事詳細填坑。
Provisioning Profiles描述檔案
圖4
我想這個介面一彈出來的時候,蛋蛋憂傷迎面撲來。然後怒點 Fix issue
,然後你們團隊負責管理憑證的基友突然發現認證中心多了好多好亂的認證以及描述檔案,然後他爆了一句:what the huck!刪掉了帶有Xcode *
的認證以及描述檔案,然後自己又暴力的點了一發Fix issue
,然後你突然調試不了了,再暴擊Fix issue
鍵,最後整個團隊都只有通過Fix issue
來真機調試了……。
所以慎點Fix issue
,如果點擊這個選項,聰明的(~~蠢哭的~~)Xcode就會自己管理描述檔案,然後各種莫名其妙的帶有Xcode *
的認證以及描述檔案……
其實只要堅信一點,認證、裝置ID、AppID、描述檔案都弄對了就絕逼不會出問題的!
描述檔案工作原理
圖5
-
- 其實描述檔案工作的原理就是在APP打包或者真機調試的時候,讓Xcode去檢查描述檔案裡面的BundleID與這個APP的BundleID是否對應。
- 對應的話就會去
keyChain
尋找有沒有相應地認證(所以認證要下載好,並且匯入keyChain
)
- 如果有認證存在的話就會檢查認證的類型,如果是開發認證,則會檢查調試的裝置是否加入了描述檔案裡面的信任裝置ID列表,如果裝置沒有在描述檔案的列表中,則無法調試;如果認證類型是發布認證則不會檢查裝置ID列表。
額外地,如果公司新增了測試機,並且在認證中心的Devices
中添加了新測試機的ID,這樣描述檔案也要相應地更新,然後重新下載,下載完之後可以先刪除舊的描述檔案(博主直接覆蓋的方式貌似描述檔案沒有更新啊),你們可以自己做實驗咯,描述檔案的路勁/Users/XXX/Library/MobileDevice/Provisioning\ Profiles
XXX
你的使用者名稱。
不要覆蓋!記得先刪除,可以免除很多問題。
推送的那些事
如果說億萬級使用者的推送服務並不是企鵝自己定製的而都是由蘋果APNs推送的話,那蘋果的推送就真的牛逼了,但是有時候測試推送,經常APNs要死不活的,推了半天才到,有一次在APNs沙箱環境怒推1000多條,然後這條隊列持續了半個月才推完~~。所以、扣扣肯定是定製的推送,有錢就是討厭,那麼任性。
但是蘋果推送的開發是比較簡單地,如果沒有進階推送需求基本就不用寫代碼了,只要配置好認證一切OK。
現在常用的後台server中,一般將推送認證以及推送認證的私密金鑰匯出p12交給後台人員即可。
PHP有點調皮,還需要轉換成pem
產生PHP需要的Pem認證
準備:
第三步根憑證的私密金鑰這裡是一個坑!因為一個App的推送認證的建立可以和根憑證建立的電腦不同,也就是keyChain產生的certSigningRequest
不一樣,所以私密金鑰也是不一樣的,在這裡產生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;elseecho 'Message successfully delivered' . PHP_EOL;fclose($fp);?>
將上面的代碼複製,儲存成push.php
然後根據上面“產生PHP需要的Pem認證”的步驟產生push.pem
兩個檔案放在同一目錄
執行下面的命令
DavidDay$ php push.php
結果為
Connected to APNSMessage successfully delivered
是不是就推送成功了呢?呵呵噠
打包、分發及內測
關於打包是有很多姿勢的,每個人都有各自的喜好,大部分規矩的做法都是使用Xcode的一條龍服務的:
這樣的做法比較保險,因為archive
只會編譯出真機的二進位碼,所以不用擔心匯出的ipa真機裝不起。
另一種姿勢是使用xcodebuild
工具,純Shell編譯,比較不好處理錯誤,但是逼格滿滿啊,想詳細瞭解這種姿勢的可以看看官方文檔 ,或者參考這位同學的分享
當然嘛,博主作為拖拖派的忠實擁躉,博主打包ipa的時候是這樣的:
圖6
隨時build隨時轉ipa。
分發內測一般都會使用第三方的平台,fir、蒲公英 都很好呀~
關於提交審核這裡,一般archive過去了,認證正確都沒問題的,當然還是要檢查項目是否調用了私人API,之前用reveal ,提交應用的時候忘了移除,千不該萬不該的還是用了Xcode的upload工具,也不報錯,在iTunesConnect中構建版本也出現了,只是狀態“正在處理”,一般這個狀態持續10分鐘~2個小時就會通過了,然後博主自信關機下班,想不到第二天構建版本還是“正在處理”,然後猜想是不是iTunes出問題了又怒傳了N個包,依然是“正在處理”,後來準備發郵件,開啟郵箱,尼瑪!
圖7
原來調用了私人介面,忘記移除reveal了~,回顧起來這裡有三個大坑,
打包項目認證選擇必須正確 (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 ")
總結
突然想起我哥說的一句話
有時候有些女人就像飯堂飯菜,雖然難吃,但是去晚了也會沒有的!
珍惜身邊的人。
感覺這個總結什麼鬼?有點傷感,嗯,iOS應用的發布,每個從業者都應該能夠熟練的對發布進行操作和意外處理的。
沒錢結婚。