iOS10之前本地推送
- 本地推送不需要借助服务器,即可实现推送功能。
- 这个时候需要借助
UILocalNotification
类进行功能实现 - 创建本地推送代码实现
// 创建本地推送
- (void)creatLocalPush{
UILocalNotification *localNotifi = [[UILocalNotification alloc]init];
// 设置触发时间
localNotifi.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
// 设置时区 以当前手机运行的时区为准
localNotifi.timeZone = [NSTimeZone defaultTimeZone];
// 设置推送 显示的内容
localNotifi.alertTitle = @"推送标题";
localNotifi.alertBody = @"本地推送内容";
localNotifi.alertAction = @"alert提示框按钮文本";
//是否显示额外的按钮,为no时alertAction消失
localNotifi.hasAction = YES;
// 设置 icon小红点个数
localNotifi.applicationIconBadgeNumber = 1;
// 设置是否重复 重复最小时间间隔为秒,但最好是分钟
// 不设置此属性,则默认不重复
localNotifi.repeatInterval = NSCalendarUnitMinute;
// 设置推送的声音
// 通知的声音默认是iOS系统自带的声音,当然也支持自定义,但是自定义必须是固定格式的音频文件,不支持mp3,最常用的是cef/pcm/ma4/alaw格式的音频文件,并且播放时间不能长于30秒,如果长于30秒,将会被系统时间所代替,音频文件必须放在工程文件当中([NSBundle mainBundle])
localNotifi.soundName = UILocalNotificationDefaultSoundName;
// 设置推送的区别符
localNotifi.userInfo = @{@"name":@"loaclPushOne"};
// 按照前面设置的计划 执行此通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNotifi];
}
- 取消指定本地推送代码实现
// 关闭本地推送
- (void)deleteLocalPush{
// 获取该app上所有的本地推送
NSArray *allLocalNotifi = [[UIApplication sharedApplication] scheduledLocalNotifications];
// 取消特定的本地推送
UILocalNotification *localNotifi = nil;
for (UILocalNotification *item in allLocalNotifi) {
NSDictionary *userInfo = item.userInfo;
if ([[userInfo objectForKey:@"name"] isEqualToString:@"loaclPushOne"]) {
localNotifi = item;
break;
}
}
[[UIApplication sharedApplication] cancelLocalNotification:localNotifi];
}
- 取消所有的本地推送
[[UIApplication sharedApplication] cancelAllLocalNotifications];
- 点击本地推送通知 进入APP后的回调
#pragma mark - LocalPush
// 点击本地推送通知 进入APP后的回调 在iOS10之后将会 分成两个方法回调
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
[application cancelLocalNotification:notification];
}
iOS10之后本地推送
- 本地通知也需要在
appdelegate
中注册。
通知内容
- 通知内容有可变和不可变之分
UNNotificationContent(不可变)、UNMutableNotificationContent(可变)
,后续我们通过某一特定标识符更新通知,便是用可变通知了。 - 不管是可变通知还是不可变通知,都有以下的几个属性:
// 1.附件数组,存放UNNotificationAttachment类
@property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments ;
// 2.应用程序角标,0或者不传,意味着角标消失
@property (NS_NONATOMIC_IOSONLY, copy, nullable) NSNumber *badge;
// 3.主体内容
@property (NS_NONATOMIC_IOSONLY, copy) NSString *body ;
// 4.app通知下拉预览时候展示的图
@property (NS_NONATOMIC_IOSONLY, copy) NSString *launchImageName;
// 5.UNNotificationSound类,可以设置默认声音,或者指定名称的声音
@property (NS_NONATOMIC_IOSONLY, copy, nullable) UNNotificationSound *sound ;
// 6.推送内容的子标题
@property (NS_NONATOMIC_IOSONLY, copy) NSString *subtitle ;
// 7.通知线程的标识
@property (NS_NONATOMIC_IOSONLY, copy) NSString *threadIdentifier;
// 8.推送内容的标题
@property (NS_NONATOMIC_IOSONLY, copy) NSString *title ;
// 9.远程通知推送内容
@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *userInfo;
// 10.category标识
@property (NS_NONATOMIC_IOSONLY, copy) NSString *categoryIdentifier;
附件内容(UNNotificationAttachment)
- 在UNNotificationContent类中,有个附件数组的属性,这就是包含UNNotificationAttachment类的数组了。
@property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments ;
苹果的解释说,UNNotificationAttachment(附件通知)是指可以包含音频,图像或视频内容,并且可以将其内容显示出来的通知。使用本地通知时,可以在通知创建时,将附件加入即可。对于远程通知,则必须实现使用UNNotificationServiceExtension类通知服务扩展。
创建附件的方法:
+ (nullable instancetype)attachmentWithIdentifier:(NSString *)identifier URL:(NSURL *)URL options:(nullable NSDictionary *)options error:(NSError *__nullable *__nullable)error;
// URL必须是一个有效的文件路径,不然会报错
- 在使用时,必须指定使用文件附件的内容,并且文件格式必须是支持的类型之一。
创建附件中options的属性,一共有4种选项。
- options属性为一个类型为字典的数值。
UNNotificationAttachmentOptionsTypeHintKey
- 一个包含描述文件的类型统一类型标识符(UTI)一个NSString。如果不提供该键,附件的文件扩展名来确定其类型,常用的类型标识符有
kUTTypeImage、kUTTypeJPEG2000、kUTTypeTIFF、kUTTypePICT、kUTTypeGIF、kUTTypePNG、kUTTypeQuickTimeImage
等。 - 这些标识符,在
UIImagePickerController
对象属性中也会遇到。 - 使用这些标识符需要导如对应的框架
<MobileCoreServices/MobileCoreServices.h>
- 使用方法示例:
NSMutableDictionary *optionsDict = [NSMutableDictionary dictionary];
// 需要导入框架 #import<MobileCoreServices/MobileCoreServices.h>
optionsDict[UNNotificationAttachmentOptionsTypeHintKey] = (__bridge id _Nullable)(kUTTypeImage);
UNNotificationAttachmentOptionsThumbnailHiddenKey
- 此值为布尔值,代表是否隐藏推送消息右侧缩略图,YES代表隐藏
- 使用方法示例:
optionsDict[UNNotificationAttachmentOptionsThumbnailHiddenKey] = @YES;
// 隐藏缩略图
UNNotificationAttachmentOptionsThumbnailClippingRectKey
- 剪贴矩形的缩略图,将缩略图整体作为1:1,然后按照比例进行缩减,以图片左上角为原点。
- 示例,剪切图片(中心的正方形)
optionsDict[UNNotificationAttachmentOptionsThumbnailClippingRectKey] = (__bridge id _Nullable)((CGRectCreateDictionaryRepresentation(CGRectMake(0.25, 0.25, 0.5 ,0.5))));
UNNotificationAttachmentOptionsThumbnailTimeKey
- 主要用于附件是影片的,选择影片中的某一秒来做这个缩略图。
- 示例,以影片第一秒来作为缩略图
optionsDict[UNNotificationAttachmentOptionsThumbnailTimeKey] = @1;
通知触发模式(UNNotificationTrigger)
- 通知触发模式供有四种情况,四种情况均是
UNNotificationTrigger
子类。
远程推送触发模式
@interface UNPushNotificationTrigger : UNNotificationTrigger
本地推送触发模式(按秒间隔)
@interface UNTimeIntervalNotificationTrigger : UNNotificationTrigger
- 使用方法示例:
// timeInterval(时间间隔)和repeats(是否重复)
// 5秒后执行,NO:不重复
// 如果需要重复执行,则重复时间间隔需要大于60秒
UNTimeIntervalNotificationTrigger *triggerOne = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
本地推送触发模式(按日期进行间隔)
UNCalendarNotificationTrigger
- 使用方法示例:
// 例如:周二早上 9:00 上班
NSDateComponents *components = [[NSDateComponents alloc] init];
// 注意,weekday是从周日开始从1计数,如果想设置为从周一开始则需要设置为2
components.weekday = 3;
components.hour = 9;
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
本地推送触发模式(按地理位置)
@interface UNLocationNotificationTrigger : UNNotificationTrigger
使用方式
- 导入框架
#import<CoreLocation/CoreLocation.h>
- 初始化对象
// 不建议使用!!!!!!CLRegion *region = [[CLRegion alloc] init];
CLCircularRegion *circlarRegin = [[CLCircularRegion alloc] init];
// 经纬度
CLLocationDegrees latitudeDegrees = 123.00; // 维度
CLLocationDegrees longitudeDegrees = 123.00; // 经度
[circlarRegin containsCoordinate:CLLocationCoordinate2DMake(latitudeDegrees, longitudeDegrees)];
UNLocationNotificationTrigger *trigger = [UNLocationNotificationTrigger triggerWithRegion:circlarRegin repeats:NO];
这里建议使用CLCircularRegion这个继承自CLRegion的类,因为我看到苹果已经飞起了CLRegion里面是否包含这一点的方法,并且推荐我们使用CLCircularRegion这个类型
创建本地通知示例
#pragma mark - 创建本地推送 ios10之后
- (void)creatLocalPushIOS10{
// 注意:创建本地通知也需要在appdelegate中心进行注册
// 1.创建通知内容
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"本地通知标题";
content.subtitle = @"本地通知副标题";
content.body = @"本地通知内容";
content.badge = @1;
NSError *error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:@"imageName" ofType:@"png"];
// 2.设置通知附件内容
NSMutableDictionary *optionsDict = [NSMutableDictionary dictionary];
// 一个包含描述文件的类型统一类型标识符(UTI)一个NSString。如果不提供该键,附件的文件扩展名来确定其类型,常用的类型标识符有 kUTTypeImage,kUTTypeJPEG2000,kUTTypeTIFF,kUTTypePICT,kUTTypeGIF ,kUTTypePNG,kUTTypeQuickTimeImage等。
// 需要导入框架 #import<MobileCoreServices/MobileCoreServices.h>
optionsDict[UNNotificationAttachmentOptionsTypeHintKey] = (__bridge id _Nullable)(kUTTypeImage);
// 是否隐藏缩略图
optionsDict[UNNotificationAttachmentOptionsThumbnailHiddenKey] = @YES;
// 剪切缩略图
optionsDict[UNNotificationAttachmentOptionsThumbnailClippingRectKey] = (__bridge id _Nullable)((CGRectCreateDictionaryRepresentation(CGRectMake(0.25, 0.25, 0.5 ,0.5))));
// 如果附件是影片,则以第几秒作为缩略图
optionsDict[UNNotificationAttachmentOptionsThumbnailTimeKey] = @1;
// optionsDict如果不需要,可以不设置,直接传nil即可
UNNotificationAttachment *att = [UNNotificationAttachment attachmentWithIdentifier:@"identifier" URL:[NSURL fileURLWithPath:path] options:optionsDict error:&error];
if (error) {
NSLog(@"attachment error %@", error);
}
content.attachments = @[att];
content.launchImageName = @"imageName@2x";
// 2.设置声音
UNNotificationSound *sound = [UNNotificationSound defaultSound];
content.sound = sound;
// 3.触发模式 多久触发,是否重复
// 3.1 按秒
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
// 3.2 按日期
// // 周二早上 9:00 上班
// NSDateComponents *components = [[NSDateComponents alloc] init];
// // 注意,weekday是从周日开始的计数的
// components.weekday = 3;
// components.hour = 9;
// UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
// 3.3 按地理位置
// 一到某个经纬度就通知,判断包含某一点么
// 不建议使用!!!!!!CLRegion *region = [[CLRegion alloc] init];
// CLCircularRegion *circlarRegin = [[CLCircularRegion alloc] init];
// 经纬度
// CLLocationDegrees latitudeDegrees = 123.00; // 维度
// CLLocationDegrees longitudeDegrees = 123.00; // 经度
// [circlarRegin containsCoordinate:CLLocationCoordinate2DMake(latitudeDegrees, longitudeDegrees)];
// UNLocationNotificationTrigger *trigger = [UNLocationNotificationTrigger triggerWithRegion:circlarRegin repeats:NO];
// 4.设置UNNotificationRequest
NSString *requestIdentifer = @"TestRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:trigger];
//5.把通知加到UNUserNotificationCenter, 到指定触发点会被触发
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
}
推送效果图示:
推送回调
- 远程推送与本地推送均是这两个回调
#pragma mark - UNUserNotificationCenterDelegate
// iOS10 推送回调
- (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 收到远程通知");
}else{
NSLog(@"ios10 收到本地通知%@%@%@%@%@",title,subTitle,body,badge,userInfo);
}
completionHandler(UNNotificationPresentationOptionBadge |
UNNotificationPresentationOptionSound |
UNNotificationPresentationOptionAlert );
// 需要执行此方法,选择是否提醒用户,有以上三种那个类型可选
}
// 通知的点击事件
- (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; // 推送收到的标题
NSLog(@">>>通知的点击事件");
if ([request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"iOS10 收到远程通知");
}else{
NSLog(@"ios10 收到本地通知%@%@%@%@%@",title,subTitle,body,badge,userInfo);
}
completionHandler(); //系统要求执行此方法
}
代码地址:https://github.com/FlyingKuiKui/PushTestApp.git