APNS 学习总结(四)

来源:互联网 发布:sql 删除表 编辑:程序博客网 时间:2024/05/01 22:53
Scheduling and Handling Local Notifications

本地通知提供给你一个方式当你的app可能没有运行的时候来提醒用户。你可以在app处于前台或者后台的时候来规划本地通知。当完成通知规划后,系统就负责在合适的时机将通知投递给用户。你的app不需要一直运行的状态来让系统投递通知。


注:就是说即便你的app退到后台了,或者退到后台并且锁屏了,系统仍然可以处理通知事件当触发时机到达时。

如果你的app没有运行或者如果他在后台,系统会直接向用户展示本地通知。系统可以以不同的方式来提醒用户,比如声音文件,或者badging。如果你的app提供了一个notification 内容app扩展,系统甚至可以用你的自定义接口来提醒用户。如果你的app在通知到达时处于前台,系统会把通知交由你的app来处理。


注意:
本地通知仅仅在ios, watchos,和tvos上支持。在macos上,app不需要本地通知来标注角标,播放声音或者显示提醒当在后台运行时。这些功能可以被appkit框架所支持。

Configuring a Local Notification
配置本地通知的步骤如下:

1. 创建和配置一个包含通知细节的UNMutableNotificationContent对象


2. 创建UNCalendarNotificationTrigger, UNTimeIntervalNotificationTrigger, 或者UNLocationNotificationTrigger 对象来描述什么条件下通知会被投递。

3. 创建UNNotificationRequest对象并设置好内容和触发信息


4. 调用addNotificationRequest:withCompletionHandler:方法来规划通知。


使用UNMutableNotificationContent 对象来设置比如想要显示的title和body。系统通过你提供的信息来决定如何和用户交互。你也可以在工程中使用数据。

当创建完通知内容后,创建一个触发对象来决定合适投递通知。user notifications 框架提供了以时间为基础和以地点为基础的触发时机。使用必须的条件来配置触发并且使用这个对象来创建UNNotificationRequest对象。

Listing 3-1
显示如何创建和配置一个本地的闹钟通知。UNCalendarNotificationTrigger 的使用导致在指定的日期或者时间通知被触发。

Listing 3-1Creating and configuring a local notification
objc


1. UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
2. content.title = [NSString localizedUserNotificationStringForKey:@"Wake up!" arguments:nil];
3. content.body = [NSString localizedUserNotificationStringForKey:@"Rise and shine! It's morning time!"
4. arguments:nil];
5. 

6. // Configure the trigger for a 7am wakeup.
7. NSDateComponents* date = [[NSDateComponents alloc] init];
8. date.hour = 7;
9. date.minute = 0;
10. UNCalendarNotificationTrigger* trigger = [UNCalendarNotificationTrigger
11. triggerWithDateMatchingComponents:date repeats:NO];
12. 

13. // Create the request object.
14. UNNotificationRequest* request = [UNNotificationRequest
15. requestWithIdentifier:@"MorningAlarm" content:content trigger:trigger];
swift


1. let content = UNMutableNotificationContent()
2. content.title = NSString.localizedUserNotificationString(forKey: "Wake up!", arguments: nil)
3. content.body = NSString.localizedUserNotificationString(forKey: "Rise and shine! It's morning time!",
4. arguments: nil)
5. 

6. // Configure the trigger for a 7am wakeup.
7. var dateInfo = DateComponents()
8. dateInfo.hour = 7
9. dateInfo.minute = 0
10. let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: false)
11. 

12. // Create the request object.
13. let request = UNNotificationRequest(identifier: "MorningAlarm", content: content, trigger: trigger)
为UNNotificationRequest对象提供一个identifier给你提供了一种途径来标记本地通知在它们被规划后。你可以使用这个标识来查找之后的pending中的请求并且在它们被投递前取消掉。

Assigning Custom Actions to a Local Notification
为了在本地通知接口上显示自定义的actions,分配你注册的其中一个categoryIdentifier属性标识到你的UNMutableNotificationContent对象中。系统使用这个category信息来决定哪些action buttons会被包含在内。你必须在规划通知请求前就给这个属性分配值。

Listing 3-2 

shows how to specify the category identifier for a local notification. In this example, the “TIMER_EXPIRED” string represents a category that was defined at launch time and that includes two custom actions. The code for registering this category is shown in Listing 2-3. 


Listing 3-2Defining a category of actions for a local notification
objc


1. UNNotificationContent *content = [[UNNotificationContent alloc] init];
2. // Configure the content. . .
3. 

