iOS 推送及bundle ID provision生成教程

Auditore發表於2018-01-03

人力有時而窮,記憶力終究還是擋不住時間消磨,期間遇到各種奇葩問題,也是隻有親身經歷才能理解。所以現在記下來,防止以後走彎路。

事先準備:

1).首先你得有一個付費的開發者賬號

2).Mac、iPhone裝置得準備好

開始進入正題

第一步:先準備好CSR,CSR又叫.certSigningRequest檔案,用於請求證書和描述檔案,所以這也叫請求檔案。生成方法如下:

1.開啟鑰匙串

點選如圖所示的“從證書頒發機構請求證書……”

iOS 推送及bundle ID provision生成教程
圖1 獲取CSR

2.跳出證書助理,使用者電子郵件地址可隨意填,但最好填你自己郵箱,請求選擇“儲存到磁碟”

iOS 推送及bundle ID provision生成教程
圖2 儲存CSR到本地磁碟

3.點選繼續後得到CertificateSigningRequest.certSigningRequest檔案

第二步:登入developer.apple.com登入你的開發者賬號

iOS 推送及bundle ID provision生成教程
圖3 申請bundle ID

1.如上圖所示,先生成APPID既bundleID,點選加號然後生成bundleID,這裡沒什麼難點,主要需要注意的是bundleID命名的規範性


iOS 推送及bundle ID provision生成教程
圖4 申請推送證書

2.現在生成推送證書,如上圖,一般需要生成開發證書和APPStore用的證書,development對應開發證書,production對應APPStore證書


iOS 推送及bundle ID provision生成教程
圖5  開發者證書選擇如上圖

點選右上角加號,如果是development則選擇如上圖所示的Apple Push Notification service SSL (Sandbox),點選繼續,選擇我們剛剛生成的App ID也就是bundle ID

iOS 推送及bundle ID provision生成教程
圖6 申請證書需要上傳CSR

接著上傳我們生成好的CertificateSigningRequest.certSigningRequest檔案,然後點選生成證書,最後一步的時候記得下載證書到桌面,後面會用到到這裡tui'son推送證書就生成了,接下來我們生成描述檔案provision

3.描述檔案生成也大同小異,沒什麼難點development就選擇development,AppStore就選Appstore,也是上傳CSR得到描述檔案provision,然後download到桌面備用。

第三步:我們回到桌面,安裝推送證書,這裡有一個坑,最好我們別直接雙擊安裝,否則有可能出現沒有專用祕鑰的情況,如下圖中第一個證書,發現了嗎?它是沒有展開箭頭的,意味著它沒有專用金鑰。這樣是不行的。

iOS 推送及bundle ID provision生成教程
圖7  錯誤的證書,缺少專用金鑰

在這裡我弄了進一個上午,反覆刪除證書和provision然後重新安裝,甚至重新生成bundle ID和provision以及推送證書全部重來一遍,都無效,網上搜尋來的方法幾乎都試過,還是無果。突然我看到某個論壇有人說了句,直接把證書拖到登入裡,一試,果然可以了!真是大坑!


iOS 推送及bundle ID provision生成教程
圖7  我們得把證書拖入登入這個選項內

如上圖,已經有下拉箭頭了,說明有專用金鑰了。你可能會問,為什麼我千方百計要把專用金鑰弄出來呢?直接安裝證書,然後選好對應provision和bundleID不就好了嗎?程式也可以正常執行啊。是的,沒錯,是可以執行,但是推送證書所需要的p12檔案你就倒不出來了!推送需要證書和專用金鑰的p12檔案!p12檔案!P12檔案!

接下來我們就可以倒出p12檔案了,右鍵證書選擇匯出

iOS 推送及bundle ID provision生成教程
圖8  匯出證書


iOS 推送及bundle ID provision生成教程
圖9  匯出證書p12

終於看到了我夢寐以求的p12檔案,淚奔

好的,把它放到桌面上,同理,也別忘記了把對應的專用金鑰匯出來,如下圖


iOS 推送及bundle ID provision生成教程
圖10 匯出金鑰p12檔案

現在我們就得到了development的推送證書和專用金鑰的.p12檔案,接下來我們需要把它們合成為一個.pem檔案,這個才是伺服器做APNs推送需要用到的檔案。

第四步:生成.pem檔案

準備材料:1.生成推送證書的sh指令碼,2.推送證書和provision的.p12檔案,然後很重要一點我們需要把我們的推送證書和專用金鑰改成如下圖一樣的名字,因為指令碼里的證書和金鑰名字得和你的檔案對應,指令碼才能找到檔案並執行命令

apns-dev-cert.p12和apns-dev-key.p12


iOS 推送及bundle ID provision生成教程
圖10 生成pem需要的檔案

第一個是推送證書的p12第二個是專用金鑰的p12第三個是生成pem的指令碼,新建一個資料夾,把這三個檔案放在這個資料夾裡,然後用終端cd到這個資料夾,再然後執行命令列sh create_pem.sh

如果你不想給自己的pem加密,就直接enter就好了,直到終端提示你需要輸入至少4字元的密碼以及確認密碼,最後我們回到這個新建的資料夾就能看到我們需要的.pem檔案了,如下圖


