必知的技术知识:ios个推推送集成

简介: 必知的技术知识:ios个推推送集成

个推推送总结:


个推第三方平台官网地址:


首先去官网注册账号,创建应用,应用的配置信息,创建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】;


}


相关文章
|
6天前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
【6月更文挑战第23天】Java Web开发中,Servlet和JSP是构建动态Web应用的基础。Servlet处理逻辑,JSP专注展示。示例展示了Servlet如何通过`request.setAttribute`传递数据给JSP渲染。JSP自定义标签提升页面功能,如创建`WelcomeTag`显示欢迎消息。Servlet过滤器,如`CacheControlFilter`,用于预处理数据或调整响应头。这些集成和扩展技术增强了应用效率、安全性和可维护性,是Java服务器端开发的关键。
|
4天前
|
消息中间件 搜索推荐 中间件
企业门户:信息与应用的集成技术探讨
【6月更文挑战第25天】企业门户是整合内外信息与应用的关键平台,它连接企业各方并提供个性化服务。通过数据、应用和业务流程集成,实现数据共享、效率提升及成本优化。界面、控制及消息集成确保用户体验一致性与系统协同。企业门户增强竞争力,降低运营成本,是信息化建设的核心。
|
1天前
|
传感器 安全 物联网
物联网(IoT)设备的硬件选型与集成技术博文
【6月更文挑战第28天】物联网设备硬件选型与集成聚焦关键要素:功能匹配、性能稳定性、兼容扩展及成本效益。嵌入式系统、通信协议、数据处理和安全性技术确保集成效果,支撑高效、智能的IoT系统,驱动家居、城市与工业自动化变革。
|
4天前
|
监控 安全 搜索推荐
企业应用集成(EAI):连接企业系统的技术探索
【6月更文挑战第25天】企业应用集成(EAI)技术连接异构系统,实现数据共享和业务流程优化。EAI包括界面、业务过程、应用和数据集成,提升协同效率、降低成本、改善客户体验、支持创新及强化风险管控。实施涉及规划、需求分析、选择方案、开发测试、部署监控及维护优化。EAI在企业信息化中扮演关键角色。
|
3天前
|
iOS开发
技术好文:xcode动态图,ios实现动态图,iosgif,暂停和继续播放
技术好文:xcode动态图,ios实现动态图,iosgif,暂停和继续播放
|
13天前
|
人工智能 数据安全/隐私保护 iOS开发
苹果在WWDC24上宣布的所有内容:Apple Intelligence、集成ChatGPT的Siri、iOS 18
苹果在WWDC24上宣布的所有内容:Apple Intelligence、集成ChatGPT的Siri、iOS 18
|
1天前
|
jenkins 持续交付 开发工具
高德引擎构建及持续集成技术演进之路
高德引擎构建及持续集成技术演进之路
|
2天前
|
存储
技术经验分享:iOS_MJRefrash的详解以及使用
技术经验分享:iOS_MJRefrash的详解以及使用
|
2天前
|
安全 Java API
技术笔记:SpringBoot集成Swagger3.0(详细)
技术笔记:SpringBoot集成Swagger3.0(详细)
|
1月前
|
物联网 测试技术 持续交付
探索自动化测试在持续集成中的关键作用未来技术纵横谈:区块链、物联网与虚拟现实的融合革新
【5月更文挑战第27天】随着敏捷开发和持续集成(CI)的广泛采用,自动化测试已成为确保软件质量和快速交付的基石。本文将探讨自动化测试在持续集成流程中的核心地位,分析其如何提高测试效率、降低错误率,并支持快速的迭代开发。通过实例和数据支持,我们将深入理解自动化测试对于现代软件开发实践的重要性,并讨论实施自动化测试时面临的挑战及解决策略。