iPhone消息推送机制实现总结
iPhone 对于应用程序在后台运行有诸多限制(除非你越狱)。因此,当用户切换到其他程序后,原先的程序无法保持运行状态。对于那些需要保持持续连接状态的应用程序(比如社区网络应用),将不能收到实时的信息。
为解决这一限制,苹果推出了APNs(苹果推送通知服务)。APNs 允许设备与苹果的推送通知服务器保持常连接状态。当你想发送一个推送通知给某个用户的iPhone上的应用程序时,你可以使用 APNs 发送一个推送消息给目标设备上已安装的某个应用程序。
Push的原理:
Push 的工作机制可以简单的概括为下图
图中,Provider是指某个iPhone软件的Push服务器,此处是创建的应用程序作为Provider。
APNS 是ApplePush Notification Service(ApplePush服务器)的缩写,是苹果的服务器。
上图可以分为三个阶段。
第一阶段:Provider应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。
第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。
从上图我们可以看到。
1、首先是应用程序注册消息推送。
2、IOS跟APNSServer要deviceToken。应用程序接受deviceToken。
3、应用程序将deviceToken发送给PUSH服务端程序。
4、 服务端程序向APNS服务发送消息。
5、APNS服务将消息发送给iPhone应用程序。
创建使用 APNs 的iOS 应用的详细步骤
1.打开“钥匙串访问”应用程序。
2.选择“KeychainAccess-> Certificate Assistant -> Request a Certificate FromCertificateAuthority”(如图1所示):
3.输入所需的信息,勾选“Savedto disk”选项,点击Continue(如图2所示):
4.使用默认文件名把证书请求进行保存(图3):在弹出窗口中,点击Done。
创建 App ID
每个使用 APNs 的 iOS 应用必须有一个唯一的 App ID。创建推送通知中要用到的App ID。
1.登录iPhoneDeveloperProgram:http://developer.apple.com/iphone/。点击页面右边的“ iPhoneDeveloper Program Portal ”(图4):
2.首先看到的是欢迎页面(图5):
3.点击左边的“App ID”,然后点击右边的“New AppID”按钮(图6):
4.在Description 栏输入“PushAppID”,在“BundleSeed ID”栏中选择“GenerateNew”。在“BundleIdentifier”栏,输入“net.learn2develop.MyPushApp”,然后点击“Submit”(图7):
5.现在你应该能看到所创建的App ID 了(图8):
配置 App
一旦创建了 App ID,你还要为推送通知对 App ID 进行一些配置。
1.点击App ID 右边的Configure 链接,会看到如下选项(图9):
勾选“Enablefor Apple Push Notificationservice”,点击“Development Push SSLCertificate”右边的“Configure”按钮。
2.接下来你会看到“ApplePush Notification service SSL Certificate Assistant”页面。点击Continue(图10):
3.点击ChooseFile 按钮,选择前面保存的证书请求文件存放地址。点击Generate(图11):
4.你的SSL 证书会被生成。点击Continue(图12):
5.点击DownloadNow 按钮,下载 SSL 证书。点击 Done(图13):
6. 下载的 SSL 证书文件名为 aps.developer.identity.cer。双击,将证书安装到钥匙串中(图14)。这个证书会在你的程序中用到,它允许程序接收 APNs 发送来的推送通知。
创建 Provisioning Profile
接下来,需要创建 provisioning profile 以便允许应用程序安装到真实设备上。
1. 回到iPhone Development Program Portal,点击 Provisioning 栏,点击 New Profile 按钮(图15)
2. Profile Name 栏输入 MyDevicesProfile,在 App ID 栏选择 PushAppID。在Devices 栏,勾选所有你想激活的设备(在 iPhone Developer Program Portal 的 Devices 页中注册的所有设备)。点击 Submit(图16)。
3. provisioning profile 会等待审核。几秒钟后,它会显示在页面上。点击Download 按钮下载该 provisioning profile(图17):
4. 下载下来的provisioning profile 名为 MydevicesProfile.mobileprovision。
激活设备
创建 provision profile 后,你可以将它安装到真实设备中。
1. 将iPhone 或 iPod 连接到 Mac。
2. 把下载下来的 MyDevicesProfile.mobileprovision 文件拖到Dock 栏的 Xcode 图标上。
3. Xcode 的 Organizer 程序将启动,选择当前连机的设备。可以看到MyDevicesProfile 已自动安装到设备上了
创建 iPhone 应用程序
打开Xcode,创建 View-Based Application 项目
展开Xcode中的 Targets项目,选择ApplePushNotification,按下 ⌘+i,在 info 出口,点击Properties 标签栏。
在 Identifier 文本框,输入net.learn2develop.MyPushApp.
点击 Build 标签栏,在 search 输入框中键入Code Signing。在 Any iPhone OS Device 选项,选择正确的 profile。
在 ApplePushNotificationAppDelegate.m 文件中,输入以下代码(加粗部分):
#import"ApplePushNotificationAppDelegate.h"
#import"ApplePushNotificationViewController.h"
@implementationApplePushNotificationAppDelegate
@synthesize window;
@synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication*)application{
[windowaddSubview:viewController.view];
[windowmakeKeyAndVisible];
NSLog(@"Registeringfor push notifications...");
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge|
UIRemoteNotificationTypeSound)];
}
-(void)application:(UIApplication*)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *str = [NSString
stringWithFormat:@"DeviceToken=%@",deviceToken];
NSLog(str);
}
-(void)application:(UIApplication*)appdidFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSStringstringWithFormat:@"Error: %@", err];
NSLog(str);
}
-(void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
for (id key in userInfo) {
NSLog(@"key:%@, value: %@", key, [userInfo objectForKey:key]);
}
}
- (void)dealloc {
[viewControllerrelease];
[window release];
[super dealloc];
}
@end
按下 ⌘+R 运行程序(在真实设备)。按下 shift+⌘+R显示DebuggerConsole 窗口。查看设备输出到控制台的device token,devicetoken 比如是38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7c e90d56e9fe145bcc 6c2c594b。记下device token(复制、粘贴到一个文本文件里)
如果查看 iPhone/iPod 上的“Settings”程序,你会发现一个 Notifications 的项
创建 PushNotification Provider
Push Notification Provider 是一个应用程序,用于通过 APNs 发送推送通知给 iPhone 应用。
通过 APNs 发送推送通知有几个步骤:
1. 使用前面创建的 SSL 证书与 APNs 通讯;
2. 构造所要发送的消息载体;
3. 发送载体到APNs;
APNs 是一个基于流的 TCP socket,你的 provider 以 SSL 协议与其通讯。推送通知(包括载体)是以二进制流的方式发送的。和APNs 建立连接后,你可以维持该连接并在连接中断之前发送多个通知。
技巧: 应避免每发送一次推送通知就建立、关闭一次连接。频繁的建立、关闭连接可能会被 APNs 认为是 DOS 攻击,从而拒绝发送 provider 的推送通知发送请求。
一个推送通知消息的格式
载体(payload)是 JSON 字符串(最长 256 字节),封装了你发送给 iOS 应用的信息。这是一个 payload 的例子:
{
"aps": {
"alert" : "Yougot a new message!" ,
"badge" : 5,
"sound" : "beep.wav"},
"acme1": "bar",
"acme2": 42
}
1. 在Xcode 中打开 PushMeBaby。
2. 右击 Resouces 文件夹,选择 Add Existing Files…,选择前面所下载到的aps.developer.identity.cer 文件
3. 在 ApplicationDelegate.m 文件中,修改如下代码(加粗部分):
- (id)init {
self = [super init];
if(self != nil) {
self.deviceToken= @"38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7ce90d56e9 fe145bcc6c2c594b";
// self.payload = @"{\"aps\":{\"alert\":\"Yougot a new //message!\",\"badge\":5,\"sound\":\"beep.wav\"},\"acme1\":\"bar\",\"acme2\":42}";
self.payload = @"{\"aps\":{\"alert\":\"Yougot a new message!\",\"badge\":5},\"acme1\":\"bar\",\"acme2\":42}";
self.certificate= [[NSBundle mainBundle]
pathForResource:@"aps_developer_identity"ofType:@"cer"];
}
return self;
}
4.按下 ⌘+R,运行程序。将会问你是否允许使用证书,点击AlwaysAllow(总是允许)
在 iPhone/iPod,确认 ApplePushNotification 程序未运行。点击 Push 按钮,会向设备发送一条推送通知。服务器实际上发送了下列消息给APN 服务器:
{
"aps": {
"alert" : "Yougot a new message!" ,
"badge" : 5,
"sound" : "beep.wav"},
"acme1": "bar",
"acme2": 42
}
5.如果消息推送成功,将会在iPhone/iPod 上出现