手把手教你如何把阿里云推送集成到iOS客户端

  • 吴 金帆
  • 2017-04-14 10:29

 

    阿里移动推送(Alibaba Cloud Mobile Push)是基于大数据的移动智能推送服务,帮助App快速集成移动推送的功能,在实现高效、精确、实时的移动推送的同时,极大地降低了开发成本。让开发者最有效地与用户保持连接,从而提高用户活跃度、提高应用的留存率。 

下面主要讲解一下如何集成阿里云推送到iOS客户端

一、注册阿里云账号

      既然使用阿里云的服务 不可避免的要去阿里云开放平台去注册一个开发者账号(https://www.aliyun.com/product/cps?spm=5176.8142029.388261.67.piFGhL)  

         

      简单的注册流程之后  再次回到移动推送的首页点击 “立即开通”    之后需要 实名认证 一下      

     

     

        认证分为两种  个人和企业  

        1.个人认证比较简单 绑定到个人支付宝即可  

        2.企业认证 有2种途径

            途径1:通过企业支付宝快速认证

            途径2:通过企业银行卡信息认证

       至此我们就已经完成了阿里云账号的注册

 

二、开放平台注册移动应用

      完成注册之后 回到移动推送首页 点击 管理控制台

       

     跳转到控制台页面后 我们需要创建我们的APP  点击“创建APP”按钮

     

    

    简单的填写信息

      

     好了,我们的应用创建完成了

三、配置证书

     iOS的推送是要走 苹果的APNS服务器的  大致流程是  

         1.客户端从APNS服务器注册一个devicetoken   

         2.客户端把 devicetoken 发送到阿里云的推送服务器换取一个 deviceid(此时也可以直接把app的用户账号或者标签和deviceid进行绑定 发送到 阿里云的服务器) 

         3.客户端把 deviceid 发送到后台

         4.后台根据deviceid(已经绑定账号或标签的可以根据账号或者标签推送) 把需要推送的消息发送到 阿里云的服务器 

         5.阿里云服务器把需要推送的消息和设备的devicetoken 发送到苹果的APNS服务器 

         6.APNS服务器根据devicetoken 把消息发送到指定设备

         7.设备收到推送消息

    为了能保证收到来自APNS服务器的推送 需要到苹果的开发者平台制作一个推送证书

    首先从本地先制作一个CSR文件    打开钥匙串

       

    点击左上角证书助理→ 从证书颁发机构请求证书

       

   选择 存储到磁盘  点击继续 把CSR 文件存储到桌面

                                      

      打开苹果的 开发者平台  创建一个appid

      

      填写名称 和app的唯一标识 bundleid

      

       选择允许推送  点击continue    → register

           

         回到首页找到刚刚创建的appid

        

       托到最下边 点击  edit

     

    找到 push Notification   点击 创建 推送的 开发证书(开发环境下可收到推送)  和  生产证书(生产环境下可收到推送)

   

   选择上传刚刚从本地创建的CRS文件

    

     下载证书  并且双击安装证书   

      

       回到钥匙串   找到对应的证书(注意要区分好 开发证书 和 生产证书) 选择导出 .p12格式的证书副本

            

        

   

        回到 阿里云的推送应用页面    把刚刚创建好的 推送证书导入

         

  四、集成阿里云推送的SDK

       下载sdk

                    

      从Xcode的对应工程 导入sdk

      

     添加需要依赖的公共包  

  • libz.tbd
  • libresolv.tbd
  • CoreTelephony.framework
  • SystemConfiguration.framework

      

   在 other linker flags 配置一下 sdk的路径 -force_load <sdk路径>/CloudPushSDK.framework/CloudPushSDK 让编译器加载sdk里面的非ObjC文件

        

     

     一般我们会在appdelegate 里面对sdk初始化   首先包含头文件

       #import <CloudPushSDK/CloudPushSDK.h>

在 app生命周期的 didFinishLaunchingWithOptions 方法中添加

  1.     // APNs注册,获取deviceToken并上报
  2.     [self registerAPNS:application];
  3.     // 初始化SDK
  4.     [self initCloudPush];
  5.     // 监听推送通道打开动作
  6.     [self listenerOnChannelOpened];
  7.     // 监听推送消息到达
  8.     [self registerMessageReceive];
  9.     // 点击通知将App从关闭状态启动时,将通知打开回执上报
  10.     // [CloudPushSDK handleLaunching:launchOptions];//(Deprecated from v1.8.1)
  11.    [CloudPushSDK sendNotificationAck:launchOptions];

     初始化sdk

  1. - (void)initCloudPush {
  2.     // 正式上线建议关闭
  3.     [CloudPushSDK turnOnDebug];
  4.     // SDK初始化
  5.     [CloudPushSDK asyncInit:@"你的appkey" appSecret:@"你的appSecret" callback:^(CloudPushCallbackResult *res) {
  6.         if (res.success) {
  7.             NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]);
  8.         } else {
  9.             NSLog(@"Push SDK init failed, error: %@", res.error);
  10.         }
  11.     }];
  12. }
  13.  

     这里需要填写一个appkey 和appsecret   打开阿里云移动推送平台找到应用

    

     点击显示可以查看appsecret

     

 

    向苹果APNs服务器申请一个设备的deviceToken

  1. - (void)registerAPNS:(UIApplication *)application {
  2.     float systemVersionNum = [[[UIDevice currentDevice] systemVersion] floatValue];
  3.     if (systemVersionNum >= 10.0) {
  4.         // iOS 10 notifications
  5.         _notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
  6.         // 创建category,并注册到通知中心
  7.         [self createCustomNotificationCategory];
  8.         _notificationCenter.delegate = self;
  9.         // 请求推送权限
  10.         [_notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
  11.             if (granted) {
  12.                 // granted
  13.                 NSLog(@"User authored notification.");
  14.                 // 向APNs注册,获取deviceToken
  15.                 [application registerForRemoteNotifications];
  16.             } else {
  17.                 // not granted
  18.                 NSLog(@"User denied notification.");
  19.             }
  20.         }];
  21.     } else if (systemVersionNum >= 8.0) {
  22.         // iOS 8 Notifications
  23. #pragma clang diagnostic push
  24. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  25.         [application registerUserNotificationSettings:
  26.          [UIUserNotificationSettings settingsForTypes:
  27.           (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
  28.                                            categories:nil]];
  29.         [application registerForRemoteNotifications];
  30. #pragma clang diagnostic pop
  31.     } else {
  32.         // iOS < 8 Notifications
  33. #pragma clang diagnostic push
  34. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  35.         [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
  36.          (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
  37. #pragma clang diagnostic pop
  38.     }
  39. }
  40. //iOS10+ 创建通知格式
  41. - (void)createCustomNotificationCategory {
  42.     // 自定义`action1`和`action2`
  43.     UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"action1" title:@"test1" options: UNNotificationActionOptionNone];
  44.     UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"action2" title:@"test2" options: UNNotificationActionOptionNone];
  45.     // 创建id为`test_category`的category,并注册两个action到category
  46.     // UNNotificationCategoryOptionCustomDismissAction表明可以触发通知的dismiss回调
  47.     UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"test_category" actions:@[action1, action2] intentIdentifiers:@[] options:
  48.                                         UNNotificationCategoryOptionCustomDismissAction];
  49.     // 注册category到通知中心
  50.     [_notificationCenter setNotificationCategories:[NSSet setWithObjects:category, nil]];
  51. }

    APNs注册成功的回调,将返回的deviceToken上传到CloudPush服务器

  1. 、- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  2.     NSLog(@"Upload deviceToken to CloudPush server.%@",deviceToken);
  3.     [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) {
  4.         if (res.success) {
  5.             NSLog(@"Register deviceToken success, deviceToken: %@", [CloudPushSDK getApnsDeviceToken]);
  6.         } else {
  7.             NSLog(@"Register deviceToken failed, error: %@", res.error);
  8.         }
  9.     }];
  10.  
  11. }
  12.  
  13. /*
  14.  *  APNs注册失败回调
  15.  */
  16. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  17.     NSLog(@"didFailToRegisterForRemoteNotificationsWithError %@", error);
  18. }

  绑定标签或者账号的方法

  1.       //按账号推送
  2. //        [CloudPushSDK  bindAccount:@"13022189291" withCallback:^(CloudPushCallbackResult *res) {
  3. //            NSLog(@"%@",res);
  4. //        }];
  5.         
  6.    
  7.     //按标签推送
  8.     //    [CloudPushSDK bindTag:@"" withTags:@"" withAlias:@"" withCallback:^(CloudPushCallbackResult *res) {
  9.    //        
  10.    //    }];

 

