Programming Apple Push Notification Services

Push 的工作机制可以简单的概括为下图

图中,Provider是指某个iPhone软件的Push服务器。 
APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。

上图可以分为三个阶段。

第一阶段:.net应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。 
第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。 
第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。

 

    从上图我们可以看到。

   1、首先是应用程序注册消息推送。

   2、 IOS跟APNS Server要deviceToken。应用程序接受deviceToken。

   3、应用程序将deviceToken发送给PUSH服务端程序。

   4、 服务端程序向APNS服务发送消息。

   5、APNS服务将消息发送给iPhone应用程序。


提供了简单的实现源码和推送服务器实现源码,地址如下:

消息推送工程源码地址

消息推送服务器工程源码地址


One of the key limitations of the iPhone is its constraint on running applications in the background. Because of this, applications cannot keep running in the background when the user switches to another application. So, applications that require a constant state of connectivity (such as social networking applications) will not be able to receive timely updates.

To remedy this limitation, Apple released the Apple Push Notification Service (APNs). The APNs is a service that allows your device to be constantly connected to Apple's push notification server. When you want to send a push notification to an application installed on the users' devices, you (the provider) can contact the APNs so that it can deliver a push message to the particular application installed on the intended device.

In this article, you will learn how to perform the various steps needed to create an iPhone application that uses the APNs.

Generating a Certificate Request

The first step to using the APNs is to generate a certificate request file so that you can use it to request for a development SSL certificate later on.

1. Launch the Keychain Access application in your Mac OS X.

2. Select Keychain Access'Certificate Assistant'Request a Certificate From a Certificate Authority (see Figure 1):


Figure 1. Generating a certificate request

3. Enter the information required and check the Saved to disk option. Click Continue (see Figure 2).


Figure 2. Saving the certificate request to disk

4. Save the certificate request using the suggested name and click Save (see Figure 3): Click Done in the next screen.


Figure 3. Naming the certificate request

Creating an App ID

Each iPhone applications that uses the APNs must have a unique application ID that uniquely identifies itself. In this step, you will learn how to create an App ID for push notification.

1. Sign in to the iPhone Developer Program at: http://developer.apple.com/iphone/. Click on the iPhone Developer Program Portal on the right of the page (see Figure 4).


Figure 4. Launching the iPhone Developer Program Portal

2. You should see the welcome page (see Figure 5).


Figure 5. The welcome screen of the iPhone Developer Program Portal

3. Click on the App IDs tab on the left and then click on the New App ID button (see Figure 6).


Figure 6. Clicking on the App ID tab

4. Enter "PushAppID" for the Description and select Generate New for the Bundle Seed ID. For the Bundle Identifier, enter net.learn2develop.MyPushApp. Click Submit (see Figure 7).


Figure 7. Creating a new App ID

5. You should now see the App ID that you have created (together with those you have previously created) (see Figure 8).


Figure 8. Viewing the newly created App ID

Configuring an App ID for Push Notifications

Once an App ID is created, you need to configure it for push notifications.

1. To configure an App ID for push notification, you need to click the Configure link displayed to the right of the App ID. You will now see the option (see Figure 9).


Figure 9. Configuring an App ID for push notification service

Check the Enable for Apple Push Notification service option and click the Configure button displayed to the right of the Development Push SSL Certificate.

2. You will now see the Apple Push Notification service SSL Certificate Assistant screen. Click Continue (see Figure 10).


Figure 10. The Apple Push Notification service SSL Certificate Assistant screen

3. Click the Choose File button to locate the Certificate Request file that you have saved earlier. Click Generate (see Figure 11).


Figure 11. Generating the SSL certificate

4. Your SSL Certificate will now be generated. Click Continue (see Figure 12).


Figure 12. The APNs SSL certificate that is generated

5. Click the Download Now button to download the SSL Certificate. Click Done (see Figure 13).


Figure 13. Downloading the certificate generated

6. The SSL Certificate that you download is named aps.developer.identity.cer. Double-click on it to install it in the Keychain Access application (see Figure 14). The SSL certificate will be used by your provider application so that it can contact the APNs to send push notifications to your applications.


Figure 14. Installing the generated certificate into the Keychain Access application

Creating a Provisioning Profile

The next step is to create a provisioning profile so that your application can be installed onto a real device.

1. Back in the iPhone Development Program Portal, click on the Provisioning tab and click on the New Profile button (see Figure 15).


Figure 15. Selecting the Provisioning tab

2. Type in MyDevicesProfile as the profile name. Select PushAppID as the App ID. Finally, check all the devices that you want to provision (you can register these devices with the iPhone Developer Program Portal through the Devices tab). Click Submit (see Figure 16).


Figure 16. Creating a new provisioning profile

