美文网首页iOS收藏iOS Coding推送
iOS开发-极光远程推送

iOS开发-极光远程推送

作者: 看我的大白眼 | 来源:发表于2016-11-01 13:50 被阅读237次
    • 首先要在控制台创建应用,并上传iOS开发证书以及生产证书,不了解的可以看iOS SDK教程,官方有详细的介绍

    • 下载官方的iOS SDK

    • 导入API开发包到应用程序项目

      • 将SDK包解压,在XCode中选择“Add files to 'Your project name'...”,将解压后的lib子文件夹(包含JPUSHService.h、jpush-ios-x.x.x.a)添加到你的工程目录中。
    • 必要的框架

      • CFNetwork.framework
      • CoreFoundation.framework
      • CoreTelephony.framework
      • SystemConfiguration.framework
      • CoreGraphics.framework
      • Foundation.framework
      • UIKit.framework
      • Security.framework
      • Xcode7需要的是libz.tbd;Xcode7以下版本是libz.dylib
      • Adsupport.framework (获取IDFA需要;如果不使用IDFA,请不要添加)
    • Build Settings
      如果你的工程需要支持小于7.0的iOS系统,请到Build Settings 关闭 bitCode 选项,否则将无法正常编译通过

      • 设置 Search Paths 下的 User Header Search Paths 和 Library Search Paths,比如SDK文件夹(默认为lib)与工程文件在同一级目录下,则都设置为"$(SRCROOT)/{静态库所在文件夹名称}"即可
    • 创建并配置PushConfig.plist文件(非必需)

      • 我们可以在JPush-iOS-SDK的demo中把PushConfig.plist拖到自己的项目中

      CHANNEL

      • 指明应用程序包的下载渠道,为方便分渠道统计,具体值由你自行定义,如:App Store。

      APP_KEY

      • 填写管理Portal上创建应用后自动生成的AppKey值

      APS_FOR_PRODUCTION

      • 0 (默认值)表示采用的是开发证书,1 表示采用生产证书发布应用,此字段的值要与Build Settings的Code Signing配置的证书环境一致。
    • 或者在AppDelegate中设置

    static NSString *appKey = @"AppKey copied from JPush Portal application";
    static NSString *channel = @"Publish channel";
    static BOOL isProduction = FALSE;
        
    //如不需要使用IDFA,advertisingIdentifier 可为nil
    [JPUSHService setupWithOption:launchOptions appKey:appKey
                            channel:channel
                   apsForProduction:isProduction
              advertisingIdentifier:advertisingId];
    
    • 添加代码

    如果用的是Xcode7时,需要在App项目的plist手动配置下key和值以支持http传输:

          <key>NSAppTransportSecurity</key> 
      <dict> 
        <key>NSAllowsArbitraryLoads</key> 
        <true/> 
      </dict>
      
    
    • 集成所需API
      导入头文件
    #import "JPUSHService.h"
    #import <AdSupport/AdSupport.h>
    

    初始化代码

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        ///  JPush
         NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
      //Required
      if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
        JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
        entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
        [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
      } 
      else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        //可以添加自定义categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                              categories:nil];
      } 
      else {
        //categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                              categories:nil];
      }
    
      //Required
      // init Push(2.1.5版本的SDK新增的注册方法,改成可上报IDFA,如果没有使用IDFA直接传nil  )
      // 如需继续使用pushConfig.plist文件声明appKey等配置内容,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。
      [JPUSHService setupWithOption:launchOptions appKey:appKey
                            channel:channel
                   apsForProduction:isProduction
              advertisingIdentifier:advertisingId]; 
    
        return YES;
    }
    

    注册APNs成功并上报DeviceToken

    //  获取deviceToken的方法
    - (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        
        /// Required - 注册 DeviceToken
        [JPUSHService registerDeviceToken:deviceToken];
    }
    

    实现注册APNs失败接口(可选)

    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
        NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
    }
    
    

    添加处理APNs通知回调方法

    //JPUSHRegisterDelegate
    // iOS 10 Support
    - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
      // Required
      NSDictionary * userInfo = notification.request.content.userInfo;
      if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
      }
      completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
    }
    
    // iOS 10 Support
    - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
      // Required
      NSDictionary * userInfo = response.notification.request.content.userInfo;
      if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
      }
      completionHandler();  // 系统要求执行这个方法
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    
      // Required, iOS 7 Support
      [JPUSHService handleRemoteNotification:userInfo];
      completionHandler(UIBackgroundFetchResultNewData);
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
      // Required,For systems with less than or equal to iOS6
      [JPUSHService handleRemoteNotification:userInfo];
    }
    
    
    • 测试

    <div align = center>


    设置推送
    查看推送情况

    </div>

    有时候推送会有延迟,延迟根据情况而定

    消息类型

    一条消息推送过来,可以有如下几种表现形式:

    • 显示一个alter或者banner,展现具体内容
    • 在应用icon上提示一个新到消息数
    • 播放一段声音

    开发者可以在每次推送的时候设置,在推送达到用户设备时开发者也可以选择不同的提示方式。

    获取 APNs(通知) 推送内容

    iOS 设备收到一条推送(APNs),用户点击推送通知打开应用时,应用程序根据状态不同进行处理需在 AppDelegate 中的以下两个方法中添加代码以获取apn内容

    • 如果 App 状态为未运行,此函数将被调用,如果launchOptions包含UIApplicationLaunchOptionsRemoteNotificationKey表示用户点击apn 通知导致app被启动运行;如果不含有对应键值则表示 App 不是因点击apn而被启动,可能为直接点击icon被启动或其他。
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; 
    // apn 内容获取:
    NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKe
    
    
    • 如果远程消息发送过来的时候,app正在运行,app代理的application:didReceiveRemoteNotification:方法会被调用,同时远程消息中的payload数据会作为参数传递进去。
      示例代码如下:
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
        if (application.applicationState == UIApplicationStateActive) {
            // 转换成一个本地通知,显示到通知栏,你也可以直接显示出一个alertView,只是那样稍显aggressive
            UILocalNotification *localNotification = [[UILocalNotification alloc] init];
            localNotification.userInfo = userInfo;
            localNotification.soundName = UILocalNotificationDefaultSoundName;
            localNotification.alertBody = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
            localNotification.fireDate = [NSDate date];
            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
        } else {
            // 其他处理
        }
    }
    
    

    极光推送平台发出去的通知格式究竟是什么样子的

    对于每一条推送消息,都包含一个payload,通常是组成了一个JSON的Dictionary,这其中必不可少的是aps属性,它对应的value也是一个Dictionary,包含下面一些内容:

    • alert消息(文本或Dictionary)

    • 应用图标上的红色数字

    • 播放的声音文件名
      在极光推送的后台发送通知中,有可选设置,用于客户端自定义事件处理。


      可选设置

    我们可以添加一下字段 如:target,goods_id,这样客户端就知道跳到哪个转页面

    应用该怎么响应推送消息

    我们有时候希望带给用户更好的使用体验,譬如一个商城应用推送了一条商品降价的信息,如果用户点击进入了APP,我们应该展示具体的商品详情,而不是进入APP,让用户再去找降价的商品.

    我们在这里以iOS10为例,因为手上没有iOS10一下的机型,暂时不能测试.

    JPUSHRegisterDelegate

    //MARK: iOS 10 Support
    - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
        // Required
        // APNs内容为userInfo
        NSDictionary * userInfo = notification.request.content.userInfo;
        //iOS10 前台收到远程通知
        if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            [JPUSHService handleRemoteNotification:userInfo];
            // 不能直接跳转页面
    //        [self goToMssageViewControllerWith:userInfo];
    
        }
        completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
    }
    
    // iOS 10 Support
    - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
        // Required
        NSDictionary * userInfo = response.notification.request.content.userInfo;
        
        //iOS10 收到远程通知
        if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            [JPUSHService handleRemoteNotification:userInfo];
            [self goToMssageViewControllerWith:userInfo];
        }
        completionHandler();  // 系统要求执行这个方法
    
    }
    
    

    跳转到相应的界面

    // 跳转到相应的界面
    - (void)goToMssageViewControllerWith:(NSDictionary*)msgDic {
        
        NSUserDefaults *pushJudge = [NSUserDefaults standardUserDefaults];
        [pushJudge setObject:@"push" forKey:@"push"];
        [pushJudge synchronize];
        
        NSString *targetStr = [msgDic objectForKey:@"target"];
        
        //trasure 商品详情   activity 最新活动
        if ([targetStr isEqualToString:@"trasure"]) {
            ProductViewController *goodsDetail = [[ProductViewController alloc]init];
            goodsDetail.good_id = msgDic[@"goods_id"];
            MainNavigationController *nav = [[MainNavigationController alloc]initWithRootViewController:goodsDetail];;
            [self.window.rootViewController presentViewController:nav animated:YES completion:nil];
        
        }else if ([targetStr isEqualToString:@"activity"]) {
            
        
        };
        
    }
    

    商品详情(ProductViewController)的处理

    // 添加如下代码
    - (void)viewWillAppear:(BOOL)animated {
        
        [super viewWillAppear:YES];
        
        if ([[MyNSUD objectForKey:@"push"] isEqualToString:@"push"]) {
            // 自定义返回按钮
            UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
            [btn setImage:[UIImage imageNamed:@"jiantou"] forState:UIControlStateNormal];
            [btn addTarget:self action:@selector(rebackToRootViewAction) forControlEvents:UIControlEventTouchUpInside];
            [btn sizeToFit];
            self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
        }else {
            self.navigationItem.leftBarButtonItem=nil;
        }
        
    }
    
    - (void)rebackToRootViewAction {
        [MyNSUD removeObjectForKey:@"push"];
        [MyNSUD synchronize];
        
        [self dismissViewControllerAnimated:YES completion:nil];
        
    }
    
    

    参考资料

    细说 iOS 消息推送

    iOS极光推送 点击推送消息跳转页面

    相关文章

      网友评论

      本文标题:iOS开发-极光远程推送

      本文链接:https://www.haomeiwen.com/subject/jzsmuttx.html