Question:pushkit是什麼?
Answer:ios8蘋果新引入了名為pushkit的框架和一種新的push通知類型,被稱作voip push.該push方式旨在提供區別於普通apns push的能力,通過這種push方式可以使app執行制定的代碼(在彈出通知給用戶之前);而該通知的默認行為和apns通知有所區別,它的默認行為裡面是不會彈出通知的。目前來看push kit的用途還局限於voip push(根據筆者的實戰經驗來看,其他類型的push暫時不能夠起作用,sdk也正處於演進中)。
Question: pushkit能幫我們做什麼?
Answer:pushkit中的voippush,可以幫助我們提升voip應用的體驗,優化voip應用的開發實現,降低voip應用的電量消耗,它需要我們重新規劃和設計我們的voip應用,從而得到更好的體驗(voip push可以說是准實時的,實側延時1秒左右);蘋果的目的是提供這樣一種能力,可以讓我們拋棄後台長連接的方案,也就是說應用程序通常不用維持和voip服務器的連接,在呼叫或者收到呼叫時,完成voip服務器的注冊;當程序被殺死或者手機重啟動時,都可以收到對方的來電,正常開展voip的業務。也就是說,我們當前可以利用它來優化voip的體驗,增加接通率;條件成熟時我們就可以完全放棄後台的長連接,走到蘋果為我們規劃的道路上。
對於pushkit,除了蘋果framework官方文檔: 以外,能夠找到的幫助理解pushkit的莫過於wwdc的視頻:712_sd_writing_energy_efficient_code_part_2。該視頻也可以從蘋果官網下載。
pushkit的局限:
在當前,pushkit僅支持ios8;且該功能正處於演進中,穩定性和在不同ios8小版本設備上的表現也可能有差異,在蘋果開發者論壇上也有不少人反饋問題;根據經驗,在下個大版本(也就是ios9)上可以期待該功能可以穩定下來。
如果需要在ios8之前的設備上支持pushkit功能,那麼需要開發者付出很多額外的努力,這裡不展開,有興趣的同學可以到蘋果論壇的相關板塊去了解,有一些開發者在這方面走的比較遠:
在簡單介紹了pushkit和它能做的事並且了解到它的局限以後,還對pushkit感興趣的童鞋可以往下繼續看了(:)為了避免浪費大家的寶貴時間)。
pushkit的voip功能的實現:
1.跟apns push類似,pushkit的voippush也需要申請證書 ;voip push的證書申請步驟截圖如下:
2.使用該證書導出並加載到push服務器上,服務器側無需做改動,僅替換證書相關的東西即可(具體流程和此前apns證書的加載完全類同);服務器和客戶端的交互流程也基本類似。
3.客戶端實現:
step1:在工程中添加pushkit;
step2:在工程設置裡面的backgroundmode裡面添加voip、backgroundfetch、remotenotifications的支持。
step3:保險起見,建議開發者使用最新版本的xcode和最新的sdk;也建議重新申請一個mobile provision文件用於打包。
step4:類似apns通知的客戶端實現流程,voip push客戶端相關的流程也類似:注冊voip push通知,實現pushkit相關的代理。
貼出主要代碼:
在應用啟動(appdelegate的didfinishlaunchwithoptions)後或根控制器的初始化等方法內調用如下代碼:
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
UIUserNotificationSettings *userNotifySetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:userNotifySetting];
上面的代碼實現了在應用啟動時對voip push的注冊;
在appdelegate或框架viewcontroller類中實現voip push的代理:
@interface EPTabBarController : UITabBarController
}
我們這裡對接的push服務器是zeropush提供的服務;後面我們會大概介紹下該服務;上面的代理方法是設備從蘋果服務器獲取到了voip token,然後傳遞給應用程序;我們需要把這個token傳遞到push服務器(和apns push類似,我們也是要傳遞apns token到push服務器,但是這兩個token的獲取方式不同,分別在不同的代理方法中回調給應用,且這兩個token的內容也是不同的)。
push server在獲取到用戶的voip token之後,在一切正常的情況下,另外一個回調會在push server下發消息到對應token的設備時被觸發。
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
NSLog(@didReceiveIncomingPushWithPayload);
// 此時進行voip注冊
// write your voip related codes here
UIUserNotificationType theType = [UIApplication sharedApplication].currentUserNotificationSettings.types;
if (theType == UIUserNotificationTypeNone)
{
UIUserNotificationSettings *userNotifySetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:userNotifySetting];
}
UILocalNotification *backgroudMsg = [[UILocalNotification alloc] init];
backgroudMsg.alertBody= NSInternationalString(@You receive a new call,nil);
[[UIApplication sharedApplication] presentLocalNotificationNow:backgroudMsg];
}
上面的回調代碼裡僅僅打印了日志,觸發了一個本地通知;這個代理方法是收到voip push通知時觸發的;如果一切正常,該通知在手機重啟、應用被系統回收、手動kill程序的情況下,依然能夠被觸發,且可以有一段時間用來執行自己的代碼(比如voip注冊等)。
我們這裡簡單設計一個業務供大家參考,主要是為了讓大家直觀的認識到pushkit的能力:
1.應用的voip長連接不保持,在收到呼叫或者發起呼叫時再連接;
2.當呼叫發送到voip 服務器時,對端若不在線,通過voip 服務器連接到pushserver向對端發push通知;
3.應用收到voip push通知時,迅速完成注冊;
4.呼叫方通過延時操作等邏輯(復雜一點對voip服務器進行改造,被叫連接上來以後通知到主叫側),再次發起呼叫,通話即成功建立。
筆者曾就一個證書相關的問題嘗試給該郵箱發信,很快得到了滿意的答復,非常棒!
zero push 提供了一個免費試用的服務,這讓我們體驗voip push非常方便;
按照它的提示,注冊賬號,然後創建應用,上傳voip 證書,從網頁上獲取到它的apikey(這個key在上傳token之前要用到,在上面的代理方法中)。
需要注意的是,該工程使用swift語言編寫,如果你的證書和provision文件等都是之前申請的,只用於oc創建的工程,那麼該工程在真機運行時很可能會閃退;解決辦法是重新生成你的證書和provision文件,並使用到工程中,然後重新打包,該問題即可得到解決了。
最後,歡迎大家任何形式的關於本課題的探討~我留意到國內關於本課題的中文資料或者實踐總結非常少,絕大部分都是英文的,希望和大家一起多多積累,共同進步~