个推你应该这样用的

前言:

    说到这个远程推送,大家知道的应该都挺多的,但用到的估计极光和个推要占一很大部分,这篇博客重点说的就是个推的使用,个推官网的链接在这里,它的集成是比较方便的,你可以直接使用Cocoapods集成,待会再下面命令行也会给大家分享出来,这我们还会提到的有它的一个推送流程,还有SDK的一些使用以及在使用的过程中我们需要注意的地方:

    先看看个推的推送流程图:

    集成中建议利用Cocoapods集成,建议还是集成这个无IDFA版本,下面是命令行,至于为什么建议集成这个版本的,个推的文档中也有这样一段话:“在 App 内无广告情况下还是建议开发者使用获取 IDFA 版本,并提交 AppStore 审核。 集成 IDFA 而未集成任何广告服务可能会遭到 Apple 拒绝。”。

platform :ios
pod 'GTSDK', '1.5.3-noidfa'

推送需要注意点:

一:在 Xcode 8.0 以上,必须开启Push Notification能力,操作看下图:

二:为了更好支持消息推送,SDK可定期抓取离线消息,提高消息到达率,需要配置后台运行权限,操作如下:

个推把你需要勾选的这两个选项也作出了解释:

Background fetch:     后台定期获取权限

Remote notifications:APNs静默推送权限

代码使用说明:

还是建议大家给个推创建一个APPDelegate的类别,如下图所示:

下一步就是注册远程通知 即用户是否同意接收通知,源代码如下:

/** 注册远程通知 即用户是否同意接收通知 */
- (void)registerRemoteNotification {
    
    /*
     Xcode8的需要手动开启“TARGETS -> Capabilities -> Push Notifications”
     */
    /*
     下面的方法区分10.0之后版本和之前版本
     该项目的最低适配版本是8.0之后的,所以放弃8.0之前注册远程通知方法
     */
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // Xcode 8编译会调用
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
            if (!error) {
                
                // NSLog(@"request authorization succeeded!");
            }
        }];
        
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    #else 
    // Xcode 7编译会调用
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    #endif
    // 大于等于8.0系统的就用这个方法注册远程通知
    }else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
        
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
}

#pragma mark - 远程通知(推送)回调
/** 远程通知注册成功委托 */
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    // 获取到的Token
    // NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token);
    
    // [ GTSdk ]:向个推服务器注册deviceToken,这个方法写在类别里面!
    [self registerDeviceTokenToGeTuiSDK:token];
   
}

/** 远程通知注册失败委托 */
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    
    // NSLog(@"\n>>>[DeviceToken Error]:%@\n\n", error.description);
} 

原本想着把SDK的方法一个一个写出来解读的,不过那样子感觉就像官方文档了,没什么意思了,在这里我直接把AppDelegate+getui.m这整个文件的代码写出来,每一个方法都是有说明的,里面很多点也是写在了注释当中,这样就觉得更完整,可读性更高一点:

@implementation AppDelegate (getui)

// 初始化个推SDK
-(void)initGeTuiSDK{
    
    // [ GTSdk ]:使用APPID/APPKEY/APPSECRENT创建个推实例
    // 通过个推平台分配的appId、 appKey 、appSecret 启动SDK,
    // 注:该方法需要在主线程中调用
    [GeTuiSdk startSdkWithAppId:GTAPPID appKey:GTAPPKEY appSecret:GTAPPSECRET delegate:self];
}

// Background Fetch 恢复SDK 运行
-(void)BackgroundFetchGeTuiSdk{
    
    // Background Fetch 恢复SDK 运行
    [GeTuiSdk resume];
}

// 同步本地角标值到服务器
-(void)setBadgeGeTuiSdk:(NSInteger)badge{
    
    [GeTuiSdk setBadge:badge];
}

// 重置角标计数
-(void)resetBadgeGeTuiSdk{
    [GeTuiSdk resetBadge];
}

/**
 向个推注册deviceToken
 @param deviceToken deviceToken
 */