3. The provisioning profile will now be pending approval. After a while, you will see it appear. Click on the Download button to download the provisioning profile (see Figure 17).


Figure 17. Pending the approval of the provisioning profile

4. The downloaded provisioning profile is named MyDevicesProfile.mobileprovision.

Provisioning a Device

With the provision profile created, you will now install it onto a real device.

1. Connect your iPhone or iPod Touch to your Mac.

2. Drag and drop the downloaded MyDevicesProfile.mobileprovision file onto the Xcode icon on the Dock.

3. Launch the Organizer application from within Xcode and select the device currently connected to your Mac. You should see the MyDevicesProfile installed on the device (see Figure 18).


Figure 18. Viewing the installed provisioning profile

Creating the iPhone Application

1. In Xcode, create a new View-Based Application project and name it as ApplePushNotification.

2. Drag and drop a WAV file (shown as beep.wav in this example) onto the Resources folder in Xcode (see Figure 19).


Figure 19. Adding a WAV file to the project

3. Expand on the Targets item in Xcode and select the ApplePushNotification item. Press Command-I. In the Info window, click the Properties tab (see Figure 20).


Figure 20. Entering the App ID for the application

In the Identifier textbox, type <net.learn2develop.MyPushApp.

4. Click on the Build tab and type "Code Signing" in the search box. In the Any iPhone OS Device item, select the profile as shown in Figure 21:


Figure 21. Selecting the profile for code signing

5. In the ApplePushNotificationAppDelegate.m file, type the following code in bold:

#import "ApplePushNotificationAppDelegate.h"
#import "ApplePushNotificationViewController.h"
 
@implementation ApplePushNotificationAppDelegate
 
@synthesize window;
@synthesize viewController;
 
- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
 
    NSLog(@"Registering for push notifications...");    
    [[UIApplication sharedApplication] 
        registerForRemoteNotificationTypes:
        (UIRemoteNotificationTypeAlert | 
         UIRemoteNotificationTypeBadge | 
         UIRemoteNotificationTypeSound)];
 
}
 
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
 
    NSString *str = [NSString 
        stringWithFormat:@"Device Token=%@",deviceToken];
    NSLog(str);
 
}
 
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
 
    NSString *str = [NSString stringWithFormat: @"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 {
    [viewController release];
    [window release];
    [super dealloc];
}
 
@end

6. Press Command-R to test the application on a real device. Press Shift-Command-R in Xcode to display the Debugger Console window. Observe carefully the device token that is printed (see Figure 22). In the figure below, the token is:38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7c e90d56e9 fe145bcc 6c2c594b. Record down this device token (you might want to cut and paste it into a text file).


Figure 22. Viewing the device token for push notification

7. If you go to the Settings application on your iPhone/iPod Touch, you will notice that you now have the Notifications item (see Figure 23).


Figure 23. Viewing the Notifications item in the Settings application

Creating the Push Notification Provider

A Push Notification provider is an application written by the application's developer to send push notifications to the iPhone application through the APNs.

Here are the basic steps to send push notifications to your applications via the Apple Push Notification Service (APNs):
1. Communicate with the APNs using the SSL certificate you have created earlier.
2. Construct the payload for the message you want to send.
3. Send the push notification containing the payload to the APNs.

The APNs is a stream TCP socket that your provider can communicate using a SSL secured communication channel. You send the push notification (containing the payload) as a binary stream. Once connected to the APNs, you should maintain the connection and send as many push notifications as you want within the duration of the connection.

Tip: Refrain from opening and closing the connections to the APNs for each push notification that you want to send. Rapid opening and closing of connections to the APNs will be deemed as a Denial-of-Service (DOS) attack and may prevent your provider from sending push notifications to your applications.

