iOS开发-极光远程推送

2017-01-14 10:03:12来源:http://www.jianshu.com/p/a6c8e2cb3c1b作者:看我的大白眼人点击


首先要在控制台创建应用,并上传iOS开发证书以及生产证书,不了解的可以看iOS SDK教程,官方有详细的介绍
下载官方的iOS SDK
导入API开发包到应用程序项目
将SDK包解压,在XCode中选择“Add files to 'Your project name'...”,将解压后的lib子文件夹(包含JPUSHService.h、jpush-ios-x.x.x.a)添加到你的工程目录中。

必要的框架


CFNetwork.framework
CoreFoundation.framework
CoreTelephony.framework
SystemConfiguration.framework
CoreGraphics.framework
Foundation.framework
UIKit.framework
Security.framework
Xcode7需要的是libz.tbd;Xcode7以下版本是libz.dylib
Adsupport.framework (获取IDFA需要;如果不使用IDFA,请不要添加)

Build Settings
如果你的工程需要支持小于7.0的iOS系统,请到Build Settings 关闭 bitCode 选项,否则将无法正常编译通过


设置 Search Paths 下的 User Header Search Paths 和 Library Search Paths,比如SDK文件夹(默认为lib)与工程文件在同一级目录下,则都设置为"$(SRCROOT)/{静态库所在文件夹名称}"即可

创建并配置PushConfig.plist文件(非必需)



我们可以在JPush-iOS-SDK的demo中把PushConfig.plist拖到自己的项目中



CHANNEL


指明应用程序包的下载渠道,为方便分渠道统计,具体值由你自行定义,如:App Store。

APP_KEY


填写管理Portal上创建应用后自动生成的AppKey值

APS_FOR_PRODUCTION


0 (默认值)表示采用的是开发证书,1 表示采用生产证书发布应用,此字段的值要与Build Settings的Code Signing配置的证书环境一致。




或者在AppDelegate中设置



static NSString *appKey = @"AppKey copied from JPush Portal application";
static NSString *channel = @"Publish channel";
static BOOL isProduction = FALSE;
//如不需要使用IDFA,advertisingIdentifier 可为nil
[JPUSHService setupWithOption:launchOptions appKey:appKey
channel:channel
apsForProduction:isProduction
advertisingIdentifier:advertisingId];

添加代码

如果用的是Xcode7时,需要在App项目的plist手动配置下key和值以支持http传输:


      <key>NSAppTransportSecurity</key> 
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

集成所需API
导入头文件
#import "JPUSHService.h"
#import <AdSupport/AdSupport.h>

初始化代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/// JPush
NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
//Required
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
}
else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
//可以添加自定义categories
[JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert)
categories:nil];
}
else {
//categories 必须为nil
[JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)
categories:nil];
}
//Required
// init Push(2.1.5版本的SDK新增的注册方法,改成可上报IDFA,如果没有使用IDFA直接传nil )
// 如需继续使用pushConfig.plist文件声明appKey等配置内容,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。
[JPUSHService setupWithOption:launchOptions appKey:appKey
channel:channel
apsForProduction:isProduction
advertisingIdentifier:advertisingId];
return YES;
}

注册APNs成功并上报DeviceToken
//  获取deviceToken的方法
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
/// Required - 注册 DeviceToken
[JPUSHService registerDeviceToken:deviceToken];
}

实现注册APNs失败接口(可选)
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}

添加处理APNs通知回调方法
//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];
}

测试



设置推送


查看推送情况


有时候推送会有延迟,延迟根据情况而定


消息类型

一条消息推送过来,可以有如下几种表现形式:


显示一个alter或者banner,展现具体内容
在应用icon上提示一个新到消息数
播放一段声音

开发者可以在每次推送的时候设置,在推送达到用户设备时开发者也可以选择不同的提示方式。


获取 APNs(通知) 推送内容

