一、关于推送
1、本地推送
只要用户允许了推送通知,并且通知提醒类型不为空,就可以进行本地推送。
2、远程推送
首先需要用户允许了推送通知,并且通知提醒类型不为空;其次需要注册远程推送,并将deviceToken上传给推送服务器,服务器配置好推送证书,App项目配置好推送权限文件,这样服务器才能推送消息到App。
二、iOS8~iOS10系统推送
- App位于后台或App未运行时,才能显示接收到的推送消息,如横幅提示、声音提示;App位于前台时不会显示接收到的推送消息。
- 推送消息一旦发出,不能修改消息内容。
- 本地推送数量上限为64个。
- 可以指定用户动作Actions,显示消息可以指定显示按钮、输入框。
1、本地推送
(1)注册推送
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
//要定制用户Action的话,可以设置categories
//注册,会触发权限请求
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
//注册完成代理方法
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {}
(2)创建通知
UILocalNotification *notification = [UILocalNotification new];
notification.alertBody = @"测试本地推送";
notification.applicationIconBadgeNumber = 66;
notification.userInfo = @{@"testdata":@"xxxxxxx"};
//定时推送
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];//5秒后推送
//定点推送,每次进入或离开指定位置区域时发送通知
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(30.5516493549,114.3165377299);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate radius:50 identifier:@"泛悦中心"];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
notification.region = region;
notification.regionTriggersOnce = NO;
//定期推送,立即触发通知,之后每天重复通知
notification.fireDate = nil;
notification.repeatCalendar = [NSCalendar currentCalendar];
notification.repeatInterval = NSCalendarUnitDay;
(3)推送通知
//按计划推送本地通知
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
//立即推送本地通知
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
(4)取消推送
[[UIApplication sharedApplication] cancelLocalNotification:notification];
(5)接收并处理推送
//App启动时处理本地推送消息
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification) {}
return YES;
}
//点击本地通知提示时,或App位于前台时,处理推送消息
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {}
(6)处理用户Action
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
NSLog(@"iOS8 处理用户定制的Actions:%@", notification.userInfo);
//处理完毕必须调用completionHandler
completionHandler();
}
2、远程推送
(1)注册推送
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
//触发权限请求
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
//注册远程推送
[[UIApplication sharedApplication] registerForRemoteNotifications];
(2)上传设备Token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"iOS8 远程推送注册完成,token:%@", deviceToken);
//TODO: 将token上传到自己的推送服务器上
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"iOS8 远程推送注册失败,error:%@", error);
}
(3)接收与处理推送消息
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"iOS10以下系统点击通知消息或App位于前台收到推送通知消息时执行该方法");
}
//如果实现了该方法,同时需要配置plist推送通知后台执行权限,同时上面的方法不再被调用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(@"iOS10以下系统点击通知消息或App位于前台收到推送通知消息时执行该方法");
}
三、iOS10及以上系统推送
- 推送内容更加丰富,可以设置title、subtitle、body、图片、音频、视频等附件
- 推送通知管理更好,可以查看、更新、删除通知
- 应用位于前台时也可以展示通知
1、本地推送
(1)注册推送
//需要引入系统头文件
#import <UserNotifications/UserNotifications.h>
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
UNAuthorizationOptions options = UNAuthorizationOptionBadge + UNAuthorizationOptionAlert + UNAuthorizationOptionSound;
//注册推送,同时请求系统权限
[center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
NSLog(@"granted:%@, error:%@", @(granted), error);
}];
(2)创建通知
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
content.title = @"测试iOS10定时推送本地通知";
content.subtitle = @"subTitle";
content.badge = @33;
content.body = @"test body";
content.sound = [UNNotificationSound defaultSound];
content.userInfo = @{@"testdata":@"xxxxx"};
//定时推送
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
UNNotificationRequest *request =[UNNotificationRequest requestWithIdentifier:@"testID" content:content trigger:trigger];
//定期推送
NSDateComponents *components = [NSDateComponents new];
components.weekday = 4;//每周三
components.hour = 20;//晚上8点
components.minute = 1;//1分
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
UNNotificationRequest *request =[UNNotificationRequest requestWithIdentifier:@"testID2" content:content trigger:trigger];
//定点推送
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(30.5516493549,114.3165377299);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate radius:50 identifier:@"泛悦中心"];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
UNLocationNotificationTrigger *trigger = [UNLocationNotificationTrigger triggerWithRegion:region repeats:YES];
UNNotificationRequest *request =[UNNotificationRequest requestWithIdentifier:@"testID3" content:content trigger:trigger];
(3)推送通知
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
NSLog(@"添加推送成功");
}];
(4)接收并处理通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
NSLog(@"iOS10 App位于前台时,接收到本地、远程推送时的处理");
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {} //远程推送
else {} //本地推送
UNNotificationPresentationOptions options = UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionBadge + UNNotificationPresentationOptionSound;
completionHandler(options);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
NSLog(@"iOS10 点击推送消息时处理推送消息");
if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {} //远程推送
else {} //本地推送
completionHandler();
}
2、远程推送
(1)注册
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;//设置该代理对象尽量在willFinishLaunchingWithOptions方法中,设置太晚可能无法及时处理通知消息
UNAuthorizationOptions options = UNAuthorizationOptionBadge + UNAuthorizationOptionAlert + UNAuthorizationOptionSound;
//请求指定推送设置的权限
[center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
NSLog(@"granted:%@, error:%@", @(granted), error);
//获得权限后注册远程推送通知
if (!error && granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
}];
(2)上传设备Token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"iOS10 远程推送注册完成,token:%@", deviceToken);
//TODO: 将token上传到自己的推送服务器上
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"iOS10 远程推送注册失败,error:%@", error);
}
(4)接收并处理通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
NSLog(@"iOS10 App位于前台时,接收到本地、远程推送时的处理");
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {} //远程推送
else {} //本地推送
UNNotificationPresentationOptions options = UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionBadge + UNNotificationPresentationOptionSound;
completionHandler(options);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
NSLog(@"iOS10 点击推送消息时处理推送消息");
if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {} //远程推送
else {} //本地推送
completionHandler();
}