The format of a push notification message looks like Figure 24 (figure from Apple's documentation):


Figure 24. Format of a push notification message

For more details, please refer to Apple Push Notification Service Programming Guide.
The payload is a JSON formatted string (maximum 256 bytes) carrying the information you want to send to your application. An example of a payload looks like this:

{
    "aps": { 
        "alert" : "You got a new message!" ,
        "badge" : 5, 
        "sound" : "beep.wav"},
     "acme1" : "bar", 
     "acme2" : 42
}

To save yourself the trouble in developing a push notification provider from scratch, you can use the PushMeBabyapplication (for Mac OS X) written by Stefan Hafeneger (Get it here), or here.

1. Open the PushMeBaby application in Xcode.

2. Right-click on the Resources folder in Xcode and select Add Existing Files…. Select theaps.developer.identity.cer file that you have downloaded earlier (see Figure 25).


Figure 25. Adding the SSL certificate to the application

3. In the ApplicationDelegate.m file, modify the code as shown in bold below:

- (id)init {
    self = [super init];
    if(self != nil) {
        self.deviceToken = @"38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7c e90d56e9 fe145bcc 6c2c594b";
 
        self.payload = @"{\"aps\":{\"alert\":\"You got a new message!\",\"badge\":5,\"sound\":\"beep.wav\"},\"acme1\":\"bar\",\"acme2\":42}";
 
        self.certificate = [[NSBundle mainBundle] 
            pathForResource:@"aps_developer_identity" ofType:@"cer"];
    }
    return self;
}

4. Press Command-R to test the application. You will be asked to grant access to the certificate. Click Always Allow (see Figure 26):


Figure 26. Granting access to the SSL certificate

On the iPhone/iPod Touch, ensure that the ApplePushNotification application is not running. To send a message to the device, click the Push button. The server essentially sends the following message to the Apple Push Notification server:

{
    "aps": { 
        "alert" : "You got a new message!" ,
        "badge" : 5, 
        "sound" : "beep.wav"},
     "acme1" : "bar", 
     "acme2" : 42
}

5. If the message is pushed correctly, you should see the notification as shown in Figure 27.


Figure 27. Receiving a Push Notification message

6. If you now debug the ApplePushNotification application by pressing Command-R and send a push message from the PushMeBaby application, the Debugger Console window will display the following outputs:

2009-11-24 21:11:49.182 ApplePushNotification[1461:207] key: acme1, value: bar
2009-11-24 21:11:49.187 ApplePushNotification[1461:207] key: aps, value: {
    alert = "You got a new message!";
    badge = 5;
    sound = "beep.wav";
}
2009-11-24 21:11:49.191 ApplePushNotification[1461:207] key: acme2, value: 42

Summary

In this article, you have seen the various steps required to build an iPhone application that utilizes Apple's Push Notification service. I am interested to know how you are using the APNs for your application. Use the comment feature below to share with us!


有些推送服务器是windows服务器的,无法使用cer或p12证书,所以补充下面的内容,但下面关于PHP推送的功能代码需要再去网上找,我转载这个主要是为了转换证书使用,所以没有提供PHP推送代码。

转自:http://blog.csdn.net/showhilllee/article/details/8631734

我们直接生成的证书windows系统(我们一般的服务器都是win系统的)是不识别的,所以我们需要生成一个后缀为pem的带证书带秘钥的文件。

 

六 处理证书

下面我们打开终端(位置:应用程序à实用工具à终端)。

cd到桌面,我们那三个文件所在的位置

 

1、把.cer的SSL证书转换为.pem文件,执行命令:

openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem

在桌面上会生成一个PushChatCert.pem文件


 

2、把私钥Push.p12文件转化为.pem文件:

openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12

 

这里需要我们输入密码,这个密码也就是我们导出p12文件时的密码,也就是我们上面设置的abcabc。然后,需要我们对生成的pem文件设置一个密语,这里我们推荐还是用上面这个abcabc,防止混乱(当然你也可以设置成别的更有意义的密语),这里的密语是要告诉我们服务器的。这样,桌面上又会生成一个PushChatKey.pem文件


3、对生成的这两个pem文件再生成一个pem文件,来把证书和私钥整合到一个文件里:

cat PushChatCert.pem PushChatKey.pem > ck.pem

生成ck.pem文件

 

这样,我们的文件就制作完了。下面进入测试阶段

为了测试证书是否工作,执行下面的命令

telnet gateway.sandbox.push.apple.com 2195

它将尝试发送一个规则的,不加密的连接到APNS服务。如果你看到上面的反馈,那说明你的MAC能够到达APNS。按下Ctrl+C关闭连接。如果得到一个错误信息,那么你需要确保你的防火墙允许2195端口。一般这里都不会出现什么问题。

 

下面我们要使用我们生成的SSL证书和私钥来设置一个安全的链接去链接苹果服务器:

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem

执行完这一句命令后需要我们输入密语

Enter pass phrase for PushChatKey.pem:

我们输入abcabc按回车

你会看到一个完整的输出,让你明白OpenSSL在后台做什么。如果链接是成功的,你可以随便输入一个字符,按下回车,服务器就会断开链接,如果建立连接时有问题,OpenSSL会给你返回一个错误信息。

 当你在最后的时候你看到这样说明你已经成功了:

CONNECTED(00000003)

depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa isincorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust CertificationAuthority - L1C

verify error:num=20:unable to get local issuercertificate

verify return:0

---

Certificate chain

 0s:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMSEngineering/CN=gateway.sandbox.push.apple.com

  i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated byreference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C

 1s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated byreference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C

   i:/O=Entrust.net/OU=www.entrust.net/CPS_2048incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.netCertification Authority (2048)

---

Server certificate

-----BEGIN CERTIFICATE-----

MIIFGzCCBAOgAwIBAgIETBz90jANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC

……省略……

fMGbLqkGn8YogdPqe5T1

-----END CERTIFICATE-----

subject=/C=US/ST=California/L=Cupertino/O=AppleInc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com

issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa isincorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust CertificationAuthority - L1C

---

No client certificate CA names sent

---

SSL handshake has read 2731 bytes and written 2165 bytes

---

New, TLSv1/SSLv3, Cipher is AES256-SHA

Server public key is 2048 bit

Secure Renegotiation IS supported

Compression: NONE

Expansion: NONE

SSL-Session:

    Protocol  : TLSv1

    Cipher    : AES256-SHA

    Session-ID:

    Session-ID-ctx:

    Master-Key:C7A47EED5E1F5……省略……369D4

    Key-Arg   : None

    Start Time:1361862882

    Timeout   : 300 (sec)

    Verify return code: 0 (ok)

---

在这里提醒一下,也许你会看到像我这样的提示:verify error:num=20:unable to get local issuercertificate

verify return:0

其实是没问题的。



七 项目测试

建立我们的推送的项目(注意BundleIdentifier必须和我们推送应用的App id一致

在AppDelegate里didFinishLaunchingWithOptions函数里写

- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

……

  //推送的形式:标记,声音,提示

   [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];

   return YES;

}

 

- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {

   NSLog(@"regisger success:%@",pToken);

   //注册成功,将deviceToken保存到应用服务器数据库中

}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{

    // 处理推送消息

    NSLog(@"userinfo:%@",userInfo);

   

    NSLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);

}

