个推推送总结:

个推第三方平台官网地址:http://www.getui.com/cn/index.html

首先去官网注册账号,创建应用,应用的配置信息,创建APNs推送证书上传 P12证书(开发对应开发证书,上线对应生产证书)包括导入 SDK 添加依赖库...这些繁琐的事请移步个推官网查看 xcode 集成教程.

一.推送的流程

个推 iOS 推送服务框架如下图所示:

  • 绿色部分是 APNs 推送,个推平台替开发者的应用通过苹果 APNs 服务器向指定的目标设备进行推送。由 APNs Server 将通知推送到相应的 iOS 设备上。
  • 红色部分是个推应用内推送部分,即 App 启动时,应用内集成的个推SDK会开启长连接到个推服务器,从而开发者可通过个推服务器推送消息到 App 里,这条链路性能和稳定性更强,是APNs的一个很重要的补充。

  app 在收到推送消息时分为三种情况

1.app 在前台接收到通知

APP接收到推送后推送后首先弹出一个Alert提示是否跳转页面

2.app 在后台接收到通知

点击通知栏使APP进入前台后,直接跳转页面

点击icon图标使APP进入前台后,不作操作

3.app 处于关闭状态接收到通知

点击通知栏启动APP,直接跳转页面

点击icon图标启动APP,不作操作

二.iOS 集成个推只支持透传消息(透传消息并且支持安卓)

三.集成个推官网 SDK 配置AppID,AppKey,AppSecret


首先为AppDelegate添加一个属性 分辨通知的三种情况

// 用来判断是否是通过点击通知栏开启(唤醒)APP
@property (nonatomic) BOOL isLaunchedByNotification;

[1]:使用APPID/APPKEY/APPSECRENT创建个推实例

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self startSdkWith:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret];
}
- (void)startSdkWith:(NSString *)appID appKey:(NSString *)appKey appSecret:(NSString *)appSecret
{
//[1-1]:通过 AppId、 appKey 、appSecret 启动SDK
//该方法需要在主线程中调用
[GeTuiSdk startSdkWithAppId:appID appKey:appKey appSecret:appSecret delegate:self];
//[1-2]:设置是否后台运行开关
[GeTuiSdk runBackgroundEnable:YES];
//[1-3]:设置电子围栏功能,开启LBS定位服务 和 是否允许SDK 弹出用户定位请求
[GeTuiSdk lbsLocationEnable:YES andUserVerify:YES];
}

[2]:注册APNS

#pragma mark - 用户通知(推送) _自定义方法
/** 注册远程通知 */
- (void)registerRemoteNotification { if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // Xcode 8编译会调用
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[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
} 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];
} else {
UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeBadge);
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
}
}


[3]远程通知注册成功委托

/** 远程通知注册成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token); NSLog(@"--个推注册成功_-");
// [ GTSdk ]:向个推服务器注册deviceToken
[GeTuiSdk registerDeviceToken:token];
}

/** 远程通知注册失败委托 */

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"---个推注册失败---");
    //注册失败通知个推服务器
[GeTuiSdk registerDeviceToken:@""];
}

[4]APP已经接收到“远程”通知(推送) - (App运行在后台/App运行在前台)

/** APP已经接收到“远程”通知(推送) - (App运行在后台/App运行在前台)  */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
//此时 App 在后台点击通知栏进去前台 这里可做进入前台操作
//app 进去前台 icon角标显示数为0 并且发送个推服务器
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[UIApplication sharedApplication].applicationIconBadgeNumber = ;
[GeTuiSdk setBadge:]; // [ GTSdk ]:将收到的APNs信息传给个推统计
[GeTuiSdk handleRemoteNotification:userInfo];
// [4-EXT]:处理APN
NSString *record = [NSString stringWithFormat:@"App运行在后台/App运行在前台[APN]%@, %@", [NSDate date], userInfo];
NSLog(@"%@", record); completionHandler(UIBackgroundFetchResultNewData);
self.isLaunchedByNotification = YES;

//iOS 10中收到推送消息

#pragma mark - iOS 10中收到推送消息

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
// iOS 10: App在前台获取到通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSLog(@"willPresentNotification:%@", notification.request.content.userInfo); // 根据APP需要,判断是否要提示用户Badge、Sound、Alert
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
} // iOS 10: 点击通知进入App时触发
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { //角标复位
[GeTuiSdk resetBadge]; [[UIApplication sharedApplication]setApplicationIconBadgeNumber:]; [[UIApplication sharedApplication] cancelAllLocalNotifications]; NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo); // [ GTSdk ]:将收到的APNs信息传给个推统计
[GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo]; completionHandler();
}
#endif