推送消息到来监听 处理推送来的消息

  1. - (void)registerMessageReceive {
  2. [[NSNotificationCenter defaultCenter] addObserver:self
  3. selector:@selector(onMessageReceived:)
  4. name:@"CCPDidReceiveMessageNotification"
  5. object:nil];
  6. }
  7.  
  8. /**
  9. * 处理到来推送消息
  10. *
  11. * @param notification
  12. */
  13. - (void)onMessageReceived:(NSNotification *)notification {
  14. CCPSysMessage *message = [notification object];
  15. NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding];
  16. NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding];
  17. NSLog(@"Receive message title: %@, content: %@.", title, body);
  18. }

通知打开的监听

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  2. // 点击通知将App从关闭状态启动时,将通知打开回执上报
  3. // [CloudPushSDK handleLaunching:launchOptions];(Deprecated from v1.8.1)
  4. [CloudPushSDK sendNotificationAck:launchOptions];
  5. return YES;
  6. }
  7.  
  8. /*
  9. * App处于启动状态时,通知打开回调
  10. */
  11. - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo {
  12. NSLog(@"Receive one notification.");
  13. // 取得APNS通知内容
  14. NSDictionary *aps = [userInfo valueForKey:@"aps"];
  15. // 内容
  16. NSString *content = [aps valueForKey:@"alert"];
  17. // badge数量
  18. NSInteger badge = [[aps valueForKey:@"badge"] integerValue];
  19. // 播放声音
  20. NSString *sound = [aps valueForKey:@"sound"];
  21. // 取得Extras字段内容
  22. NSString *Extras = [userInfo valueForKey:@"Extras"]; //服务端中Extras字段,key是自己定义的
  23. NSLog(@"content = [%@], badge = [%ld], sound = [%@], Extras = [%@]", content, (long)badge, sound, Extras);
  24. // iOS badge 清0
  25. application.applicationIconBadgeNumber = 0;
  26. // 通知打开回执上报
  27. // [CloudPushSDK handleReceiveRemoteNotification:userInfo];(Deprecated from v1.8.1)
  28. [CloudPushSDK sendNotificationAck:userInfo];
  29. }

 

