前言
上一篇文章介绍了UILocalNotification
的使用,这篇文章主要介绍一下UNUserNotificationCenter
的使用。UILocalNotification
现在虽然还能使用,但是也已经是要被废弃不用的方法了,而本篇所要介绍的UNUserNotificationCenter
就是被弃用方法的替代品。
UNUserNotificationCenter的使用
还是那个思路,只知道使用UNUserNotificationCenter
来实现本地推送,具体怎么实现不知道。
我们在上一篇文章中所叙述的代码在Xcode里虽然能执行,但是由于那时苹果弃用的方法,所以会报出一大堆恶心的警告,我们就来看一下警告,就能够从中知道该怎么使用UNUserNotificationCenter
了。
1. 注册通知
关于注册通知的这个方法中对于警告的类我都在图中标注了,警告的意思就是说某某方法已经被弃用,让使用UserNotifications
框架中的某某方法代替。那么我们就用新的类来注册一下通知。(既然是新的框架,必然要引入头文件咯,不然是会报错的哟)
上图中出现了UNUserNotificationCenter
新类和-[UNUserNotificationCenter requestAuthorizationWithOptions:completionHandler:]
、-[UNUserNotificationCenter setNotificationCategories:]
两个示例方法,先查看一下新类的构造。
@interface UNUserNotificationCenter : NSObject
// The delegate can only be set from an application
@property (NS_NONATOMIC_IOSONLY, nullable, weak) id <UNUserNotificationCenterDelegate> delegate;
// Returns YES if the current device supports content extensions
@property (NS_NONATOMIC_IOSONLY, readonly) BOOL supportsContentExtensions;
// The UNUserNotificationCenter for the current application
+ (UNUserNotificationCenter *)currentNotificationCenter;
- (instancetype)init NS_UNAVAILABLE;
// User authorization is required for applications to notify the user using UNUserNotificationCenter via both local and remote notifications.
- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler;
// Notification categories can be used to choose which actions will be displayed on which notifications.
- (void)setNotificationCategories:(NSSet<UNNotificationCategory *> *)categories __TVOS_PROHIBITED;
- (void)getNotificationCategoriesWithCompletionHandler:(void(^)(NSSet<UNNotificationCategory *> *categories))completionHandler __TVOS_PROHIBITED;
// The application's user notification settings
- (void)getNotificationSettingsWithCompletionHandler:(void(^)(UNNotificationSettings *settings))completionHandler;
// Notification requests can be scheduled to notify the user via time and location. See UNNotificationTrigger for more information. Calling -addNotificationRequest: will replace an existing notification request with the same identifier. A notification request with the identifier as an existing delivered notifications will alert for the new notification request and replace the existing delivered notification when it is triggered. The number of pending notification requests that may be scheduled by an application at any one time is limited by the system.
- (void)addNotificationRequest:(UNNotificationRequest *)request withCompletionHandler:(nullable void(^)(NSError *__nullable error))completionHandler;
// Notification requests that are waiting for their trigger to fire
- (void)getPendingNotificationRequestsWithCompletionHandler:(void(^)(NSArray<UNNotificationRequest *> *requests))completionHandler;
- (void)removePendingNotificationRequestsWithIdentifiers:(NSArray<NSString *> *)identifiers;
- (void)removeAllPendingNotificationRequests;
// Notifications that have been delivered and remain in Notification Center. Notifiations triggered by location cannot be retrieved, but can be removed.
- (void)getDeliveredNotificationsWithCompletionHandler:(void(^)(NSArray<UNNotification *> *notifications))completionHandler __TVOS_PROHIBITED;
- (void)removeDeliveredNotificationsWithIdentifiers:(NSArray<NSString *> *)identifiers __TVOS_PROHIBITED;
- (void)removeAllDeliveredNotifications __TVOS_PROHIBITED;
@end
从以上的构造中我们可以知道的是,UNUserNotificationCenter
类继承自NSObject
类,还有一个UNUserNotificationCenterDelegate
类型的代理,一个类方法+ (UNUserNotificationCenter *)currentNotificationCenter;
用于返回当前应用的通知中心;至于下面的那么多示例方法,其中包括注册通知的方法、设置categories
的方法、获取通知的设置的方法、添加通知的方法、移除通知的方法等等。
因为我们是要注册通知,故先仔细看一下注册通知这个方法。
- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler;
该方法需要一个UNAuthorizationOptions
类型的参数,点进去看一下这个类型,发现这个竟然是个枚举类型的,跟上篇文章中设置通知方法中的那个参数类似,只是换了一个名称而已。至于后面的blockcompletionHandler
,就是注册结果的一个block。
typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) {
UNAuthorizationOptionBadge = (1 << 0),
UNAuthorizationOptionSound = (1 << 1),
UNAuthorizationOptionAlert = (1 << 2),
UNAuthorizationOptionCarPlay = (1 << 3),
} __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
接下来我们就可以顺利的写出来注册通知的代码了,如下:
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
}];
这里还有个代理忘了说了,center
的代理方法有两个,如下:
@protocol UNUserNotificationCenterDelegate <NSObject>
@optional
// The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;
@end
这个代理方法可以根据项目实际需求看是否需要了。
2. 设置通知
还是老路子,先来看一下发送通知的报黄警告内容。
警告的内容明确说了- scheduleLocalNotification:
这个方法被弃用了,要让使用-[UNUserNotificationCenter addNotificationRequest:withCompletionHandler:]
来代替,这么一看,这不就是刚才注册通知时候的那个UNUserNotificationCenter
类中的示例方法嘛,这下问题就更好解决了,方法所在类都了解了,剩余的就是看参数咯。
- (void)addNotificationRequest:(UNNotificationRequest *)request withCompletionHandler:(nullable void(^)(NSError *__nullable error))completionHandler;
从上面的函数中我们可以知道,该实例方法需要一个UNNotificationRequest
类型的参数。点进去看看它究竟是个什么鬼。
@interface UNNotificationRequest : NSObject <NSCopying, NSSecureCoding>
// The unique identifier for this notification request. It can be used to replace or remove a pending notification request or a delivered notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *identifier;
// The content that will be shown on the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) UNNotificationContent *content;
// The trigger that will or did cause the notification to be delivered. No trigger means deliver now.
@property (NS_NONATOMIC_IOSONLY, readonly, copy, nullable) UNNotificationTrigger *trigger;
+ (instancetype)requestWithIdentifier:(NSString *)identifier content:(UNNotificationContent *)content trigger:(nullable UNNotificationTrigger *)trigger;
- (instancetype)init NS_UNAVAILABLE;
@end
进去一看,哇塞,这么简短,只有短短的三十行代码(包含注释),知道了这个类是集成自NSObject
类,还有三个成员变量和一个类方法的初始方法和一个示例方法的初始化方法。我们在初始化的时候肯定就用类方法初始化啊,这样更简单,因为在类方法中已经把必须的参数都给包含了,不用使用- init
方法之后再依次的给其成员变量赋值。
- 类方法
+ (instancetype)requestWithIdentifier:(NSString *)identifier content:(UNNotificationContent *)content trigger:(nullable UNNotificationTrigger *)trigger;
这个方法中除了需要一个字符串的标识符identifier
以外,还需要UNNotificationContent
类型的content以及UNNotificationTrigger
类型的trigger。接下来我们就来仔细看一下这两个参数。
A. UNNotificationContent
类型的content
先来看一下类组成
@interface UNNotificationContent : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
// Optional array of attachments.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSArray <UNNotificationAttachment *> *attachments __TVOS_PROHIBITED;
// The application badge number.
@property (NS_NONATOMIC_IOSONLY, readonly, copy, nullable) NSNumber *badge;
// The body of the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *body __TVOS_PROHIBITED;
// The identifier for a registered UNNotificationCategory that will be used to determine the appropriate actions to display for the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *categoryIdentifier __TVOS_PROHIBITED;
// The launch image that will be used when the app is opened from the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *launchImageName __TVOS_PROHIBITED;
// The sound that will be played for the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy, nullable) UNNotificationSound *sound __TVOS_PROHIBITED;
// The subtitle of the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *subtitle __TVOS_PROHIBITED;
// The unique identifier for the thread or conversation related to this notification request. It will be used to visually group notifications together.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *threadIdentifier __TVOS_PROHIBITED;
// The title of the notification.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *title __TVOS_PROHIBITED;
// Apps can set the userInfo for locally scheduled notification requests. The contents of the push payload will be set as the userInfo for remote notifications.
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSDictionary *userInfo __TVOS_PROHIBITED;
@end
__IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
@interface UNMutableNotificationContent : UNNotificationContent
// Optional array of attachments.
@property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments __TVOS_PROHIBITED;
// The application badge number. nil means no change. 0 to hide.
@property (NS_NONATOMIC_IOSONLY, copy, nullable) NSNumber *badge;
// The body of the notification. Use -[NSString localizedUserNotificationStringForKey:arguments:] to provide a string that will be localized at the time that the notification is presented.
@property (NS_NONATOMIC_IOSONLY, copy) NSString *body __TVOS_PROHIBITED;
// The identifier for a registered UNNotificationCategory that will be used to determine the appropriate actions to display for the notification.
@property (NS_NONATOMIC_IOSONLY, copy) NSString *categoryIdentifier __TVOS_PROHIBITED;
// The launch image that will be used when the app is opened from the notification.
@property (NS_NONATOMIC_IOSONLY, copy) NSString *launchImageName __TVOS_PROHIBITED;
// The sound that will be played for the notification.
@property (NS_NONATOMIC_IOSONLY, copy, nullable) UNNotificationSound *sound __TVOS_PROHIBITED;
// The subtitle of the notification. Use -[NSString localizedUserNotificationStringForKey:arguments:] to provide a string that will be localized at the time that the notification is presented.
@property (NS_NONATOMIC_IOSONLY, copy) NSString *subtitle __TVOS_PROHIBITED;
// The unique identifier for the thread or conversation related to this notification request. It will be used to visually group notifications together.
@property (NS_NONATOMIC_IOSONLY, copy) NSString *threadIdentifier __TVOS_PROHIBITED;
// The title of the notification. Use -[NSString localizedUserNotificationStringForKey:arguments:] to provide a string that will be localized at the time that the notification is presented.
@property (NS_NONATOMIC_IOSONLY, copy) NSString *title __TVOS_PROHIBITED;
// Apps can set the userInfo for locally scheduled notification requests. The contents of the push payload will be set as the userInfo for remote notifications.
@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *userInfo;
@end
这个是代码量相比较上一个类是多了很多,但是再仔细看一下,这是两个类,第一个类UNNotificationContent
是继承自NSObject
类,第二个类 UNMutableNotificationContent
继承自UNNotificationContent
,有没有很熟悉的感觉,这不就是跟NSArray
和NSMutableArray
的关系一样嘛,仔细看一下成员变量都基本上相同,唯一的区别在于前者的成员变量的是readonly
的,后者则没有限制,那么我们要构造这个参数就可以直接使用后者可变的UNMutableNotificationContent
来构造了。至于成员变量无非就是设置推送内容、声音、图片等的,唯一值得一提的是,这里的声音又单独封装了一个类UNNotificationSound
来实现,其中包含有一个默认声音的+ (instancetype)defaultSound;
类方法和可以自定义声音+ (instancetype)soundNamed:(NSString *)name __WATCHOS_PROHIBITED;
类方法以及一个- init
初始化方法。至于使用那就不用多说了吧。
B. UNNotificationTrigger
类型的trigger
先来看一下类构造
@interface UNNotificationTrigger : NSObject <NSCopying, NSSecureCoding>
@property (NS_NONATOMIC_IOSONLY, readonly) BOOL repeats;
- (instancetype)init NS_UNAVAILABLE;
@end
// UNPushNotificationTrigger can be sent from a server using Apple Push Notification Service.
__IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
@interface UNPushNotificationTrigger : UNNotificationTrigger
@end
// UNTimeIntervalNotificationTrigger can be scheduled on the device to notify after the time interval, and optionally repeat.
__IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
@interface UNTimeIntervalNotificationTrigger : UNNotificationTrigger
@property (NS_NONATOMIC_IOSONLY, readonly) NSTimeInterval timeInterval;
+ (instancetype)triggerWithTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats;
- (nullable NSDate *)nextTriggerDate;
@end
// UNCalendarNotificationTrigger can be scheduled on the device to notify based on date and time values, and optionally repeat. For example, if a notification should be delivered at the next 8:00 AM then set the 'hour' property of dateComponents to 8. If the notification should be delivered every day at 8:00 AM then set repeats to YES.
__IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
@interface UNCalendarNotificationTrigger : UNNotificationTrigger
@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSDateComponents *dateComponents;
// The next date is calculated using matching date components.
+ (instancetype)triggerWithDateMatchingComponents:(NSDateComponents *)dateComponents repeats:(BOOL)repeats;
- (nullable NSDate *)nextTriggerDate;
@end
// UNLocationNotificationTrigger can be scheduled on the device to notify when the user enters or leaves a geographic region. The identifier on CLRegion must be unique. Scheduling multiple UNNotificationRequests with different regions containing the same identifier will result in undefined behavior. The number of UNLocationNotificationTriggers that may be scheduled by an application at any one time is limited by the system. Applications must have "when-in-use" authorization through CoreLocation. See the CoreLocation documentation for more information.
__IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED
@interface UNLocationNotificationTrigger : UNNotificationTrigger
@property (NS_NONATOMIC_IOSONLY, readonly, copy) CLRegion *region;
+ (instancetype)triggerWithRegion:(CLRegion *)region repeats:(BOOL)repeats __WATCHOS_PROHIBITED;
@end
猛地一看貌似也很多的样子,但是仔细一看就发现了端倪:
这里不仅仅是UNNotificationTrigger
一个类,还包含了以下四个类:
// UNPushNotificationTrigger can be sent from a server using Apple Push Notification Service. UNPushNotificationTrigger
// UNTimeIntervalNotificationTrigger can be scheduled on the device to notify after the time interval, and optionally repeat. UNTimeIntervalNotificationTrigger
// UNCalendarNotificationTrigger can be scheduled on the device to notify based on date and time values, and optionally repeat. For example, if a notification should be delivered at the next 8:00 AM then set the 'hour' property of dateComponents to 8. If the notification should be delivered every day at 8:00 AM then set repeats to YES. UNCalendarNotificationTrigger
// UNLocationNotificationTrigger can be scheduled on the device to notify when the user enters or leaves a geographic region. The identifier on CLRegion must be unique. Scheduling multiple UNNotificationRequests with different regions containing the same identifier will result in undefined behavior. The number of UNLocationNotificationTriggers that may be scheduled by an application at any one time is limited by the system. Applications must have "when-in-use" authorization through CoreLocation. See the CoreLocation documentation for more information. UNLocationNotificationTrigger
值得一说的是,这四个类全部都是继承自
UNNotificationTrigger
类,也就是说添加推送的方法参数trigger中,我们无论是使用UNNotificationTrigger
亦或者是其子类都可以。
OK,所有的介绍到现在为止,我们已经能够写出来发送通知的代码了,如下:
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.badge = [NSNumber numberWithInt:1];
content.title = @"磨蹭";
content.body = @"不要磨蹭了你个懒蛋";
content.sound = [UNNotificationSound defaultSound];
// 间隔多久推送一次
// 当前时间之后的没分钟推送一次(如果重复的话时间要大于等于60s)
// UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:60 repeats:YES];
// 定时推送
NSDateComponents *dateCom = [[NSDateComponents alloc] init];
// 每天下午两点五十五分推送
dateCom.hour = 14;
dateCom.minute = 55;
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateCom repeats:YES];
UNNotificationRequest *notificationRequest = [UNNotificationRequest requestWithIdentifier:@"request1" content:content trigger:trigger];
[center addNotificationRequest:notificationRequest withCompletionHandler:^(NSError * _Nullable error) {
}];
总结
新类UNUserNotificationCenter
实现推送相比较于上篇文章中介绍的UILocalNotification
类来说从内容上来说,新类是将原先的类进行了更加细致化的封装并将新类放在新的框架UserNotifications
中,各个类功能分工更加明确,使用起来也更加简便。
友情链接:iOS8 本地推送 UILocalNotification
如有不足之处,欢迎指出。