个推推送总结:
个推第三方平台官网地址:
首先去官网注册账号,创建应用,应用的配置信息,创建APNs推送证书上传 P12证书(开发对应开发证书,上线对应生产证书)包括导入 SDK 添加依赖库...这些繁琐的事请移步个推官网查看 xcode 集成教程.
一.推送的流程
个推 iOS 推送服务框架如下图所示:
绿色部分是 APNs 推送,个推平台替开发者的应用通过苹果 APNs 服务器向指定的目标设备进行推送。由 APNs Server 将通知推送到相应的 iOS 设备上。
红色部分是个推应用内推送部分,即 App 启动时,应用内集成的个推SDK会//代码效果参考:http://www.lyjsj.net.cn/wz/art_24115.html
开启长连接到个推服务器,从而开发者可通过个推服务器推送消息到 App 里,这条链路性能和稳定性更强,是APNs的一个很重要的补充。app 在收到推送消息时分为三种情况
1.app 在前台接收到通知
APP接收到推送后推送后首先弹出一个Alert提示是否跳转页面
2.app 在后台接收到通知
点击通知栏使APP进入前台后,直接跳转页面
点击icon图标使APP进入前台后,不作操作
3.app 处于关闭状态接收到通知
点击通知栏启动APP,直接跳转页面
点击icon图标启动APP,不作操作
二.iOS 集成个推只支持透传消息(透传消息并且支持安卓)
三.集成个推官网 SDK 配置AppID,AppKey,AppSecret
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 132, 0, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
span.s2 { font: 11px "PingFang SC"; font-variant-ligatures: no-common-ligatures }
p.p1 { margin: 0; font: 16px "Helvetica Neue"; color: rgba(47, 47, 47, 1); -webkit-text-stroke: #2f2f2f }
span.s1 { font-kerning: none }
首先为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:apntype】;
}
}
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 132, 0, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
span.s2 { font: 11px "PingFang SC"; font-variant-ligatures: no-common-ligatures }
p.p1 { margin: 0; font: 11px "PingFang SC"; color: rgba(0, 132, 0, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
【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】;
}
p.p1 { margin: 0; font: 11px "PingFang SC"; color: rgba(0, 132, 0, 1) }
span.s1 { font: 11px Menlo; font-variant-ligatures: no-common-ligatures }
span.s2 { font-variant-ligatures: no-common-ligatures }
/ 远程通知注册失败委托 /
- (void)application:(UIApplication )application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"---个推注册失败---");
//注册失败通知个推服务器
【GeTuiSdk registerDeviceToken:@""】;
}
p.p1 { margin: 0; font: 11px "PingFang SC"; color: rgba(0, 132, 0, 1) }
span.s1 { font: 11px Menlo; font-variant-ligatures: no-common-ligatures }
span.s2 { font-variant-ligatures: no-common-ligatures }
【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 = 0;
【GeTuiSdk setBadge:0】;
// 【 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;
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 132, 0, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
span.s2 { font: 11px "PingFang SC"; font-variant-ligatures: no-common-ligatures }
//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:0】;
【【UIApplication sharedApplication】 cancelAllLocalNotifications】;
NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo);
// 【 GTSdk 】:将收到的APNs信息传给个推统计
【GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo】;
completionHandler();
}
#endif
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 132, 0, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
//设置GeTuiSdkDelegate
注意 APP 启动成功会返回 clientId ,我们项目中使用clientId进行消息透传,在登录的时候将clientId传给我们自己的服务器,我们服务器根据clientId给用户进行推送
/ SDK启动成功返回cid /
- (void)GeTuiSdkDidRegisterClient:(NSString )clientId
{
// 【4-EXT-1】: 个推SDK已注册,返回clientId
NSLog(@"<span style="color: rgba(128, 0, 0, 1)"]]【GeTuiSdk RegisterClient】:----%@", clientId);
// 将clientId写入本地
【USER_DEFAULT setObject:clientId forKey:kPushClientId】;
}
/ SDK遇到错误回调 /
- (void)GeTuiSdkDidOccurError:(NSError )error
{
// 【EXT】:个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
NSLog(@"\n]【GTSdk error】:%@\n\n", 【error localizedDescription】);
}
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 132, 0, 1) }
span.s1 { font-variant-ligatures: no-common-ligatures }
span.s2 { font: 11px "PingFang SC"; font-variant-ligatures: no-common-ligatures }
/ SDK收到透传消息回调 */
/ SDK收到透传消息回调 /
- (void)GeTuiSdkDidReceivePayloadData:(NSData )payloadData andTaskId:(NSString )taskId andMsgId:(NSString )msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString )appId
{
// 汇报个推自定义事件
【GeTuiSdk sendFeedbackMessage:90001 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(1007);
}
// 控制台打印日志
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:0】;
【【UIApplication sharedApplication】setApplicationIconBadgeNumber:0】;//进入前台取消应用消息图标搜索
//代码效果参考:http://www.lyjsj.net.cn/wz/art_24113.html
【【UIApplication sharedApplication】 cancelAllLocalNotifications】;}
- (void)applicationDidBecomeActive:(UIApplication *)application {
【DeviceDelegateHelper sharedInstance】.preDate = 【NSDate date】;
/// 重新上线
【self startSdkWith:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret】;
}