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];
}