-(void)registerDeviceTokenToGeTuiSDK:(NSString *)deviceToken{
    
    // 向个推服务器注册deviceToken
    [GeTuiSdk registerDeviceToken:deviceToken]; 
}

/*
 将收到的APNs信息传给个推统计
 @param userInfo 获取到的消息
 */
-(void)handleRemoteNotificationToGrTuiSDK:(NSDictionary *)userInfo{
    
    // 将收到的APNs信息传给个推统计
    [GeTuiSdk handleRemoteNotification:userInfo];
}

#pragma mark - GeTuiSdkDelegate
/** SDK启动成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
    
    // [4-EXT-1]: 个推SDK已注册,返回clientId
    // NSLog(@"\n>>[GTSdk RegisterClient]:%@\n\n", clientId);
    WRITEUSERDEFAULTS(clientId, ClientId);
}

/** SDK遇到错误回调 */
- (void)GeTuiSdkDidOccurError:(NSError *)error {
    
    // [EXT]:个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
    //NSLog(@"\n>>[GTSdk error]:%@\n\n", [error localizedDescription]);
}

/*  SDK收到透传消息回调 
    SDK 在线状态时( App 在前台运行),个推服务器会直接给 App 发送透传消息,不发送苹果APNS消息,可以更快的把消息发送到手机端;SDK 离线状态时 (停止 SDK 或 App 后台运行 或 App 停止),个推服务器会给 App 发送苹果 APNs 消息,同时保存个推的离线消息,当 SDK 在线后,SDK 会获取所有的个推透传消息,offLine 字段就是表明该条消息是否为离线消息。
 
    注意:这里是否能收到推送消息也是有在线时间限制的,最长是72小时之前的在线过的用户、
    也就是说能收到消息的就是在72小时内在线过的,超过这个时间的是收不到推送消息的,这也就解决好长时间不在线,已在线会收到很多推送消息的困扰
 **/
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
   
    /**
     *汇报个推自定义事件
     *actionId:用户自定义的actionid,int类型,取值90001-90999。
     *taskId:  下发任务的任务ID。
     *msgId:   下发任务的消息ID。
     *返回值:   BOOL,YES表示该命令已经提交,NO表示该命令未提交成功。注:该结果不代表服务器收到该条命令
     **/

    //[GeTuiSdk sendFeedbackMessage:90001 andTaskId:taskId andMsgId:msgId];
    // 数据转换
    NSString *payloadMsg = nil;
    if (payloadData) {
        
        payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding];
    }
    
    // 解析拿到的数据
    if (payloadMsg != nil) {
    
    NSData * data = [payloadMsg dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary * JSONresponseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    }
    
    UIAlertController * GeTuiAlertController=[[NotificationHandleObject sharedInstance]addBaseViewNotificationAlertViewWithMessage:JSONresponseObject[@"title"] andConfirmTitle:@"确定"];
    [self.window.rootViewController presentViewController:GeTuiAlertController animated:YES completion:nil];
    }
  }
}

/** SDK收到sendMessage消息回调 */
- (void)GeTuiSdkDidSendMessage:(NSString *)messageId result:(int)result{
    
    // 发送上行消息结果反馈
    // NSString *msg = [NSString stringWithFormat:@"sendmessage=%@,result=%d", messageId, result];
    // NSLog(@"\n>>[GTSdk DidSendMessage]:%@\n\n", msg);
}

/** SDK运行状态通知 */
- (void)GeTuiSDkDidNotifySdkState:(SdkStatus)aStatus {
    
    // 通知SDK运行状态
    // NSLog(@"\n>>[GTSdk SdkState]:%u\n\n", aStatus);
}

/** SDK设置推送模式回调 */
- (void)GeTuiSdkDidSetPushMode:(BOOL)isModeOff error:(NSError *)error {
    if (error) {
        // NSLog(@"\n>>[GTSdk SetModeOff Error]:%@\n\n", [error localizedDescription]);
        return;
    }
    // NSLog(@"\n>>[GTSdk SetModeOff]:%@\n\n", isModeOff ? @"开启" : @"关闭");
}

