远程推送

来源:互联网 发布:java prim算法 编辑:程序博客网 时间:2024/06/02 00:58
这里主要详细介绍苹果的远程推送服务,在本文后会有本地通知的简单示例。
一,IOS远程通知服务APNs
苹果的APNs(苹果推送通知服务Apple Push Notification server)允许设备和苹果的推送通知服务器保持链接,支持开发者推送消息到给用户设备对应的应用程序。
苹果的APNs基本原理是:
首先由应用注册远程通知。注册成功之后APNs会返回一个唯一标示的设备令牌码deviceToken,应用拿到分配的设备令牌码之后,需要将该设备令牌码连同其他设备以及帐户相关信息(如果有必要的话)传递给该应用对应的后台服务器。当后台服务器需要推送消息时,就将消息以及需要推送设备对应的deviceToken传递给APNs,由APNs完成推送工作.
不仅如此,应用对应的后台服务器还需要经常和APNs进行反馈通信,以便后台服务器可以知道那些deviceToken已经不存在(可能的原因是用户卸载了本应用),这种情况下我们不应该再向deviceToken对应的设备发送消息,否则会增加系统负荷。事实上,做苹果的APNs大量的工作都在后台,在前台的app开发中需要做的就是获取deviceToken并传递给后台服务器。
下面特酷吧根据自己的实践介绍下整个操作流程。
如果之前我们创建App ID时配置了开启推送服务,那么我们使用的开发和发布版的Provisioning文件已经能够满足我们的操作,这种情况下需要做的就是制作后台服务器使用的证书文件。
1,创建请求证书
使用该证书请求来申请一个用于开发的SSL证书。
1. 打开“钥匙串访问”应用程序。
2. 选择“KeychainAccess[钥匙串访问]->Certificate Assistant[证书助理]->Request a Certificate From CertificateAuthority[从证书办法机构请求证书]”
输入账户等信息后以默认的文件名保存到本地。名称一般为CertificateSigningRequest.certSigningRequest。
2,申请开发的SSL证书
(1)创建App ID
使用APNs服务的IOS应用必须有一个唯一的App ID。首先我们需要创建App ID。
进入apple开发者中心
https://developer.apple.com/devcenter/ios/index.action
进入"Certificates,Identifiers & Profiles"。
[特酷吧写这篇文章的时候是2013年5月,apple开发者中心的网站似乎改版过,和之前有些不一样了]。
进入"ios Apps",点击"Identifiers"。
点击右上角的加号添加一个App ID.
App ID Description中name可以随便取一个名字.
App Services中Enable Services字段需要勾选Push Notifications。[当前这些内容都可以在App ID创建好之后重新再配置]
Explicit App ID中的Bundle ID填入我们应用的Bundle ID即可。其他默认。
(2)配置App ID
创建好App ID之后,进入该App ID详情页面。进入setting。
选择"Create an additional certificate to use for this App ID."进入"Create Certificate"页面之后根据提示向导选择第1步生成的请求证书上传。
再根据操作向导下载生成好的开发版的SSL证书。下载之后[名称为aps_development.cer],双击将证书安装到钥匙串中。这个证书会允许你的程序接收APNs发送来的推送通知。
3,创建Provisioning Profile
进入https://developer.apple.com/account/ios/profile/profileList.action
Provisioning Profiles
点击右上角加号添加Provisioning Profile, 选择iOS App Development,选择你刚才创建的App ID。
过程中会让你选择你需要包含的设备(我是勾选所有设备)。再随便输入你取的证书的名字即可生成该证书。下载到本地安装该文件。名称一般为XXXX.mobileprovision
将XXXX.mobileprovision导出p12格式的私钥文件,这里名称为Certificates.p12文件
4,制作后台服务器(C#为例)使用的p12文件
需要创建C#用的证书文件,具体制作过程如下:
制作p12文件,我们需要使用OpenSSL
我们需要上面几步中得到的三个文件:
1、CertificateSigningRequest.certSigningRequest
2、Certificates.p12//本地导出的私钥文件
3、aps_development.cer
操作如下,在终端中执行;
1、将aps_development.cer转换成aps_development.pem格式。
openssl x509 -in aps_development.cer -inform DER -out aps_development.pem -outform PEM
2、将p12格式的私钥转换成pem,需要设置几次密码。
openssl pkcs12 -nocerts -out Certificates.pem -in Certificates.p12
3、用CertificateSigningRequest.certSigningRequest, Certificates.pem和aps_development.pem创建P12格式的文件。
openssl pkcs12 -export -in aps_development.pem -inkey Certificates.pem -certfile CertificateSigningRequest.certSigningRequest -name "aps_developer_identity" -out aps_developer_identity.p12
这样我们就得到了在.net应用程序中使用的证书文件:aps_developer_identity.p12。
基于C#,JAVA等程序的开源的库也比较多,如:https://github.com/Redth/APNS-Sharp提供了一个C#的版本。在该测试程序中,需要给出这里的aps_developer_identity.p12文件以及密码。
此外,为了方便IOS开发者测试APNs,已经有很多做好的线程的服务器端的demo,比如:PushMeBaby[下载地址:https://github.com/stefanhafeneger/PushMeBaby].
下载完成后打开工程,将aps.developer.cer文件加入到工程中,修改工程中对应代码:
self.deviceToken = /*填入第4步中didRegisterForRemoteNotificationsWithDeviceToken获取到的deviceToken*/;
self.certificate = [[NSBundle mainBundle] pathForResource:@"aps_developer" ofType:@"cer"]; 
运行PushMeBaby工程,点击push即可给app终端发送消息。
5,本地app代码参考
1,在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中注册远程通知
//注册远程通知
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
2,实现几个代理方法:
  1. //获取deviceToken令牌  
  2. -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken  
  3. {  
  4.     //获取设备的deviceToken唯一编号  
  5.     NSLog(@"deviceToken=%@",deviceToken);  
  6.     NSString *realDeviceToken=[NSString stringWithFormat:@"%@",deviceToken];  
  7.     //去除<>  
  8.     realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@"<" withString:@""];  
  9.     realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@">" withString:@""];  
  10.     NSLog(@"realDeviceToken=%@",realDeviceToken);  
  11.     [[NSUserDefaults standardUserDefaults] setValue:realDeviceToken forKey:@"DeviceToken"];  
  12. }  
  13.   
  14. //获取令牌出错  
  15. -(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error  
  16. {  
  17.     //注册远程通知设备出错  
  18.     NSLog(@"RegisterForRemoteNotification error=%@",error);  
  19. }  
  20. //在应用在前台时受到消息调用  
  21. -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo  
  22. {  
  23.    //打印推送的消息  
  24.   NSLog(@"%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]):  
  25. }  
另外:
在进行IOS远程推送的过程中,首先需要创建带有“Enable for Apple Push Notification service”的App ID。如果之前的创建的App ID开启了推送功能,则可以直接使用之前开发和发布需要的Provisioning。如果之前的App ID没有配置开启远程推送功能,则应该首先创建开启了远程推送功能的App ID,并根据该App ID生成对应的开发和发布版本的Provisioning。
还需要制作服务器端的证书,如果app使用的是开发者证书,则需要使用此开发者证书制作服务器端的开发者证书,等到发布版的时候,还需要制作发布版本的证书。
使用开发者证书的测试地址
gateway.sandbox.push.apple.com:2195 
发布版本的地址
gateway.push.apple.com:2195
另外一个值得注意的问题是:一般我们是使用开发版本的Provisioning做推送测试,如果没有问题,再使用发布版本证书的时候一般也应该是没有问题的。为了以防万一,我们可以在越狱的手机上安装我们的使用发布版证书的ipa文件(最好使用debug版本,并打印出获取到的deviceToken),安装成功后在;XCode->Window->Organizer-找到对应的设备查看console找到打印的deviceToken。
在后台的推送程序中使用发布版制作的证书并使用该deviceToken做推送服务.
使用开发和发布证书获取到的deviceToken是不一样的



 
远程通知
 
/**
 远程消息推送必须在真机上运行!
 */
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 需要告诉苹果的服务器,当前应用程序需要接收远程通知
    [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | 
     UIRemoteNotificationTypeSound];
    returnYES;
}
 
#pragma mark - 获取到设备的代号(令牌)
// 接收到苹果返回的设备代号
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    // 第一次运行获取到DeviceToken时间会比较长!
    NSLog(@"%@", deviceToken);
     
    // 将deviceToken转换成字符串,以便后续使用
    NSString *token = [deviceToken description];
    NSLog(@"description %@", token);
     
    // =======================================================
    // 如果DeviceToken发生变化,需要通知服务器
    // 每次都记录住从服务器获取到得DeviceToken
    // 再次获取时进行比对
    // 从偏好设置取出当前保存的Token
    NSString *oldToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"DeviceToken"];
     
    // 当Token发生变化时,提交给服务器保存新的Token
//    if (![oldToken isEqualToString:token]) {
//        
//        // 将deviceToken通过Post请求,提交给自己的服务器即可!
//        // 发送Post请求
//        NSURL *url = [NSURL URLWithString:@"公司后台服务器的网址"];
//        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:
//        NSURLRequestUseProtocolCachePolicy timeoutInterval:10.f];
//        request.HTTPMethod = @"POST";
//        request.HTTPBody = @"转换后的设备ID以及其他信息[之前的Token]";
//        
//        // SQL: update t_deviceTable set token = newToken where token = oldToken;
//        
//        // 同步:必须执行完才能继续
//        // 异步:直接交给其他线程工作,不干扰主线程工作,用户也感觉不到延迟
//        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(
//       NSURLResponse *response, NSData *data, NSError *connectionError) {
//            // 偷偷的将用户信息传送到公司的服务器
//        }];
//    }
     
    // 将Token保存至系统偏好
    [[NSUserDefaults standardUserDefaults] setObject:token forKey:@"DeviceToken"];
}

0 0
原创粉丝点击