OS的通知(notifications)有兩種形式:
- pushnotifications,從iOS3開始就有了,由遠程服務器發起通知localnotifications,從iOS4開始支持,由本地應用發起的通知
兩種通知都是為了提醒用戶后台執行的應用有了變化。從用戶角度來看,效果是一樣的,都是通知。只是實現的方式不一樣,對於技術實現來說。
本文主要說明pushnotification的devicetoken的步驟。
可以通過《偷窺iPhonePushNotification的幕后》和《iPhone的Push(推送通知)功能原理淺析》對pushnotification有個原理上的了解。
設備的准備
首先要知道,pushnotification只能在真機上運行的,無法在模擬器上使用,如果在模擬器上運行,在注冊設備的時候會有類似如下報錯:
Errorinregistration.Error:ErrorDomain=NSCocoaErrorDomainCode=3010"remotenotificationsarenotsupportedinthesimulator"UserInfo=0x5d249d0{NSLocalizedDescription=remotenotificationsarenotsupportedinthesimulator}
真機也要注意,如果沒有越獄,沒有問題。越獄的話,比如通過blacksnOw,因為沒有經過iTunes,無法生成有效的設備證書(devicecertificate),因此注冊的時候不會成功。
檢查越獄版本是否可用,可以ssh到設備上,執行命令:
ls/var/mobile/Library/Preferences/com.apple.apsd.plist-l
-rw-1mobilemobile119Aug2419:21/var/mobile/Library/Preferences/com.apple.apsd.plist
返回的文件大小是119,就沒有問題。
獲取devicetoken的原理
在說操作步驟之前,先說一下獲取devicetoken的一些原理方面的事情。
devicetoken,即設備令牌,不是系統唯一標識,需要在應用啟動時發起到apple服務器請求,注冊自己的設備和應用,並獲得這個devicetoken。
devicetoken有什么用?如果應用需要pushnotification給手機,那么它要有個服務器端(provider),但是它發出的信息不是直接給手機的,而是必須統一交給apple的服務器,這個服務器就是applepushnotificationserver(apns)。apple服務器通過這個token,知道應用要發的消息是給哪個手機設備的,並轉發該消息給手機,手機再通知應用程序。
獲取devicetoken的操作步驟
這里主要參照了這篇文章:ProgrammingApplePushNotificationServices
該文檔很詳細,照做就應該沒有問題。
需要注意的是identifier一定要和provisionportalprofile中的appid一致,即:
要和:
一致。
另外,要確保設備綁定的是唯一的profile:
編寫代碼,是在AppDelegate中增加兩個方法:
- didRegisterForRemoteNotificationsWithDeviceToken:當應用第一次運行的時候,ios獲取到devicetoken后調用,用於注冊設備到apns上之后的操作(比如將devicetoken通知應用的服務器端provider)didFailToRegisterForRemoteNotificationsWithError:如果注冊的時候失敗,ios會調用這個方法,可以打印一些報錯日志或者提醒用戶通知不可用
另外,有一個方法需要增加內容,主要是打印日志,說明是否已經注冊:
-(void)applicationDidFinishLaunching:(UIApplication*)application{
[[UIApplicationsharedApplication]setApplicationIconBadgeNumber:0];
NSLog(@"InitiatingremoteNoticationssAreActive");
if(!application.enabledRemoteNotificationTypes){
NSLog(@"InitiatingremoteNoticationssAreActive1");
[[UIApplicationsharedApplication]registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)];
}
UIApplication*myapp=[UIApplicationsharedApplication];
myapp.idleTimerDisabled=YES;
[windowaddSubview:viewController.view];
[windowmakeKeyAndVisible];
}