app在前台时收到通知 iOS10+特殊处理

  1. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  2.     NSLog(@"Receive a notification in foregound.");
  3.     // 处理iOS 10通知,并上报通知打开回执
  4.     [self handleiOS10Notification:notification];
  5.     // 通知不弹出
  6.     completionHandler(UNNotificationPresentationOptionNone);
  7.     
  8.     // 通知弹出,且带有声音、内容和角标
  9.    // completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
  10. }

  点击通知栏的回调iOS10+

  1. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
  2.     NSString *userAction = response.actionIdentifier;
  3.     // 点击通知打开
  4.     if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
  5.         NSLog(@"User opened the notification.");
  6.         // 处理iOS 10通知,并上报通知打开回执
  7.         [self handleiOS10Notification:response.notification];
  8.     }
  9.     // 通知dismiss,category创建时传入UNNotificationCategoryOptionCustomDismissAction才可以触发
  10.     if ([userAction isEqualToString:UNNotificationDismissActionIdentifier]) {
  11.         NSLog(@"User dismissed the notification.");
  12.     }
  13.     NSString *customAction1 = @"action1";
  14.     NSString *customAction2 = @"action2";
  15.     // 点击用户自定义Action1
  16.     if ([userAction isEqualToString:customAction1]) {
  17.         NSLog(@"User custom action1.");
  18.     }
  19.     
  20.     // 点击用户自定义Action2
  21.     if ([userAction isEqualToString:customAction2]) {
  22.         NSLog(@"User custom action2.");
  23.     }
  24.     completionHandler();
  25. }
  26.  

对通知消息的处理iOS10+

  1. - (void)handleiOS10Notification:(UNNotification *)notification {
  2.     UNNotificationRequest *request = notification.request;
  3.     UNNotificationContent *content = request.content;
  4.     NSDictionary *userInfo = content.userInfo;
  5.     // 通知时间
  6.     NSDate *noticeDate = notification.date;
  7.     // 标题
  8.     NSString *title = content.title;
  9.     // 副标题
  10.     NSString *subtitle = content.subtitle;
  11.     // 内容
  12.     NSString *body = content.body;
  13.     // 角标
  14.     int badge = [content.badge intValue];
  15.     // 取得通知自定义字段内容,例:获取key为"Extras"的内容
  16.     NSString *extras = [userInfo valueForKey:@"Extras"];
  17.     // 通知打开回执上报
  18.     [CloudPushSDK sendNotificationAck:userInfo];
  19.     NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d, extras: %@.", noticeDate, title, subtitle, body, badge, extras);
  20. }
  21.  

把这个打开 顺便还能帮你检查一下证书对不对

                 

  五、推送测试

  连接真机运行app 可以在控制台找到deviceid

      

到阿里云推送的平台上可以创建测试推送 选择推送通知  和开发环境  (生产环境和开发环境差不多 需要打一个ADHoc版本的包安装到手机才可以测试 或者上线后从appstore下载)

     、

把我们刚刚获得deviceId 填进去  点击发送 

     

就可以愉快的收到推送消息了

     

 

 

阅读 2848