4. // Assign the category (and the associated actions).
5. content.categoryIdentifier = @"TIMER_EXPIRED";
6. 

7. // Create the request and schedule the notification.
swift


1. let content = UNMutableNotificationContent()
2. // Configure the content. . .
3. 

4. // Assign the category (and the associated actions).
5. content.categoryIdentifier = "TIMER_EXPIRED"
6. 

7. // Create the request and schedule the notification.
For information on how to register custom actions with a category, see Configuring Categories and Actionable Notifications
Adding a Sound to the Notification Content
If you want a local notification to play a sound when it is delivered, assign a value to the sound property of your UNMutableNotificationContent object. You specify sounds using a UNNotificationSound object, which lets you play either a custom sound or the default notification sound. Custom sounds must reside locally on the user’s device before they can be played. Store the sound files for your notifications in your app’s main bundle or download them and store them in the Library/Sounds subdirectory of your app’s container directory.
To play the default sound, create the sound file and assign it to your notification content. For example:

1. content.sound = [UNNotificationSound defaultSound];

1. content.sound = UNNotificationSound.default()
When specifying custom sounds, specify only the filename of the sound file that you want played. If the system finds a suitable sound file with the name you provided, it plays that sound when delivering the notification. If the system does not find a suitable sound file, it plays the default sound.

1. content.sound = [UNNotificationSound soundNamed:@"MySound.aiff"];

1. content.sound = UNNotificationSound(named: "MySound.aiff")
For information about the supported sound file formats, see UNNotificationSound Class Reference.
Scheduling Local Notifications for Delivery
调用UNUserNotificationCenter的addNotificationRequest:withCompletionHandler:方法来投递notification。

Listing 3-3Scheduling a local notification for delivery

1. // Create the request object.
2. UNNotificationRequest* request = [UNNotificationRequest
3. requestWithIdentifier:@"MorningAlarm" content:content trigger:trigger];
4. 

5. UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
6. [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
7. if (error != nil) {
8. NSLog(@"%@", error.localizedDescription);
9. }
10. }];

1. // Create the request object.
2. let request = UNNotificationRequest(identifier: "MorningAlarm", content: content, trigger: trigger)
3. 

4. // Schedule the request.
5. let center = UNUserNotificationCenter.current()
6. center.add(request) { (error : Error?) in
7. if let theError = error {
8. print(theError.localizedDescription)
9. }
10. }
规划本地通知依然有效直到它们被系统所注销或者你显示地取消掉。在通知被投递后系统会自动注销这些通知,除非通知的触发配置为repeat。为了在投递通知前就可以取消掉,或者取消掉一个repeating的通知,就需要调用removePendingNotificationRequestsWithIdentifiers: 那么就必须有一个identifier分配给这个UNNotificationRequest对象。removeAllPendingNotificationRequests 会取消掉所有pending状态的本地通知而不管它们是否有request identifier。
注意:所有的设置完成以后必须要记得设置delegate!否则notificationcenter的delegate方法不会执行。

Responding to the Delivery of Notifications
当你的app没有在运行或者在后台,系统会使用你指定的interactions来自动投递本地和远程通知。如果用户选择了一个action,或者选择了标准交互中的一种,系统会通知你的app用户的选择。程序就可以使用选择来执行额外的任务了。如果你的app在前台运行,通知就会被直接投递给你的app。你可以决定是否悄悄执行通知或者还是提醒用户。

为了响应通知的投递,你必须实现UNUserNotificationCenterDelegate的代理方法。

Important
You must assign your delegate to the shared UNUserNotificationCenter object before your app or app extension finishes launching. Failure to do so may prevent your app from handling notifications correctly.
For additional information on how to implement your delegate object, see UNUserNotificationCenterDelegate Protocol Reference.
Handling Notifications When Your App Is in the Foreground
当你的app在前台时,如果一个通知到达了,你可以悄悄执行这个通知或者告知系统来继续显示通知接口。默认情况下系统不会提醒用户。

如果你想让系统继续展示通知接口,就需要提供一个delegate对象,并且实现userNotificationCenter:willPresentNotification:withCompletionHandler: 方法。你的这个方法的视线仍然需要访问通知数据。

Listing 3-4 shows a sample implementation of this method that tells the system to play a sound. The notification’s payload identifies which sound to play.
Listing 3-4Playing a sound while your app is in the foreground

1. - (void)userNotificationCenter:(UNUserNotificationCenter *)center
2. willPresentNotification:(UNNotification *)notification
3. withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
4. // Update the app interface directly.
5. 

