iOS 推送通知

苹果通知简介

通知的种类:

  • 通知设计模式(NSNotification)
  • 本地通知(UILocalNotification)
  • 远程通知(APNs)

通知设计模式:

——是一种设计模式,是一种设计思想,是抽象的,推送通知(本地和远程)是肉眼可以看到的,是有界面的。

本地推送通知:

——本地通知不需要连接网络,一般是开发人员在合适的情况下在App内发送通知,应用场景:当能够确定在某个时间时需要提醒用户。

远程通知:

—— 所有苹果设备在联网状态下都会与苹果服务器建立长连接,连接是双向的,苹果设备可以向苹果服务器发送请求,苹果服务器也可以向苹果设备发送请求,一般是服务器端发送通知,远程推送服务又称为APNs(Apple Push Notification Services).

苹果服务器常用的通知功能:

  • 时间校准
  • 系统升级
  • 查找我的iPhone

长连接的好处:更加及时

对于用户,通知一般是指的推送通知,即本地推送通知和远程推送通知,App退到前台、后台或者完全退出都可接受

本地和远程通知对应的效果:

  • 在主屏幕的顶端会出现通知消息
  • 当手机锁屏时出现在锁屏界面,可以通过滑动打开该App,
  • 在通知中心中出现推送的消息
  • App图标会有微标值① badgeValue
  • 推送通知提示音

注意:
发送通知时,如果程序正在前台允许,那么推送通知UI就不会显示出来;点击通知系统默认会打开该App。

20161014132109865.png
20161014132131551.png
20161014132200817.png
20161014132200817.png

通知的使用场景:

  • 一些任务管理App,会在任务时间即将到达时,通知你该做任务了。如:提醒事项App、 电影App:电影即将开始提示用户按时到达影院。
  • 聊天App:程序退出到后台或者完全退出时收到消息
  • 电商App:推荐新品时
  • 新闻App:推送新闻

知识准备

//推送通知的代理类是: AppDelegate

//启动选项参数:当程序是通过点击应用程序图标时该参数是nil,当应用程序完全退出时,点击推送通知时该参数不为空,key为UIApplicationLaunchOptionsLocalNotificationKey

 - (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions{
}

通常当用户点击通知时会做一些业务处理,如QQ在前台状态下会将提醒数字+1, 当应用程序在后台状态或完全退出状态下会打开对应的聊天窗口

通知详解

本地通知的基本使用

#import "ViewController.h"  
@interface  ViewController ()
@end 
@implementation  ViewController 
- (void)viewDidLoad {
 [super viewDidLoad];
 } // 简单实例:点击通知进入App 
- (IBAction)postLocalNotification:(id)sender 
{ 
UILocalNotification *localNotification = [[UILocalNotification alloc] init]; 
localNotification.alertBody = @"hello, 你好啊!- alertBody + fireDate";
 localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3]; // 3秒钟后  //--------------------可选属性------------------------------ 
 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.2) { 
localNotification.alertTitle = @"推送通知提示标题:alertTitle"; // iOS8.2 
} 
// 锁屏时在推送消息的最下方显示设置的提示字符串 localNotification.alertAction = @"点击查看消息"; 
// 当点击推送通知消息时,首先显示启动图片,然后再打开App, 默认是直接打开App的 
localNotification.alertLaunchImage = @"LaunchImage.png";
 // 默认是没有任何声音的 UILocalNotificationDefaultSoundName:声音类似于震动的声音
 localNotification.soundName = UILocalNotificationDefaultSoundName; 
// 传递参数 localNotification.userInfo = @{@"type": @"1"};
 //重复间隔:类似于定时器,每隔一段时间就发送通知 
 // localNotification.repeatInterval = kCFCalendarUnitSecond; localNotification.category = @"choose"; // 附加操作  // 定时发送 [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
 NSInteger applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1; [[UIApplication sharedApplication]setApplicationIconBadgeNumber:applicationIconBadgeNumber]; // 立即发送
  // [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; } 
// 示例1:简单示例:点击通知进入App 
 //- (IBAction)postLocalNotification:(id)sender {  // UILocalNotification *localNotification = [[UILocalNotification alloc] init];  