- (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

   NSLog(@"Registfail%@",error); 

}

我们运行程序的时候会有提示,说我们的程序要发送推送通知

 

 

下面我们把php服务器代码和生成的ck.pem文件放在统一文件夹下面(这里我们还是统一放在桌面上)。

用Xcode打开(其他工具也可以)php服务器端的代码,把deviceToken改成我们现在要进行测试的iphone的deviceToken(获得方法,:在Xcode的顶部工具栏点击windowàOrganizer,在左侧选中我们的iphone后,右边的Identifier后面的就是了),密语改成我们之前设置的abcabc。然后保存。

然后在终端运行命令(如果刚才你关闭了终端的话,最好ls一下,看看当前是不是在桌面),执行命令:

php pushMe.php

然后回车(pushMe为服务器文件名称)


如果出现这样的提示说明成功了,然后在iphone上,我们期待已久的推送消息终于来了。

以下是推送的几种效果:

 

常见问题:

1、在用证书和秘钥链接服务器时出现提示:

Error opening client certificate private key filePushChatKey.pem

20839:error:02001002:system library:fopen:No such file ordirectory:/SourceCache/OpenSSL098/OpenSSL098-44/src/crypto/bio/bss_file.c:356:fopen('PushChatKey.pem','r')

20839:error:20074002:BIO routines:FILE_CTRL:systemlib:/SourceCache/OpenSSL098/OpenSSL098-44/src/crypto/bio/bss_file.c:358:

unable to load client certificate private key file

 

解决:

文件路径不对。cd到生成的pem文件路径下再进行链接

 

2、前期测试没有问题,将ck.pem给服务器,通过服务器进行推送时推送不成功,提示链接APNS失败。

解决:一,看一下证书的名称,密语是否正确;二,路径是否正确;然后检查一下库,OpenSSL和libssl;此外apache还要开启OpenSSL权限,确保可以访问pem

 

3、APNS地址 
测试地址gateway.sandbox.push.apple.com:2195 
发布地址 gateway.push.apple.com:2195

测试的地址用的是沙盒,发布地址是不同的。发布软件的时候记得改过来


4、要注意顺序问题,一定要按照这个顺序来:

生成钥匙串请求 -->配置下载开发证书-->  配置App ID ,配置、下载SSL证书-->Provisioning证书 


5、多注意一下红色字体部分 


在此感谢曾经为此而努力过的前辈们,尤其是感谢杨大哥的帮助。

在这里附上杨大哥的帖子:http://www.cocoachina.com/bbs/read.php?tid=102110&page=1

 

另外附上几个关于推送的不错的帖子:

http://zxs19861202.iteye.com/blog/1532460

一篇很不错的帖子,老外写的

http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12

中文翻译

http://article.ityran.com/archives/194

 

在过程中如果有疑问可以新浪或腾讯微博@showhilllee虽然本人是菜鸟一个,也许不能为你把问题解决掉,但是会本着菜鸟精神去帮你解决

 

转帖请注明出处:http://blog.csdn.net/showhilllee/article/details/8631734


php服务器代码pushMe.php:http://vdisk.weibo.com/s/zw-xeocHvZSgv  


本文若有问题,欢迎大家斧正



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值