6. // Play a sound. 这里必须要设置上你需要系统做出的反应,是播放声音还是显示alert信息等。如果不设置,那么你之前的自定义alert内容将无法显示出来!

7. completionHandler(UNNotificationPresentationOptionSound);
8. }

1. func userNotificationCenter(_ center: UNUserNotificationCenter,
2. willPresent notification: UNNotification,
3. withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
4. // Update the app interface directly.
5. 

6. // Play a sound.
7. completionHandler(UNNotificationPresentationOptions.sound)
8. }
如果你的app在后台或者没有运行,那么userNotificationCenter:willPresentNotification:withCompletionHandler:方法是不会被调用的。

Responding to the Selection of a Custom Action
使用userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: 方法来和用户进行交互。在这个方法里面就可以得知用户对自定义的actions都正在进行哪种操作。

如果你的app或者app extension党response接收到时候没有在运行,系统会在后台加载你的app或者app extension来执行这个response。使用提供的后台时间来更新你的数据结构并且你的app的接口来反映用户的选择。不要使用时间来执行不相关的任务。

Listing 3-5 shows an implementation of the response handler method for a timer app with multiple categories and custom actions. The implementation uses both the action and the categoryIdentifier property to determine an appropriate course of action.
Listing 3-5Handling a custom notification action

1. - (void)userNotificationCenter:(UNUserNotificationCenter *)center
2. didReceiveNotificationResponse:(UNNotificationResponse *)response
3. withCompletionHandler:(void (^)(void))completionHandler {
4. if ([response.notification.request.content.categoryIdentifier isEqualToString:@"TIMER_EXPIRED"]) {
5. // Handle the actions for the expired timer.
6. if ([response.actionIdentifier isEqualToString:@"SNOOZE_ACTION"])
7. {
8. // Invalidate the old timer and create a new one. . .
9. }
10. else if ([response.actionIdentifier isEqualToString:@"STOP_ACTION"])
11. {
12. // Invalidate the timer. . .
13. }
14. 

15. }
16. 

17. // Else handle actions for other notification types. . .
18. }

1. func userNotificationCenter(_ center: UNUserNotificationCenter,
2. didReceive response: UNNotificationResponse,
3. withCompletionHandler completionHandler: @escaping () -> Void) {
4. if response.notification.request.content.categoryIdentifier == "TIMER_EXPIRED" {
5. // Handle the actions for the expired timer.
6. if response.actionIdentifier == "SNOOZE_ACTION" {
7. // Invalidate the old timer and create a new one. . .
8. }
9. else if response.actionIdentifier == "STOP_ACTION" {
10. // Invalidate the timer. . .
11. }
12. }
13. 

14. // Else handle actions for other notification types. . .
15. }
Handling the Standard System Actions
In the system’s notification interface, users can explicitly dismiss the notification interface or launch your app instead of selecting one of your custom actions. Dismissing the interface involves tapping an applicable button or closing the interface directly; ignoring a notification or flicking a notification banner away does not represent an explicit dismissal. When system actions are triggered, the user notification center reports them to the userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: method its delegate. The response object passed to that method contains one of the following action identifiers:
* UNNotificationDismissActionIdentifier lets you know that the user explicitly dismissed the notification interface without selecting a custom action. 

* UNNotificationDefaultActionIdentifier lets you know that the user launched your app without selecting a custom action.

You handle the standard system actions in the same way that you handle other actions. Listing 3-6 shows a template for the userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: method that checks for these special actions.
Listing 3-6Handling the standard system actions

1. - (void)userNotificationCenter:(UNUserNotificationCenter *)center
2. didReceiveNotificationResponse:(UNNotificationResponse *)response
3. withCompletionHandler:(void (^)(void))completionHandler {
4. if ([response.actionIdentifier isEqualToString:UNNotificationDismissActionIdentifier]) {
5. // The user dismissed the notification without taking action.
6. }
7. else if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
8. // The user launched the app.
9. }
10. 

11. // Else handle any custom actions. . .
12. }

1. func userNotificationCenter(_ center: UNUserNotificationCenter,
2. didReceive response: UNNotificationResponse,
3. withCompletionHandler completionHandler: @escaping () -> Void) {
4. if response.actionIdentifier == UNNotificationDismissActionIdentifier {
5. // The user dismissed the notification without taking action
6. }
7. else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
8. // The user launched the app
9. }
10. 

11. // Else handle any custom actions. . .
12. }

0 0
原创粉丝点击