// localNotification.alertBody = @"hello, 你好啊!- alertBody + fireDate"; 
 // localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; // 5秒钟后 //
 // [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];  //
}
  @end

#import "AppDelegate.h" 
 #import "AppDelegate+PrivateMethod.h" 
 @interface  AppDelegate () 
@end 
 @implementation  AppDelegate
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
// Override point for customization after application launch. 
 if (launchOptions != nil) {
 UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
 if (localNotification != nil) {
 // 程序完全退出状态下,点击推送通知后的业务处理  // 如QQ会打开想对应的聊天窗口  NSInteger applicationIconBadgeNumber = application.applicationIconBadgeNumber - 1; 
application.applicationIconBadgeNumber = applicationIconBadgeNumber >= 0 ? applicationIconBadgeNumber : 0; } 
} 
[self registerUserNotificationSettingsForIOS80]; 
return  YES; 
} 
// 当App在前台状态下,如果有通知会调用该方法  // 当应用程序在后台状态下,点击推送通知,程序从后台进入前台后,会调用该方法(从锁屏界面点击推送通知从后台进入前台也会执行)  // 当应用程序完全退出时不调用该方法 
- (void)application:(UIApplication *)application didReceiveLocalNotification:(nonnull UILocalNotification *)notification { 
NSLog(@"%@", notification); 
// 处理点击通知后对应的业务 
UIApplicationState applicationState = [[UIApplication sharedApplication] applicationState]; 
if (applicationState == UIApplicationStateActive) {
 // 前台  // 例如QQ会增加tabBar上的badgeValue未读数量 
}
 else  if (applicationState == UIApplicationStateInactive) {
// 从前台进入后台  // 例如QQ会打开对应的聊天窗口  
NSInteger applicationIconBadgeNumber = application.applicationIconBadgeNumber - 1; application.applicationIconBadgeNumber = applicationIconBadgeNumber >= 0 ? applicationIconBadgeNumber : 0;
 } 
   [application cancelLocalNotification:notification];
 }
 // 监听附加操作按钮
 - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification completionHandler:(nonnull void (^)())completionHandler { 
NSLog(@"identifier:%@", identifier); 
completionHandler();
 } 
// 该方法在iOS9.0后调用,iOS9.0之前调用上面那个方法
 - (void)application:(UIApplication *)app handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification withResponseInfo:(nonnull NSDictionary *)responseInfo completionHandler:(nonnull void (^)())completionHandler { 
// ====identifier:no, content:
{
UIUserNotificationActionResponseTypedTextKey = "not agree";
}  
NSLog(@"====identifier:%@, content:%@", identifier, responseInfo);
completionHandler(); 
} 
@end
#import "AppDelegate.h" 
 @interface  AppDelegate (PrivateMethod)
 - (void)registerUserNotificationSettingsForIOS80; 
@end 
 #import "AppDelegate+PrivateMethod.h" 
@implementation  AppDelegate (PrivateMethod) 
- (void)registerUserNotificationSettingsForIOS80
 { // iOS8.0 适配 
 if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) 
{ // categories: 推送消息的附加操作,可以为nil,此时值显示消息,如果不为空,可以在推送消息的后面增加几个按钮(如同意、不同意)
 UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init]; 
category.identifier = @"choose"; // 同意 UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
 action1.identifier = @"yes";
 action1.title = @"同意"; 
action1.activationMode =UIUserNotificationActivationModeForeground; // 点击按钮是否进入前台 
action1.authenticationRequired = true; 
action1.destructive = false; // 不同意 UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
 action2.identifier = @"no"; action2.title = @"不同意"; action2.activationMode=UIUserNotificationActivationModeBackground; // 后台模式,点击了按钮就完了 
action2.authenticationRequired = true; 
action2.destructive = true; 
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) { action2.behavior = UIUserNotificationActionBehaviorTextInput; 
action2.parameters=@{UIUserNotificationTextInputActionButtonTitleKey: @"拒绝原因"};
 }
 [category setActions:@[action1, action2] forContext:UIUserNotificationActionContextDefault]; 
NSSet<UIUserNotificationCategory *> *categories = [NSSet setWithObjects:category, nil];
 UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; 
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
 [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; 
}
 }
 @end

运行效果:

