zoukankan      html  css  js  c++  java
  • IOS本地,APNS远程推送(具体过程)

    添加本地推送

    ///本地添加  

    1. -(void)addLocalPushNotification:(UIButton*)sender;  
    2. {  
    3.       
    4.       
    5.     NSLog(@"%s",__FUNCTION__);  
    6.     UILocalNotification* localNotification=[[UILocalNotification alloc]init];  
    7.       
    8.     if (localNotification) {  
    9.         //设置时间当前加20秒  
    10.         NSDate* pushDate=[NSDate dateWithTimeIntervalSinceNow:20];  
    11.         /*推送时区设置:从网上搜到 
    12.         timeZone是UILocalNotification激发时间是否根据时区改变而改变,如果设置为nil的话,那么UILocalNotification将在一段时候后被激发,而不是某一个确切时间被激发。*/  
    13.         localNotification.timeZone=[NSTimeZone defaultTimeZone];  
    14.         ///推送时间设置  
    15.         localNotification.fireDate=pushDate;  
    16.         //时间间隔,若不设置将只会推送1次  
    17.         localNotification.repeatInterval=kCFCalendarUnitDay;  
    18.         //推送时的声音,(若不设置的话系统推送时会无声音)  
    19.         localNotification.soundName=UILocalNotificationDefaultSoundName;  
    20.         //推送的文字信息(若不设置,推送中心中不显示文字,有声音提示前提是设置有声音)  
    21.         localNotification.alertBody=@"Hello world";  
    22.         //推送时小图标的设置,PS:这个东西不知道还有啥用  
    23.         localNotification.alertLaunchImage=[[NSBundle mainBundle]pathForResource:@"3" ofType:@"jpg"];  
    24.           
    25.         ///这个东西,到时用于定位是哪个notification,以便取消用  
    26.         NSDictionary* infoDic=[NSDictionary dictionaryWithObject:@"name" forKey:@"key"];  
    27.         localNotification.userInfo=infoDic;  
    28.           
    29.         //讲推送设置以及信息加入  
    30.         UIApplication* app=[UIApplication sharedApplication];  
    31.         BOOL status=YES;  
    32.         for (UILocalNotification* notification in app.scheduledLocalNotifications) {  
    33.             if ([notification.userInfo objectForKey:@"key"]) {  
    34.                 status=NO;  
    35.             }  
    36.         }  
    37.           
    38.         if (status) {  
    39.             //加入推送(只能加入一次)  
    40.             [app scheduleLocalNotification:localNotification];  
    41.         }  
    42.           
    43.   
    44.           
    45.         NSLog(@"%@",app.scheduledLocalNotifications);  
    46.     }  
    47. }  
    取消本地推送 
    1. ///本地移除  
    2. -(void)removeLocalPushNotification:(UIButton*)sender  
    3. {  
    4.     NSLog(@"%s",__FUNCTION__);  
    5.     UIApplication* app=[UIApplication sharedApplication];  
    6.     //获取当前应用所有的通知  
    7.     NSArray* localNotifications=[app scheduledLocalNotifications];  
    8.   
    9.     if (localNotifications) {  
    10.           
    11.         for (UILocalNotification* notification in localNotifications) {  
    12.   
    13.             NSDictionary* dic=notification.userInfo;  
    14.               
    15.             if (dic) {  
    16.                 NSString* key=[dic objectForKey:@"key"];  
    17.                 if ([key isEqualToString:@"name"]) {  
    18.                     //取消推送 (指定一个取消)  
    19.                     [app cancelLocalNotification:notification];  
    20.                       
    21.                     break;  
    22.                 }  
    23.             }  
    24.   
    25.         }  
    26.     }  
    27.     //取消当前应用所有的推送  
    28.     //[app cancelAllLocalNotifications];  
    29.       
    30.       
    31. }  


    远程推送

    当服务端远程向APNS推送至一台离线的设备时,苹果服务器Qos组件会自动保留一份最新的通知,等设备上线后,Qos将把推送发送到目标设备上

    客户端需要注意的

     bundle ID与App Id一致

    设备Token能正常获取

    若为沙盒测试,证书得使用developer的

    单设备

    如上图所示:我们的服务端将需要推送的相关信息提交到APNS(Apple Push Notification Service),由APNS在Push服务IOS设备列表中找到对应的设备,并将信息推到终端上,终端上再推到客户端APP上

    多设备

    流程大概是这样的

    1.生成CertificateSigningRequest.certSigningRequest文件

    2.将CertificateSigningRequest.certSigningRequest上传进developer,导出.cer文件

    3.利用CSR导出P12文件

    4.需要准备下设备token值(无空格)

    5.使用OpenSSL合成服务器所使用的推送证书

    1.打开钥匙串,在右上角选择(钥匙串访问->证书助理->从证书颁发机构请求证书)

    生成 CertificateSigningRequest.certSigningRequest

    以下信息填写号后,保存到对应位置

    2.进入developer.apple.com中 上传CertificateSigningRequest.certSigningRequest并保存cer文件

    (1)

    (2)选择类型为 推送服务--沙盒测试用

    (3)选中对应的APP ID,别忘了,项目配置文件中的Bundle ID与其一致

    (4)选择保存路径

    (5)选择上传文件 CertificateSigningRequest.certSigningRequest

    (6)保存cer文件,并双击添加进钥匙串

    (7)新建一个Provisioning Profiles

    选中与前面一致的 App Id

    选中刚才新建的certificates

    选择可调试设备

    保存provisioning文件,并将其加入设备中

    通过OPENSSL文件合并

    1.在钥匙串->证书 找到刚才所添加进去的证书 右键导出p12

    2.进入终端 ,将aps_development.cer转成PushChatCert.pem(openssl x509 -in aps_development.cer -inform der  -out PushChatCert.pem)

    3.openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12  生成p12私钥 .pem文件(需设置密码,服务端推送时要用)

    4.利用PushChatCert.pem和新生成的PushChatKey.pem合成一个新的p12文件(这个p12是提供给服务器推送用的)(

    openssl pkcs12 -export -in PushChatCert.pem -inkey PushChatKey.pem -certfile CertificateSigningRequest.certSigningRequest -name "aps_developer_identity" -out aps_developer_identity.p12

    合成PHP所用的PEM文件

    1.   openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
    2.  openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
    3. cat PushChatCert.pem PushChatKey.pem > newck.pem

    代码实现如下

    注册推送通知

    [cpp] view plaincopy
     
    1. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:  
    2. (UIRemoteNotificationTypeAlert|  
    3.  UIRemoteNotificationTypeBadge|  
    4.  UIRemoteNotificationTypeSound)];  


    在AppDelegate中加入以下几个代理方法

    [cpp] view plaincopy
     
    1. ///Token值成功获取的时候走的是这个方法(Token值不能带空格)  
    2. -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken  
    3. {  
    4.   
    5.     NSLog(@"%@",deviceToken);  
    6.   
    7. }  
    8. ///Token值获取失败的时候走的是这个方法  
    9. -(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error  
    10. {  
    11.   
    12.     NSLog(@"%@",error);  
    13. }  
    14. ///应用程序处在打开状态,且服务器有推送消息过来时,以及通过推送打开应用程序,走的是这个方法  
    15. -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo  
    16. {  
    17.     for (id key in userInfo) {  
    18.         NSLog(@"%@:%@",key, [userInfo objectForKey:key]);  
    19.     }  
    20.     ///Icon推送数量设为0  
    21. //    application.applicationIconBadgeNumber=0;  
    22. }  

    应用程序不处在后台,且通过推送通知打开的时候,如果需要推送下来相关的信息可以在

    [cpp] view plaincopy
     
    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  

    方法中加入
    [cpp] view plaincopy
     
    1. ///应用程序不处在后台,并且是通过推送打开应用的时候  
    2. if (launchOptions) {  
    3.     ///获取到推送相关的信息  
    4.     NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];  
    5. }  


    服务端PHP推送代码

    [cpp] view plaincopy
     
    1. <?php  
    2.     $deviceToken= 'ba6d5106503c8e62e68b5df1b36c3b58ced1588c6dabe0fc9e6828961aeb12d6'; //没有空格  
    3.     $body = array("aps" => array("alert" => 'helloHui',"badge" => 2,"sound"=>'default'));  //推送方式,包含内容和声音  
    4.     $ctx = stream_context_create();  
    5.     //如果在Windows的服务器上,寻找pem路径会有问题,路径修改成这样的方法:  
    6.     //$pem = dirname(__FILE__) . '/' . 'apns-dev.pem';  
    7.     //linux 的服务器直接写pem的路径即可  
    8.     stream_context_set_option($ctx,"ssl","local_cert","26ck.pem");  
    9.     $pass = "123123";  
    10.     stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);  
    11.     //此处有两个服务器需要选择,如果是开发测试用,选择第二名sandbox的服务器并使用Dev的pem证书,如果是正是发布,使用Product的pem并选用正式的服务器  
    12. //    $fp = stream_socket_client("ssl://gateway.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);  
    13.     $fp = stream_socket_client("ssl://gateway.sandbox.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);  
    14.     if (!$fp) {  
    15.         echo "Failed to connect $err $errstrn";  
    16.         return;  
    17.     }  
    18.     print "Connection OK ";  
    19.     $payload = json_encode($body);  
    20.     $msg = chr(0) . pack("n",32) . pack("H*", str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;  
    21.     echo "sending message :" . $payload ." ";  
    22.     fwrite($fp, $msg);  
    23.     fclose($fp);?>  
    [php] view plaincopy
     
    1. <pre></pre>  
    2. <pre></pre>  
    3. <pre></pre>  
    4. <pre></pre>  
    5. <pre></pre>  
    6. <pre></pre>  
    7.       
    8.         <div style="padding-top:20px">           
    9.             <p style="font-size:12px;">版权声明:本文为博主原创文章,未经博主允许不得转载。</p>  
    10.         </div>  
     
     
  • 相关阅读:
    Java基础加强总结(一)——注解(Annotation)
    修改intellij(idea)中mybatis对应的xml背景颜色
    spring 手动添加 bean 到容器,例子 :多数据源配置
    Quartz使用总结
    js 上一步 下一步 操作
    BigDecimal提供了8种舍入方式
    precision scale
    jQuery jsonp跨域请求
    js菜鸟进阶-jQuery源码分析(1)-基本架构
    逐行分析jQuery源码
  • 原文地址:https://www.cnblogs.com/fshmjl/p/4870216.html
Copyright © 2011-2022 走看看