首页 > 代码库 > IOS PUSH 实践操作~~~~

IOS PUSH 实践操作~~~~

1.推送过程简介

 
     (1)App启动过程中,使用UIApplication::registerForRemoteNotificationTypes函数与苹果的APNS服务器通信,发出注册远程推送的申请。若注册成功,回调函数application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 会被触发,App可以得到deviceToken,该token就是一个与设备相关的字符串.
     (2)App获取到DeviceToken后,将DeviceToken发送给自己的服务端。
     (3)服务端拿到DeviceToken以后,使用证书文件,向苹果的APNS服务器发起一个SSL连接。连接成功之后,发送一段JSON串,该JSON串包含推送消息的类型及内容。
    (4)苹果的APNS服务器得到JSON串以后,向App发送通知消息,使得App的回调函数application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo被调用,App从userInfo中即可得到推送消息的内容。
 
 
 
2. 用到的证书文件及生成过程
 
   (1)certSigningRequest文件,该文件在MAC系统中生成,用于在Apple网站上申请推送证书文件。
         生成过程:
         打开应用程序中的“钥匙串访问”软件,从菜单中选择 “钥匙串访问”-》“证书助理”-》“从证书颁发机构请求证书”,邮箱和名称随便填写,然后选择保存到磁盘,就可以在本地生成一个CertificateSigningRequest.certSigningRequest文件。
 
   (2)注册一个支持push的app id,后面会用到。
        生成过程:
       进入developer.apple.com,选择member center - Certificates, Identifiers & Profiles  -  Identifiers- App Ids,然后选择注册app id,设置appid名称,同时,app id suffix一栏必须选择explicit app id,然后设置bundle id,最后勾选 App Services中的 Push Notifications,这样就可以注册一个支持push的aphid。
 
    
  (3) 推送证书cer文件,该文件在developer.apple.com中生成,用于生成服务端需要的文件。
        生成过程:
        进入developer.apple.com,选择member center - Certificates, Identifiers & Profiles  -  Certificates,然后选择创建certificate,类型分为Development和Product。这里以Development为例,选择Apple Push Notification service SSL (Sandbox) ,然后下一步,选择之前生成的支持push的AppId,然后下一步,提交之前创建的CSR文件,再下一步就可以生成cer文件,然后保存到本地。
 
  (4)生成服务端使用的证书文件。如果是使用网上的mac 版PushMeBaby工具,在mac机器上进行推送消息的发送,那么有上面的cer文件就够了。如果是使用PHP、java/c#开发自己的服务端,那么还需要将上面的cer文件做一个转换,生成pem文件或者p12文件。
 
       生成php用的pem文件过程为:
        首先双击前面保存的cer文件,此时会打开“钥匙串访问”软件,里面会出现一个Apple Development  IOS push services证书,一个公用密钥和一个专用秘钥,秘钥的名称与证书助理中填写的名称一致。
      选中证书,导出为 apns-dev-cert.p12 文件
      选中专有秘钥,导出为apns-dev-key.p12文件
      通过终端命令将这些文件转换为PEM格式:
      openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
      openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
      最后, 需要将两个pem文件合并成一个apns-dev.pem文件,此文件在连接到APNS时需要使用:
      cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem
      
  (5)生成XCODE使用的provisioning文件,该文件用于真机调试。
         生成过程:
         进入developer.apple.com,选择member center - Certificates, Identifiers & Profiles  -  Provisioning Profiles,然后选择创建Provisioning  file,接着选择iOS App Development ,下一步选择AppId,选中之前建立的支持push的appid,接着下一步选择支持push的certificate,下一步勾选需要支持的device id,最后一步设置provisioning文件的文件名,这样provisioning文件就生成了。
 
 
    3. 服务端的开发
     (1)如果只是希望在mac电脑上测试一下消息的推送,可以使用PushMeBaby工具,使用起来比较简单。该工具是开源的,可以从https://github.com/stefanhafeneger/PushMeBaby,代码的执行过程实际上就是设置一下SSL证书,然后连接APNS,接着发送JSON数据。由于要处理SSL逻辑,因此代码稍微多点。在使用工具时,将工程资源中的cer文件替换成自己的cer文件,然后将代码中的deviceToken替换成自己设备的deviceToken即可。
 
 
 
///////////////////////////

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

{    

    NSString* dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

    NSLog(@"deviceToken:%@", dt);

}

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

    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);

}

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

    NSLog(@"didReceiveRemoteNotification~~~~");

    NSLog(@"remote notification: %@",[userInfo description]);

    NSString* alertStr = nil;

    NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];

    NSObject *alert = [apsInfo objectForKey:@"alert"];

    if ([alert isKindOfClass:[NSString class]])

    {

        alertStr = (NSString*)alert;

    }

    else if ([alert isKindOfClass:[NSDictionary class]])

    {

        NSDictionary* alertDict = (NSDictionary*)alert;

        alertStr = [alertDict objectForKey:@"body"];

    }

    application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];

    if ([application applicationState] == UIApplicationStateActive && alertStr != nil)

    {

        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed222 Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

        [alertView show];

    }

}

 
 
 
/////服务器代码
 

<?php

    

    // Put your device token here (without spaces):

    $deviceToken = ‘7d40b88~~~~~80013f376603ff7a0237509336d6616ae04564b3412b86‘;

    

    // Put your private key‘s passphrase here:

    $passphrase = ‘198~~~~30‘;

    

    // Put your alert message here:

    $message = ‘My first push notification!‘;

    

    ////////////////////////////////////////////////////////////////////////////////

    

    $ctx = stream_context_create();

    stream_context_set_option($ctx, ‘ssl‘, ‘local_cert‘, ‘apns-dev.pem‘);

    stream_context_set_option($ctx, ‘ssl‘, ‘passphrase‘, $passphrase);

    

    // Open a connection to the APNS server

    $fp = stream_socket_client(

                               ‘ssl://gateway.sandbox.push.apple.com:2195‘, $err,$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

    

    if (!$fp)

    exit("Failed to connect: $err $errstr" . PHP_EOL);

    

    echo ‘Connected to APNS‘ . PHP_EOL;

    

    // Create the payload body

    $body[‘aps‘] = array(

                         ‘alert‘ => $message,

                         ‘sound‘ => ‘default‘

                         );

    

    // Encode the payload as JSON

    $payload = json_encode($body);

    

    // Build the binary notification

    $msg = chr(0) . pack(‘n‘, 32) . pack(‘H*‘, $deviceToken) . pack(‘n‘, strlen($payload)) . $payload;

    

    // Send it to the server

    $result = fwrite($fp, $msg, strlen($msg));

    

    if (!$result)

    echo ‘Message not delivered‘ . PHP_EOL;

    else

    echo ‘Message successfully delivered‘ . PHP_EOL;

    

    // Close the connection to the server  

    fclose($fp);

 
 
 
 
 
转载自  http://www.2cto.com/kf/201401/275788.html