iOS 设备收到一条推送(APNs),用户点击推送通知打开应用时,应用程序根据状态不同进行处理需在 AppDelegate 中的以下两个方法中添加代码以获取apn内容


如果 App 状态为未运行,此函数将被调用,如果launchOptions包含UIApplicationLaunchOptionsRemoteNotificationKey表示用户点击apn 通知导致app被启动运行;如果不含有对应键值则表示 App 不是因点击apn而被启动,可能为直接点击icon被启动或其他。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; 
// apn 内容获取:
NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKe

如果远程消息发送过来的时候,app正在运行,app代理的application:didReceiveRemoteNotification:方法会被调用,同时远程消息中的payload数据会作为参数传递进去。
示例代码如下:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (application.applicationState == UIApplicationStateActive) {
// 转换成一个本地通知,显示到通知栏,你也可以直接显示出一个alertView,只是那样稍显aggressive
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.userInfo = userInfo;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
localNotification.fireDate = [NSDate date];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
} else {
// 其他处理
}
}

极光推送平台发出去的通知格式究竟是什么样子的

对于每一条推送消息,都包含一个payload,通常是组成了一个JSON的Dictionary,这其中必不可少的是aps属性,它对应的value也是一个Dictionary,包含下面一些内容:



alert消息(文本或Dictionary)



应用图标上的红色数字



播放的声音文件名
在极光推送的后台发送通知中,有可选设置,用于客户端自定义事件处理。



可选设置

我们可以添加一下字段 如:target,goods_id,这样客户端就知道跳到哪个转页面


应用该怎么响应推送消息

我们有时候希望带给用户更好的使用体验,譬如一个商城应用推送了一条商品降价的信息,如果用户点击进入了APP,我们应该展示具体的商品详情,而不是进入APP,让用户再去找降价的商品.


我们在这里以iOS10为例,因为手上没有iOS10一下的机型,暂时不能测试.


JPUSHRegisterDelegate
//MARK: iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
// Required
// APNs内容为userInfo
NSDictionary * userInfo = notification.request.content.userInfo;
//iOS10 前台收到远程通知
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
// 不能直接跳转页面
// [self goToMssageViewControllerWith: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;
//iOS10 收到远程通知
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
[self goToMssageViewControllerWith:userInfo];
}
completionHandler(); // 系统要求执行这个方法
}

跳转到相应的界面
// 跳转到相应的界面
- (void)goToMssageViewControllerWith:(NSDictionary*)msgDic {
NSUserDefaults *pushJudge = [NSUserDefaults standardUserDefaults];
[pushJudge setObject:@"push" forKey:@"push"];
[pushJudge synchronize];
NSString *targetStr = [msgDic objectForKey:@"target"];
//trasure 商品详情 activity 最新活动
if ([targetStr isEqualToString:@"trasure"]) {
ProductViewController *goodsDetail = [[ProductViewController alloc]init];
goodsDetail.good_id = msgDic[@"goods_id"];
MainNavigationController *nav = [[MainNavigationController alloc]initWithRootViewController:goodsDetail];;
[self.window.rootViewController presentViewController:nav animated:YES completion:nil];
}else if ([targetStr isEqualToString:@"activity"]) {

};
}

商品详情(ProductViewController)的处理
// 添加如下代码
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
if ([[MyNSUD objectForKey:@"push"] isEqualToString:@"push"]) {
// 自定义返回按钮
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
[btn setImage:[UIImage imageNamed:@"jiantou"] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(rebackToRootViewAction) forControlEvents:UIControlEventTouchUpInside];
[btn sizeToFit];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
}else {
self.navigationItem.leftBarButtonItem=nil;
}
}
- (void)rebackToRootViewAction {
[MyNSUD removeObjectForKey:@"push"];
[MyNSUD synchronize];
[self dismissViewControllerAnimated:YES completion:nil];
}

参考资料


细说 iOS 消息推送


iOS极光推送 点击推送消息跳转页面





最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台