说到远程推基本上任何一个app都会用到,下面就说一下关于iOS远程推送的一些需要做的事情.
1.配置证书.
(1).首先要有一个开发者账号,不明白的可以去参考://www.greatytc.com/p/0915bb139a2a.
(2).登录开发者账号创建一个有远程推送的appID
3.下一步就是要配置证书了.
首先打开我们电脑的钥匙串.
接下来回到appleDevloper
将根证书导入,然后生成开发者证书
下载下来双击放入钥匙串,然后配置apns证书.这些都很简单.
(3).需要说的是,下载之后双击导入证书,这些证书都是基于根证书的.导入后可以把开发者证书.倒成一个p12证书.在钥匙串中右击需要的开发者证书.
需要提醒的是导出p12的时候记得自己的密码,后台和他人使用是需要的密码的.
2.接下来的就是配置xcode.
3.好了接下来就是要上代码了
在appDelegate didFinishlanch中:
if ([[UIDevice currentDevice].systemVersion floatValue]<8.0) {
UIRemoteNotificationType type = UIUserNotificationTypeSound|UIUserNotificationTypeBadge|UIUserNotificationTypeAlert;
[application registerForRemoteNotificationTypes:type];
}
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound|UIUserNotificationTypeBadge|UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
注册通知之后,苹果会将DeviceToken通过代理方法的形式返回相应的代理方法。这个代理方法会将手机的UDID + 应用程序的Bundle ID发送给苹果,苹果进行某种编码之后再通过代理方法返回,deviceToken = (手机的UDID + 应用程序的Bundle ID) 苹果编码,返回的deviceToken是NSData类型的.(注意注册时要有网!!!);
//此方法会返回DeviceToken数据为二进制,解析一下即可
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
}
//此方法是受到本地通知时回调用
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
}
//此方法是受到远程通知时回调用(ios8之前用)
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
}
//此方法是受到远程通知时回调用(ios8之后用)
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
}
记得要执行一下尾部的BLOCK,执行completionHandler有两个目的:
1系统会估量App消耗的电量,并根据传递的UIBackgroundFetchResult 参数记录新数据是否可用
2调用完成的处理代码时,应用的界面缩略图会自动更新
注意:接收到远程通知到执行完网络请求之间的时间不能超过30秒
4:第三方比如极光为例
之前用过极光,用起来是比较方便的,当然证书的配置还是不能省略的.(记得他要配置ats,)
<1>.倒入项目.
选择1:Cocoapods导入
通过Cocoapods下载地址:
pod 'JPush'
如果需要安装指定版本则使用以下方式(以3.0.2版本为例):
pod 'JPush', '3.0.2'
选择2:手动导入
在极光官网下载最新SDK
将SDK包解压,在Xcode中选择“Add files to 'Your project name'...”,将解压后的lib子文件夹(包含JPUSHService.h、jpush-ios-x.x.x.a、jcore-ios-x.x.x.a)添加到你的工程目录中。
添加Framework
CFNetwork.framework
CoreFoundation.framework
CoreTelephony.framework
SystemConfiguration.framework
CoreGraphics.framework
Foundation.framework
UIKit.framework
Security.framework
libz.tbd (Xcode7以下版本是libz.dylib)
AdSupport.framework (获取IDFA需要;如果不使用IDFA,请不要添加)
UserNotifications.framework (Xcode8及以上)
libresolv.tbd (JPush 2.2.0及以上版本需要, Xcode7以下版本是libresolv.dylib)
注意: 如果集成JPush 3.0.1及以上版本, 且同时集成极光其他SDK(如:JMessage 3.0.0及以上版本)
1. Cocoapods导入,建议都更新为线上最新版本,来避免Jcore版本不一致导致的冲突。
2. 手动导入,在工程中只需保留一个最新版本的jcore-ios-x.x.x.a静态库文件。
<2>.添加初始化APNs代码.
请将以下代码添加到
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
//Required
//notice: 3.0.0及以后版本注册可以这样写,也可以继续用之前的注册方式
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
// 可以添加自定义categories
// NSSet *categories for iOS10 or later
// NSSet *categories for iOS8 and iOS9
}
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
添加初始化JPush代码
请将以下代码添加到
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Optional
// 获取IDFA
// 如需使用IDFA功能请添加此代码并在初始化方法的advertisingIdentifier参数中填写对应值
NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
// Required
// init Push
// notice: 2.1.5版本的SDK新增的注册方法,改成可上报IDFA,如果没有使用IDFA直接传nil
关于appKey如果确定用极光做推送,要把p12证书给后台让后台注册极光给你appKEY就行了
// 如需继续使用pushConfig.plist文件声明appKey等配置内容,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。
[JPUSHService setupWithOption:launchOptions appKey:appKey
channel:channel
apsForProduction:isProduction
advertisingIdentifier:advertisingId];
注册APNs成功并上报DeviceToken
请在AppDelegate.m实现该回调方法并添加回调方法中的代码
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
/// Required - 注册 DeviceToken
[JPUSHService registerDeviceToken:deviceToken];
}
实现注册APNs失败接口(可选)
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
//Optional
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
添加处理APNs通知回调方法
请在AppDelegate.m实现该回调方法并添加回调方法中的代码
#pragma mark- 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];
}
所有的第三方都可以先下载一个demo试一下就明白了.个人觉得极光有时候还是很不给力的经常会出现丢失推送的问题,至于为什么呢?想来想去钱没给到,用免费的推送肯定没有vip的通道快,免费的用的人多会堵塞.
5.用scoket来做远程推送
本人做过的项目包含这种的推送.
大家如果接过即时通讯就会知道,环信的消息提示的时候就是当消息过来的时候,发一个本地的通知,然后我们把消息的内容做出来.
所以原理相同,类似于一个IM,说白了就是一个IM的东西,用心跳包保持一个与服务器的长连接,服务器可以直接群发消息就形成了一个推送.中间的道理并不难,我们拿到消息有很多种处理的方法,最合理的就是当收到消息就要做一个本地的保存,免得会出现IM没走服务器,当然个人建议还是用APns,这东西稳定一些,有条件的公司自己封装一下还是会好很多.