iOS 推送及bundle ID provision生成教程
圖11 pem檔案已經生成

這就是我們最終需要的.pem檔案,把這檔案給伺服器就好了,剩下的是伺服器端的事情。

等伺服器安裝好證書及除錯後,我們需要測試下推送到底能不能用,所以,我們提供pem檔案的同時得提供bundleID和devicetoken。等等,devicetoken?這是什麼東東?好的,接下來我們再講講這個坑。

通過神奇的百度,我找到了如下資料:

先簡單介紹下push的機制

客戶端通過

(void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types

這個函式向APNs(Apple Push Service)註冊push,types可標明接收的push的型別,聲音,數字等。

(void)application:(UIApplication

*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData

*)deviceToken;

當app成功註冊通知後,會呼叫這個函式,並把deviceToken返回給應用。

然後我們的程式就會把返回的這個deviceToken以及裝置的udid及軟體版本(淘寶for iPhone還是淘寶for iPad)及系統版本,使用者名稱等傳送到我們的伺服器(下圖中的provider)上,然後儲存在資料庫裡。整個獲取device token的過程可參見下圖所示:

iOS 推送及bundle ID provision生成教程

在需要傳送push時,我們的服務端就會取出要傳送的裝置的device token,然後以下圖所示的結構,組成符合特定結構的字串,然後將其傳送到的APNs

iOS 推送及bundle ID provision生成教程

APNs可以根據與APNs建立連線的Provider所使用的證書判斷是要哪個app請求傳送的notification,繼而把這個notification傳送到的裝置上。

下圖為一個簡單的從Provider到Device傳送push的過程:

iOS 推送及bundle ID provision生成教程

device

token到底是什麼呢?不同的app的device

token相同麼?一個裝置會產生多個device token麼?一個的device token可能對應多個UDID麼?

結論:device token是對APNs來說,裝置的識別符號,與app無關,所以同一臺裝置上,不同的app獲得的device token是一樣的;一個裝置可能會產生多個device token,一個device

token也可能對應多個UDID,下面進行解釋。

device

token是什麼?

文件中如下描述的:

iOS 推送及bundle ID provision生成教程

對於APS來說,token是裝置的識別符號。device token不同於UIDevice的uniqueIdentifier(即UDID),因為出於安全和隱私原因,當裝置被擦除後,token必須變化。

所以也就是說,一般情況下,token是不變的,但是在裝置被擦除後,token會變的。

今天無心說在我們的伺服器上的資料庫裡,存在同一個UDID對應有多個token的情況,之前是沒有考慮到裝置擦除的情況,所以就懷疑是不是同一個裝置上同時裝了taobao4iphone和taobao4ipad,而token是與app關聯的,所以產生的這種情況,於是就找了楊匡的ipad來做測試,結果發現taobao4iphone和taobao4ipad收到的token是相同的,所以token應該是與app無關的,而是針對裝置的(文件上也是如此描述的),是裝置的標識,那除了裝置被擦除的情況外,裝置的device token應該是相同的,可是楊匡說之前崇厚給他查出來的他的iPad的token和我log出來的device token是不同的,後來就想到了,push是有兩套的,development和product,即除錯和release,在這兩種情況下,服務端使用的push證書是不一樣的,而程式使用的證書也不一樣,那同一個裝置在development和distribution情況下收到的device token是否一樣呢,於是就做了實驗,實際結果如下

實驗裝置:iPad 1

iOS 推送及bundle ID provision生成教程

可以看出,同一個裝置在development和distribution情況下,收到的device token是不同的,而token是與app無關的。

綜合文件及上述實驗結果可以得到以下結果:

同一個udid對應有不同的device token的情況暫時有如下兩種:

裝置擦除過,token變化過,老的新的都儲存在資料庫裡

裝置同時裝過development和distribution的程式

不知道還有沒有其它原因造成的同一個裝置有不同的device token的情況,大家如果有什麼相關的經驗,可以補充一下。

Ok,balabala一堆講完了,我們總結了下,devicetoken類似於令牌,但是又不同於UUID唯一識別符號,devicetoken會變化,但是我們只要知道它也是Apple裝置的識別符號就好了,配合bundleID這樣才能給裝置準確地推送,OK科普完畢,開始獲取devicetoken

//獲取DeviceToken成功

- (void)application:(UIApplication*)application

didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken

{

NSLog(@"DeviceToken: {%@}",deviceToken);

//這裡進行的操作,是將Device Token傳送到服務端

UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:nilmessage:[NSStringstringWithFormat:@"DeviceToken:%@",deviceToken]delegate:selfcancelButtonTitle:nilotherButtonTitles:@"確定",nil];

[alertshow];

}

從上面這個方法裡,我們就能得到devicetoken,列印出來就OK了,但我們還有一個問題,APPStore版本和development用的是同樣的bundleID所以devicetoken是一致的,但是如果是inhouse版本怎麼辦?其實也很簡單,那就是,我們把上面那個方法裡得到的devicetoken傳遞到某個頁面,然後用label或者alertview,或者其他可視的控制元件展示出來就好了,然後抄下來就OK啦!

OK,推送搞定!

接著我們選擇對應的證書provision 和 bundleID就可以愉快地開發啦!

相關文章