20161015175742775.png
20161015175654182.png
20161015175703885.jpeg
20161015175722698.png
20161015175731745.jpeg
20161015202305154.jpeg
20161015202524671.png

远程通知

远程通知逻辑过程:


例如微信App:首先每个联网并打开微信的App都与微信服务器有一个长连接,当微信A用户向微信B用户发送一个消息时,微信A用户将消息发送到微信服务器,然后微信服务器判断微信B用户是否和微信服务器建立了长连接,如果有直接通过微信B用户和微信服务器建立的连接管道直接发送即可,这样微信B用户就能收到消息;如果微信B用户此时没有打开微信App,那么微信服务器就将消息发送给苹果服务器,苹果服务器再讲消息发送到某台苹果设备上。苹果是怎么知道该发送给那台设备呢?用户A发送消息时需要将用户B的UDID和微信App的Bundle ID 附带在消息上一块发送给B用户,这些消息微信服务器又发送给苹果服务器,苹果服务器通过UDID就知道发送给那台设备了,然后通过Bundle ID就知道是哪个App发送的了。苹果根据UDID + Bundle ID 生成一个deviceToken, 这样每条微信消息中都加上deviceToken苹果服务器就能识别设备和App了。


例如 微信A用户发送消息:{“to”:”1234567”, “msg”:”hello”} ——-》微信服务器{“deviceToken”:”RSFWERWR23L342JOI2NLMO2H4”, “to”:”1234567”, “msg”:”hello”} —–》APNs服务器 ——》微信B用户

总结

  • 请求苹果服务器获取deviceToken
  • 发送deviceToken给App的服务器
  • 监听用户点击远程推送通知的行为

创建通知证书:

  • 创建真机调试证书并配置推送证书文件:apns_development.cer和描述文件

  • 首先创建真机证书、AppIDs(要选择Push Notifications), AppIDs创建完后可以看到状态是Configurable,是黄色的圆点,此时还不能使用推送通知,还要继续配置一下,选择Edit–>Push Notifications—> Create Certificate(创建推送通知证书),当证书创建完成后,可以看到AppID中的状态就变成了绿色的圆点(可用状态)

20161017103923023.png
20161017103932601.png
20161017103940867.png
20161017103950086.png
20161017104000430.png
20161017104009836.png
20161017104706344.png
20161017104714516.png
20161017112302407.png

当配置App IDs时需要选择Push Notifications,然后Edit,Create Certificate(创建证书),然后闯将证书选择Apple Push Notification servide SSL(Sandbox)

远程通知项目配置

相对简单的推送证书以及环境的问题,我就不在这里讲啦,我在这里说的,是指原有工程的适配。

  • 首先我们需要打开下面的开关。所有的推送平台,不管是极光还是什么的,要想收到推送,这个是必须打开的哟~
1124181-97ad5cdef86bbfe2.jpeg
QQ20160918-2.png
  • 之后,系统会生成一个我们以前没见过的文件,如图:
QQ20160918-0.png

可能产生的问题:之前有朋友反馈过,将开发环境由 development 变成 production ,在开关这里会产生错误,如图:

QQ20160918-1.png

如果大家点击Fix issue之后,会惊奇的发现,APS Environment由 production 又变成 development 了。

解决办法:我的建议是不做任何修改。

经过我的测试,打包之后,生成的ipa包内,是没有这个.entitlements 文件的。经过测试,我发现是可以正常收到推送信息的。测试的方法如下,大家也可以测试一下。

  • 测试方法:打包之后安装ipa文件,然后利用极光推送,选择生产环境,推送,即可。(也可用用原生推送)

经过上面的操作,你就会惊奇的发现,推送已经适配完毕了,iOS10的系统,已经可以正常接收通知了。

远程推送通知代码集成

一:系统自带方法推送通知

大家不管是使用三方平台的推送,还是系统自带的推送,都先应该了解下系统自带方法,如何实现远程通知的实现。

  • 第一步
    导入#import <UserNotifications/UserNotifications.h>且要遵守<UNUserNotificationCenterDelegate>的协议,在Appdelegate.m中。
    这里需要注意,我们最好写成这种形式
