APNS总结
之前做技术储备的时候就预感到APNS会是个大坑,果不其然。
APNS是Apple Push Notification Service的简称,简单来说就是你想给iOS设备发通知,就需要苹果的服务器来作个中介。你的server需要将要push给用户的消息发送给apple的notification server。apple server通过这个消息中带着的token这个属性判断要发送到哪个设备。而这个设备接收到这个消息后,需要知道它是哪个app的消息。所以消息中又带有一个证书文件和一个key文件。
所以在做APNS推送之前,你需要准备好三样东西:一个证书文件(.cer),一个key文件(.p12)和设备token。
证书文件和key文件需要通过apple的开发者中心获得: https://developer.apple.com/account/ios/certificate/certificateList.action 访问这个网站之前需要先在钥匙串程序中获得一个CertificateSigningRequest.certSigningRequest文件,这个在真机测试的教程里说明过。之后需要一个与你的app的bundle identifier相同的app id(关于怎么在Xcode里面修改bundle identifier,可以参考这个:http://www.cnblogs.com/ubersexual/p/3420819.html )。
然后设置并下载此app id对应的推送证书。在开发者中心选certificates-development,然后选择App push notification service SSL(production)。生成文件然后下载。这个文件的后缀就是.cer,现在你已经拿到了第一样东西。
将你下载的这个.cer的文件双击就能在钥匙串中打开它,它里面包含一个文件。将这个文件导出为.p12后缀的文件。这就是你要的第二样东西。
已经拿到这两个东西以后,还没有结束在apple开发者中心的旅程。获得推送证书以后,你需要再次生成一次真机证书(之前那个不会作废,但获取token会有问题,相信我,再生成一次就对了)。真机证书的后缀是.mobileprovision,双击它会自动安装到你的xcode里面。
现在你已经为获得第三样东西:设备token做好了准备。
设备token需要一台真实的iOS设备,这就是你需要真机证书的原因,没有它你无法将你的app编译进真实设备里。而获取token需要你在你的设备里运行你的app。
在项目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代码:
//
[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];
//
通过registerForRemoteNotificationTypes方法,告诉应用程序,能接受push来的通知。在项目的AppDelegate中添加下面的方法来获取deviceToken:
//
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
NSLog(@"My token is:%@", token);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSString *error_str = [NSString stringWithFormat: @"%@", error];
NSLog(@"Failed to get token, error:%@", error_str);
}
//
如果一切顺利,你可以看到token被打印在控制台里。实际场景下,需要将token传到后台,但现在只是调试,所以你可以复制打印到log里的token。
现在,三样东西终于都凑齐了。最后一步是来实现你的push server,向apple的notification server发送消息。如果你使用php之类的,我可能帮不了你,因为我是用nodejs来实现push server的。你需要安装一个叫做apn的nodejs模块。在package.json里添加这个依赖,然后npm install一下,pan模块就装好了。
然后需要实现以下代码:
//
var apns = require('apn');
var options = {
cert: 'cert.pem', /* Certificate file path */
key: 'key.pem', /* Key file path */
gateway: 'gateway.sandbox.push.apple.com',/* gateway address */
port: 2195, /* gateway port */
errorCallback: errorHappened , /* Callback when error occurs function(err,notification) */
};
function errorHappened(err, notification){
console.log("err " + err);
}
var apnsConnection = new apns.Connection(options);
var token = "3a4925d81ec6ab9pppppppppp26f9b7dddddddddddddc3be6d766840373";
var myDevice = new apns.Device(token);
var note = new apns.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 1;
note.sound = "ping.aiff";
note.alert = "Hello World";
note.payload = {'messageFrom': 'Caroline'};
note.device = myDevice;
apnsConnection.sendNotification(note);
//
看起来挺简单的吧,这里还忘了一个事情,就是cert.perm和key.perm这两个文件。它们是哪儿来的呢。还记得.cer和.p12这两个文件吗,对,就是来自它们。在终端里输入这两行命令,用来处理这两个文件。
$ openssl x509 -in cert.cer -inform DER -outform PEM -out cert.pem
$ openssl pkcs12 -in key.p12 -out key.pem -nodes
处理完成后,将cert.perm和key.perm放到以上代码文件的同目录下就可以了。然后,试着运行一下以上代码,运气好的话,应该就可以收到通知了。
参考资料:
http://blog.csdn.net/showhilllee/article/details/8631734 http://www.cnblogs.com/wengzilin/archive/2012/05/02/2479241.html(关于获取证书和整体流程)
http://blog.csdn.net/yick8799/article/details/6447365(关于token)
http://iosdevelopersnote.blogspot.com/2012/08/nodejs-apple-push-notification-service.html(关于nodejs实现的push server)
APNS是Apple Push Notification Service的简称,简单来说就是你想给iOS设备发通知,就需要苹果的服务器来作个中介。你的server需要将要push给用户的消息发送给apple的notification server。apple server通过这个消息中带着的token这个属性判断要发送到哪个设备。而这个设备接收到这个消息后,需要知道它是哪个app的消息。所以消息中又带有一个证书文件和一个key文件。
所以在做APNS推送之前,你需要准备好三样东西:一个证书文件(.cer),一个key文件(.p12)和设备token。
证书文件和key文件需要通过apple的开发者中心获得: https://developer.apple.com/account/ios/certificate/certificateList.action 访问这个网站之前需要先在钥匙串程序中获得一个CertificateSigningRequest.certSigningRequest文件,这个在真机测试的教程里说明过。之后需要一个与你的app的bundle identifier相同的app id(关于怎么在Xcode里面修改bundle identifier,可以参考这个:http://www.cnblogs.com/ubersexual/p/3420819.html )。
然后设置并下载此app id对应的推送证书。在开发者中心选certificates-development,然后选择App push notification service SSL(production)。生成文件然后下载。这个文件的后缀就是.cer,现在你已经拿到了第一样东西。
将你下载的这个.cer的文件双击就能在钥匙串中打开它,它里面包含一个文件。将这个文件导出为.p12后缀的文件。这就是你要的第二样东西。
已经拿到这两个东西以后,还没有结束在apple开发者中心的旅程。获得推送证书以后,你需要再次生成一次真机证书(之前那个不会作废,但获取token会有问题,相信我,再生成一次就对了)。真机证书的后缀是.mobileprovision,双击它会自动安装到你的xcode里面。
现在你已经为获得第三样东西:设备token做好了准备。
设备token需要一台真实的iOS设备,这就是你需要真机证书的原因,没有它你无法将你的app编译进真实设备里。而获取token需要你在你的设备里运行你的app。
在项目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代码:
//
[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];
//
通过registerForRemoteNotificationTypes方法,告诉应用程序,能接受push来的通知。在项目的AppDelegate中添加下面的方法来获取deviceToken:
//
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
NSLog(@"My token is:%@", token);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSString *error_str = [NSString stringWithFormat: @"%@", error];
NSLog(@"Failed to get token, error:%@", error_str);
}
//
如果一切顺利,你可以看到token被打印在控制台里。实际场景下,需要将token传到后台,但现在只是调试,所以你可以复制打印到log里的token。
现在,三样东西终于都凑齐了。最后一步是来实现你的push server,向apple的notification server发送消息。如果你使用php之类的,我可能帮不了你,因为我是用nodejs来实现push server的。你需要安装一个叫做apn的nodejs模块。在package.json里添加这个依赖,然后npm install一下,pan模块就装好了。
然后需要实现以下代码:
//
var apns = require('apn');
var options = {
cert: 'cert.pem', /* Certificate file path */
key: 'key.pem', /* Key file path */
gateway: 'gateway.sandbox.push.apple.com',/* gateway address */
port: 2195, /* gateway port */
errorCallback: errorHappened , /* Callback when error occurs function(err,notification) */
};
function errorHappened(err, notification){
console.log("err " + err);
}
var apnsConnection = new apns.Connection(options);
var token = "3a4925d81ec6ab9pppppppppp26f9b7dddddddddddddc3be6d766840373";
var myDevice = new apns.Device(token);
var note = new apns.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 1;
note.sound = "ping.aiff";
note.alert = "Hello World";
note.payload = {'messageFrom': 'Caroline'};
note.device = myDevice;
apnsConnection.sendNotification(note);
//
看起来挺简单的吧,这里还忘了一个事情,就是cert.perm和key.perm这两个文件。它们是哪儿来的呢。还记得.cer和.p12这两个文件吗,对,就是来自它们。在终端里输入这两行命令,用来处理这两个文件。
$ openssl x509 -in cert.cer -inform DER -outform PEM -out cert.pem
$ openssl pkcs12 -in key.p12 -out key.pem -nodes
处理完成后,将cert.perm和key.perm放到以上代码文件的同目录下就可以了。然后,试着运行一下以上代码,运气好的话,应该就可以收到通知了。
参考资料:
http://blog.csdn.net/showhilllee/article/details/8631734 http://www.cnblogs.com/wengzilin/archive/2012/05/02/2479241.html(关于获取证书和整体流程)
http://blog.csdn.net/yick8799/article/details/6447365(关于token)
http://iosdevelopersnote.blogspot.com/2012/08/nodejs-apple-push-notification-service.html(关于nodejs实现的push server)
还没人转发这篇日记