// 别名推送
// 绑定别名是否成功
// 处理 绑定/解绑 delegate返回结果:
- (void)GeTuiSdkDidAliasAction:(NSString *)action result:(BOOL)isSuccess sequenceNum:(NSString *)aSn error:(NSError *)aError {

    if ([kGtResponseBindType isEqualToString:action]) {

        //NSLog(@"绑定结果 :%@ !, sn : %@", isSuccess ? @"成功" : @"失败", aSn);
        if (!isSuccess) {

            //NSLog(@"失败原因: %@", aError);
        }
    } else if ([kGtResponseUnBindType isEqualToString:action]) {

        //NSLog(@"绑定结果 :%@ !, sn : %@", isSuccess ? @"成功" : @"失败", aSn);
        if (!isSuccess) {

            //NSLog(@"失败原因: %@", aError);
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

iPhone X大卖 可有人却说这是苹果最后的辉煌

12月5日消息,据国外媒体报道,苹果公司最近一次向市场推出全新产品是什么时候?公司放出不同的想法又是什么时候?规则为了库比蒂诺(苹果公司总部)的光明未来被打破再...

19960
来自专栏iOS122-移动混合开发研究院

RestKit ,一个用于更好支持RESTful风格服务器接口的iOS库

简介 RestKit 是一个用于更好支持RESTful风格服务器接口的iOS库,可直接将联网获取的json/xml数据转换为iOS对象. 最新示例: 点击下载 ...

20950
来自专栏IMWeb前端团队

聊聊移动端跨平台开发的各种技术

介绍 最近出现的 React Native 再次让跨平台移动端开发这个话题火起来了,曾经大家以为在手机上可以像桌面那样通过 Web 技术来实现跨平台开发,却大多...

34050
来自专栏iOS122-移动混合开发研究院

EAIntroView–高度可定制的iOS应用欢迎页通用解决方案

简介 高度可定制的应用欢迎页通用解决方案,可高度定制,不要仅限于现有的demo. 最新示例: 点击下载 入门 安装 安装后,引入” EAIntroView.h”...

22260
来自专栏iOS122-移动混合开发研究院

SVProgressHUD–比MBProgressHUD更好用的 iOS进度提示组件

简介 ? SVProgressHUD是简单易用的显示器,用于指示一个持续进行的任务的进度. 最新示例: 点击下载 快速入门 安装 通过Cocoapods pod...

46180
来自专栏iOS122-移动混合开发研究院

有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?

Apple 算是最重视应用开发体验的公司了.从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发...

20060
来自专栏iOS122-移动混合开发研究院

RDVTabBarController--可自由定制的iOS底部导航控件

RDVTabBarController:一个十分完善的tabBarController,可以自定义角标个数,爽的停不下来。 RDVTabBarControlle...

254100
来自专栏王二麻子IT技术交流园地

四、VueJs 填坑日记之搭建Axios接口请求工具

上一章,我们认识了项目的目录结构,以及对项目的目录结构做了一些调整,已经能把项目重新跑起来了。今天我们来搭建api接口调用工具Axios。Vue本身是不支持aj...

39180
来自专栏iOS122-移动混合开发研究院

Pop–实现任意iOS对象的任意属性的动态变化

简介 Pop 是一个可扩展的动画引擎,可用于实现任意iOS对象的任意属性的动态变化,支持一般动画,弹性动画和渐变动画三种类型. 最新示例: 点击下载 注...

22570
来自专栏iOS122-移动混合开发研究院

Aspects– iOS的AOP面向切面编程的库

简介 一个简洁高效的用于使iOS支持AOP面向切面编程的库.它可以帮助你在不改变一个类或类实例的代码的前提下,有效更改类的行为.比iOS传统的 AOP方法,更加...

44980

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励