#ifdef NSFoundationVersionNumber_iOS_9_x_Max #import <UserNotifications/UserNotifications.h> #endif
  • 第二步
    我们需要在 -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中注册通知,代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 程序完全退出,点击通知[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]有值.
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
// 处理程序完全退出时,点击推送通知
if (dictionary != nil) {
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
textView.text = dictionary.description;
[self.window.rootViewController.view addSubview:textView];
}
 if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
 //iOS10特有
 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; 
// 必须写代理,不然无法监听通知的接收与点击
 center.delegate = self;
 [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
 if (granted) { 
// 点击允许 
NSLog(@"注册成功");
 [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
 NSLog(@"%@", settings);
}]; 
} else { // 点击不允许 
NSLog(@"注册失败"); 
} }]; }else if (
[[UIDevice currentDevice].systemVersion floatValue] >8.0){ 
//iOS8 - iOS10 
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
 }else if (
[[UIDevice currentDevice].systemVersion floatValue] < 8.0) { 
//iOS8系统以下
 [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; } 
// 注册获得device Token
 [[UIApplication sharedApplication] registerForRemoteNotifications];//其中,获得Device Token的方法是没有改变的。

// 获得Device Token
 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
 NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
 } 
// 获得Device Token失败
 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
 }

此次iOS10系统的更新,苹果给了我们2个代理方法来处理通知的接收和点击事件,这两个方法在<UNUserNotificationCenterDelegate>的协议中,大家可以查看下。此外,苹果把本地通知跟远程通知合二为一。区分本地通知跟远程通知的类是UNPushNotificationTrigger.h类中,UNPushNotificationTrigger的类型是新增加的,通过它,我们可以得到一些通知的触发条件,在使用时,我们不应该直接使用这个类,应当使用它的子类。

我简单点说

  • UNPushNotificationTrigger (远程通知) 远程推送的通知类型
  • UNTimeIntervalNotificationTrigger (本地通知) 一定时间之后,重复或者不重复推送通知。我们可以设置timeInterval(时间间隔)和repeats(是否重复)。
  • UNCalendarNotificationTrigger(本地通知) 一定日期之后,重复或者不重复推送通知 例如,你每天8点推送一个通知,只要dateComponents为8,如果你想每天8点都推送这个通知,只要repeats为YES就可以了。
  • UNLocationNotificationTrigger (本地通知)地理位置的一种通知,

当用户进入或离开一个地理区域来通知。在CLRegion标识符必须是唯一的。因为如果相同的标识符来标识不同区域的UNNotificationRequests,会导致不确定的行为。

接收通知的代码如下:

// iOS 10收到通知
 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
 NSDictionary * userInfo = notification.request.content.userInfo; 
UNNotificationRequest *request = notification.request; // 收到推送的请求
 UNNotificationContent *content = request.content; // 收到推送的消息内容
 NSNumber *badge = content.badge; // 推送消息的角标 
NSString *body = content.body; // 推送消息体 
UNNotificationSound *sound = content.sound; // 推送消息的声音 
NSString *subtitle = content.subtitle; // 推送消息的副标题 
NSString *title = content.title; // 推送消息的标题 
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
 NSLog(@"iOS10 前台收到远程通知:%@", [self logDic:userInfo]); 
} else {
 // 判断为本地通知 
NSLog(@"iOS10 前台收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo); 
}
 completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
 }

//下面的代码则是通知的点击事件:

// 通知的点击事件
 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{ 
NSDictionary * userInfo = response.notification.request.content.userInfo; 
UNNotificationRequest *request = response.notification.request; // 收到推送的请求 
UNNotificationContent *content = request.content; // 收到推送的消息内容
 NSNumber *badge = content.badge; // 推送消息的角标 
NSString *body = content.body; // 推送消息体
 UNNotificationSound *sound = content.sound; // 推送消息的声音 
NSString *subtitle = content.subtitle; // 推送消息的副标题
 NSString *title = content.title; // 推送消息的标题 
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
 NSLog(@"iOS10 收到远程通知:%@", [self logDic:userInfo]);
 } else { 
// 判断为本地通知
 NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
 } 
# Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called. 

completionHandler(); // 系统要求执行这个方法
}
//在点击事件中,如果我们不写completionHandler()这个方法,可能会报一下的错误,希望大家注意下~

# Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.