//设置GeTuiSdkDelegate

注意 APP 启动成功会返回 clientId ,我们项目中使用clientId进行消息透传,在登录的时候将clientId传给我们自己的服务器,我们服务器根据clientId给用户进行推送

/** SDK启动成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId
{
// [4-EXT-1]: 个推SDK已注册,返回clientId
NSLog(@">>>[GeTuiSdk RegisterClient]:----%@", clientId);
// 将clientId写入本地
[USER_DEFAULT setObject:clientId forKey:kPushClientId];
} /** SDK遇到错误回调 */
- (void)GeTuiSdkDidOccurError:(NSError *)error
{
// [EXT]:个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
NSLog(@"\n>>[GTSdk error]:%@\n\n", [error localizedDescription]);
}

/** SDK收到透传消息回调 */

/** SDK收到透传消息回调 */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId
{
// 汇报个推自定义事件
[GeTuiSdk sendFeedbackMessage: andTaskId:taskId andMsgId:msgId]; // [4]: 收到个推消息
//这里收到透传消息,根据自己服务器返回的格式处理
NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:payloadData options:NSJSONReadingMutableLeaves error:nil];
// 当app不在前台时,接收到的推送消息offLine值均为YES
// 判断app是否是点击通知栏消息进行唤醒或开启
// 如果是点击icon图标使得app进入前台,则不做操作,并且同一条推送通知,此方法只执行一次 if (offLine) {
// 离线消息,说明app接收推送时不在前台
if (self.isLaunchedByNotification) {
// app是通过点击通知栏进入前台 } else { // app是通过点击icon进入前台,在这里不做操作 }
} else {
// app已经处于前台,提示框提示
//调用系统震动系统声音
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
AudioServicesPlaySystemSound(); }
// 控制台打印日志
NSString *msg = [NSString stringWithFormat:@"SDK收到透传消息回调taskId=%@,messageId:%@,payloadMsg:%@%@", taskId, msgId, jsonDict, offLine ? @"<离线消息>" : @""];
NSLog(@"\n>>[GTSdk ReceivePayload]:%@\n\n", msg);
#pragma mark--- 接收到推送后,进行提示或怎样 }
/** 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);
}
#pragma mark ---application
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(@"推送的内容:%@",notificationSettings); [application registerForRemoteNotifications];
}

注意: app 运行在后台时并不会走 APNS 推送,由个推服务器推送,我们要让 app在后台第一时间让个推 SDK 断线,先用 APNS 推送, app 进入前台重新激活 SDK, 如果由个推服务器推送 app 可以收到透传的消息,但不会在通知栏提示.

- (void)applicationDidEnterBackground:(UIApplication *)application {
///切后台关闭SDK,让SDK第一时间断线,让个推先用APN推送
[GeTuiSdk destroy];
} - (void)applicationWillEnterForeground:(UIApplication *)application { //设置角标为0 相当于复位
[GeTuiSdk setBadge:];
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:];//进入前台取消应用消息图标搜索
[[UIApplication sharedApplication] cancelAllLocalNotifications];
} - (void)applicationDidBecomeActive:(UIApplication *)application {
[DeviceDelegateHelper sharedInstance].preDate = [NSDate date];
/// 重新上线
[self startSdkWith:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret];
}

四.推送开关

关于推送开关的设置,我这里使用单例类属性接收,

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

在需要设置 UISwitch 开关的地方来设置

[pushBtn setOn:[DemoGlobalClass sharedInstance].isMessageShake];
- (void)getValue:(UISwitch*)sender
{
[GlobalData shareIntance].isMessagePush = sender.isOn;
NSLog(@"-----%d__--",!sender.isOn);
     //发送开关结果告诉个推服务器
[GeTuiSdk setPushModeForOff:!sender.isOn]; }

五.关于iOS icon 角标显示

角标的处理,其实个推 SDK 已经封装好了,iOS 前端只需要把收到推送的消息个数,已读全部通知,设置角标为0并且发送个推服务器,如有未读推送通知,把剩余的通知发送给个推服务器,我们服务器从个推服务器上获取角标,来设置推送的消息个数,并有我们服务器发送透传消息过来.

 //设置角标为0 相当于复位
[GeTuiSdk setBadge:];
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:];//进入前台取消应用消息图标搜索
[[UIApplication sharedApplication] cancelAllLocalNotifications];







ios 个推推送集成的更多相关文章

  1. iOS极光推送集成步骤

    1.下载SDK,导入Xcode 2.在苹果开发者中心建立AppId与bundleID进行关联,注意勾选推送功能 3.在苹果开发者中心建立推送证书 4.在极光后台建立应用且上传推送证书 5.建立描述文件 ...

  2. (转载)iOS 极光推送SDK 集成指南

    iOS SDK 集成指南 使用提示 本文匹配的 SDK版本:r1.2.5 以后. 查看最近更新了解最新的SDK更新情况. 产品功能说明 极光推送(JPush)是一个端到端的推送服务,使得服务器端消息能 ...

  3. 个推推送iOS版 常见问题详解

    原文:http://www.oschina.net/question/1782938_234760   1.提交了.p12文件后多久可以测试? 提交后10分钟左右才可以测试,并不是立即生效的.   2 ...

  4. 使用PushSharp给iOS应用推送消息

    PushSharp是一个C#编写的服务端类库,用于推送消息到各种客户端,支持iOS(iPhone/iPad).Android.Windows Phone.Windows 8.Amazo.Blackbe ...

  5. iOS图表库Charts集成与使用

    Charts是一个很优秀的图表库,它支持Android.iOS.tvOS和macOS,这样使用起来,可以节省学习成本,可以从GitHub上了解更多信息.本文记录在iOS项目上的集成与使用. Chart ...

  6. IOS远程推送

    IOS远程推送 一.关于推送通知 推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说 ...

  7. iOS 消息推送(APNs) 傻瓜式教程

    也可以去我的简书页面查看这篇文章 首先: 1.做iOS消息推送需要真机测试 2.做iOS消息推送需要有付费的开发者账号 是否继续看帖? 先学习一下相关的知识吧! 因为中途可能会遇到一些问题,这篇文章或 ...

  8. 给iOS开发新手送点福利,简述文本属性Attributes的用法

    给iOS开发新手送点福利,简述文本属性Attributes的用法   文本属性Attributes 1.NSKernAttributeName: @10 调整字句 kerning 字句调整 2.NSF ...

  9. iOS远程推送原理及实现过程

    ➠更多技术干货请戳:听云博客 推送通知,是现在的应用必不可少的功能.那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什么呢?在做 iOS 远程推送时,我们会遇到各种各样的问题 ...

随机推荐

  1. 自己动手系列——实现一个简单的ArrayList

    ArrayList是Java集合框架中一个经典的实现类.他比起常用的数组而言,明显的优点在于,可以随意的添加和删除元素而不需考虑数组的大小.处于练手的目的,实现一个简单的ArrayList,并且把实现 ...

  2. npm 不是内部命令

    最近办公室流行给电脑装win10系统,于是在重新装好电脑系统后,再次运行thinkjs项目的时候,就发现了之前做过的项目打不开了,待再确认问题出在哪里的时候,才发现”nodejs以及npm不是内部或者 ...

  3. TFS2010升级至TFS2013完全指南

    一.背景:         公司已使用tfs2010很长时间,目前随着公司的发展,项目越来越少,而产品越来越多,采用的开发模式,也逐渐从瀑布式.迭代式转向敏捷开发.为了更好的支持产品研发,决定将tfs ...

  4. iOS Storyboard适配问题

      通用的Storyboard 通用的stroyboard文件是通向自适应布局光明大道的第一步.在一个storyboard文件中适配iPad和iPhone的布局在iOS8中已不再是梦想.我们不必再为不 ...

  5. Github windows客户端简单上手教程

    作为一个前端,如果不知道GitHub,那你有可能就是一个假前端(O(∩_∩)O哈哈~)开个玩笑...进入正题,咳咳... 1.第一步要在GitHub官网下载最新的客户端,网址是https://desk ...

  6. Extjs 数据代理

    Ext.data.proxy.Proxy 代理类的根类 客户端代理: 1.LocalStorageProxy:将数据存储在localStorage中,此种方式可以持久的将数据存储在客户端 要使用代理, ...

  7. 用canvas的arc绘制时钟

    在页面上加入canvas标签: <body> <canvas id="c1" width="600px" height="600px ...

  8. TCP和UDP的"保护消息边界”

    转自:http://blog.csdn.net/zhangxinrun/article/details/6721427 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP ...

  9. 动态添加删除网卡 - 每天5分钟玩转 OpenStack(156)

    这是 OpenStack 实施经验分享系列的第 6 篇. 在项目实施过程中,经常会有添加删除网卡的需求.比如一个运行数据库的 instance,初始只有一个网卡,数据库服务和备份共用这块网卡,后来为提 ...

  10. 规范 : angular ui router path & params

    在seo文章中提到url的path 必须是 why-us,而不是whyUS 所以定了规范,所有的path 必须why-us path ?后尾的是用来filter的,所以可以WhyUs 如果是不需要给s ...