//最后最后,我们要大家补充一下,旧版本的一些方法,方便大家扩充iOS10的通知的通知,不影响原有逻辑。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { 
NSLog(@"iOS6及以下系统,收到通知:%@", [self logDic:userInfo]); 
} 
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler: (void (^)(UIBackgroundFetchResult))completionHandler {
 NSLog(@"iOS7及以上系统,收到通知:%@", [self logDic:userInfo]); 
completionHandler(UIBackgroundFetchResultNewData);
 }

二.极光推送(需要下载最新的版本)

如果用到三方的一些平台,做推送就会更为简单。

1.注册通知的代码如下

if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { 
#ifdef NSFoundationVersionNumber_iOS_9_x_Max JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init]; 
entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound; 
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
 #endif 
} 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];
 }

注册完成之后,我们则需要加入极光推送更新后,新加入的2个方法,这两个方法在<JPUSHRegisterDelegate>代理方法中。

/* 进入前台接受通知方法 @brief handle UserNotifications.framework [willPresentNotification:withCompletionHandler:] * @param center [UNUserNotificationCenter currentNotificationCenter] 新特性用户通知中心 * @param notification 前台得到的的通知对象 * @param completionHandler 该callback中的options 请使用UNNotificationPresentationOptions */ 
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger options))completionHandler{
}
 /* 点击通知启动app的方法@brief handle UserNotifications.framework [didReceiveNotificationResponse:withCompletionHandler:] * @param center [UNUserNotificationCenter currentNotificationCenter] 新特性用户通知中心 * @param response 通知响应对象 * @param completionHandler */
 - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
}

使用时,只需要在上面的代码中添加极光的处理方法就可以了,具体使用如下:

if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { 
// 这个方法,不管是收到通知代理还是点击通知的代理,如果使用极光推送,我们都是需要增加这个方法的。
 [JPUSHService handleRemoteNotification:userInfo]; NSLog(@"iOS10 收到远程通知:%@", [self logDic:userInfo]); 
[rootViewController addNotificationCount]; 
}else {
 // 判断为本地通知 
NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo); 
}

管理用户通知消息,通过给用户设置别名达到给用户分组。

//设置别名 
-(void)setAlias:(NSString*)alia{
    [JPUSHService setAlias:alia completion:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
        NSLog(@"%@",iAlias);
        if (iResCode == 0) {
            NSLog(@"添加别名成功");
        }
    } seq:1];
}

//移除别名
-(void)deleteAliassetAlias:(NSString*)alia{
    [JPUSHService deleteAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
        if (iResCode == 0) {
            NSLog(@"删除别名成功");
        }
    } seq:1];
}

通过上面的文章,相信大家已经可以初步了解新版本的推送,要如何处理啦~

参考:https://www.jianshu.com/p/bb89d636f989

激光推送有对应的后台发通知测试……

参考

远程推送通知测试

使用PushMeBaby(只能测试development版,hod没法测试,根据服务器代码通知地址都分沙盒测试版生产版本,证书也分开发证书和发布证书,当然你也可以改PushMeBaby的源码,把苹果服务器测试地址换成发布地址即可gateway.sandbox.push.apple.com沙盒,gateway.push.apple.com发布,当然deviceToken是和配置文件有关的,所以只要更换配置文件deviceToken就会变)

IOS PushMeBaby(是一款用来测试ANPs的开源Mac项目)

介绍

● PushMeBaby是一款用来测试ANPs的开源Mac项目

● 它充当了服务器的作用,用法非常简单

● 它负责将内容提交给苹果的APNs服务器,苹果的APNs服务器再将内容推送给用户 的设备

496841-20170519165914541-354158652.png

● PushMeBaby的主页

https://github.com/stefanhafeneger/PushMeBaby

PushMeBaby的使用步骤

  • 注释掉不要的错误
496841-20170519170132228-1561437942.png

● 填写必要信息

● deviceToken:用于找到设备的令牌

● payload:推送的内容

496841-20170519170230322-981425497.png

将真机调试的推送证书改为名apns.cer,添加到PushMeBaby项目中

496841-20170519170324822-380305088.png

● command + R启动程序,然后点击Push

● 接下来就可以在设备上接收到远程推送通知

496841-20170519170443307-1834448179.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容