iOS 10 用户通知功能
快速了解 iOS 10 用户通知功能
引言
该项目 NotificationExample 旨在帮助开发者快速了解如何使用 iOS 10 中引入的新功能,向用户呈现灵活强大的通知。本文将介绍如何附加媒体内容、操作以及自定义通知 UI。
背景
iOS 10 为开发者带来了更强大、更灵活的本地和远程通知功能。它引入了两个新框架。
它们是:
- UserNotifications.framework
- UserNotificationsUI.framework
面向开发者的主要新功能
- 通知支持视频、音频和图像。
- 即使 App 处于前台,通知也会显示。
- 为通知添加操作
- 启用快速回复文本
- 支持 GIF 图像
- 自定义通知的用户界面
使用代码
让我们使用 iOS 10 的新功能创建一个本地通知。
在 Xcode 中,转到 Build Phases,然后添加 UserNotifications.framework 和 UserNotificationsUI.frameworks。
#import <UserNotifications/UserNotifications.h>
在 App 前台时获取通知
在您的 .h/App delegate 文件中扩展 UNUserNotificationCenterDelegate 协议,并在完成处理程序中通过执行 UNNotificationPresentationOptionAlert 来实现 willPresentNotification 委托方法。
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0){ completionHandler(UNNotificationPresentationOptionAlert); }
通知服务注册
本地通知和远程通知都必须注册。
@property(strong,nonatomic) UNUserNotificationCenter* notiCenter;
在您的类扩展中添加上述属性。
// Getting current notification center object and ask for notification authorization from user _notiCenter = [UNUserNotificationCenter currentNotificationCenter]; _notiCenter.delegate=self; [_notiCenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) { if(granted) { [_notiCenter setDelegate:self]; [self generateTimerBasedNotification]; [self generateLocationBasedNotification]; } //Enable or disable features based on authorization. }];
在 iOS 10 中,我们还可以使用 API 类 UNUserNotificationCenter 以编程方式读取通知设置值。
// Read the notification setting, set by user [_notiCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { if(settings.soundSetting==UNNotificationSettingEnabled) { NSLog(@"Sound Notification is Enabled"); } else { NSLog(@"Sound Notification is Disabled"); } if(settings.alertSetting==UNNotificationSettingEnabled) { NSLog(@"Alert Notification is Enabled"); } else { NSLog(@"Alert Notification is Disabled"); } if(settings.badgeSetting==UNNotificationSettingEnabled) { NSLog(@"Badge is Enabled"); } else { NSLog(@"Badge is Disabled"); } }];
让我们看看 iOS 10 为通知新增的 2 个 App 扩展。
-
通知服务
-
通知内容
通知服务扩展
它在后台运行,用于下载远程通知中指定的任何 URL,或在远程通知显示给用户之前替换其任何内容。
转到 File->New->Target,选择 Notification Service Extension。
添加目标后,会创建 NotificationService.h、NotificationService.m 和 info.plist 文件。
NotificationService 类继承自 UNNotificationServiceExtension,这个基类只有 2 个消息,通知服务仅与远程通知一起工作。
(void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *contentToDeliver))contentHandler;
使用上面的委托方法下载远程通知中提到的 URL 内容,以便将其显示给用户。
(void)serviceExtensionTimeWillExpire;
如果您的 App 在规定时间内(设备接收远程通知到显示给用户之前的时间)无法完成内容下载,请使用上面的委托方法定义一个替代解决方案。
设备接收远程通知并在显示给用户之前,系统会运行此服务扩展。首先,系统会调用 didReceiveNotificationRequest,您可以在此处从 UNNotificationRequest 获取通知数据,然后获取媒体 URL 并开始下载。系统会调用 serviceExtensionTimeWillExpire 方法来告知您下载内容的时间已接近尾声。您可以在这里提供一些替代方案,例如替换为静态图像、视频或音频。
通知内容
转到 File->New->Target,选择 Notification Content。
此内容扩展功能可帮助开发者添加自己的视图或自定义视图,并处理通知上的用户操作。但这些视图是不可交互的。
添加目标后,会创建 NotificationViewController.h、NotificationViewController.m、MainInterface.storyboard 和 info.plist 文件。
请使用 MainInterface.storyboard 来自定义通知视图。选择 Notification View Controller Scene,然后点击 Main View,转到 Size inspector,并将高度设置为与其宽度相同。
NotificationViewController 类扩展了 UNNotificationContentExtension,并有两个主要委托方法:didReceiveNotification 和 didReceiveNotificationResponse。
当用户点击任何操作按钮时,系统会在此扩展中调用 didReceiveNotificationResponse 委托方法。
让我们看看如何创建带有操作按钮和媒体文件的通知。
为通知附加图像
使用 UNMutableNotificationContent 类,开发者可以为通知添加丰富的媒体内容。
对于本地通知,我们可以将图像、音频或视频的路径添加到 UNMutableNotificationContent.attachments 中。
// Creating notification Content object and attaching image file UNMutableNotificationContent *notificationcontent = [[UNMutableNotificationContent alloc] init]; notificationcontent.title = [NSString localizedUserNotificationStringForKey:@"New Arrivals" arguments:nil]; notificationcontent.body = [NSString localizedUserNotificationStringForKey:@"New arrival of Your favourite products!" arguments:nil]; notificationcontent.sound = [UNNotificationSound defaultSound]; notificationcontent.categoryIdentifier=@"com.mcoe.notificationcategory.timerbased"; NSError *error=nil; // reading image from bundle and copying it to document directory. NSURL *fileFromBundle =[[NSBundle mainBundle] URLForResource:@"psc" withExtension:@"png"]; // Destination URL NSURL *url = [[self applicationDocumentsDirectory]URLByAppendingPathComponent:@"psc.png"]; NSError *error1; // copying from bundle to document directory [[NSFileManager defaultManager]copyItemAtURL:fileFromBundle toURL:url error:&error1]; // Creating attachment with image url UNNotificationAttachment *image_attachment=[UNNotificationAttachment attachmentWithIdentifier:@"com.mcoe.notificationcategory.timerbased" URL:url options:nil error:&error]; notificationcontent.attachments=[NSArray arrayWithObject:image_attachment]; notificationcontent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
为通知添加操作
主要有 3 种操作:
- 默认操作 – 当用户从通知打开 App 时,会触发默认操作。
- 自定义操作 – 快速操作可以直接从通知本身执行,无需启动 App。这些自定义操作可以是后台或前台的。后台自定义操作可以关闭通知,系统会在后台提供有限的时间来执行自定义操作。前台操作可以关闭通知并启动 App 来执行自定义操作。
- 关闭操作
// creating 3 Notification Action, setting unique identifier and adding it to notification center UNNotificationAction *checkoutAction = [UNNotificationAction actionWithIdentifier:@"com.mcoe.notificationcategory.timerbased.yes" title:@"Check out" options:UNNotificationActionOptionForeground]; UNNotificationAction *declineAction = [UNNotificationAction actionWithIdentifier:@"com.mcoe.notificationcategory.timerbased.no" title:@"Decline" options:UNNotificationActionOptionDestructive]; UNNotificationAction *laterAction = [UNNotificationAction actionWithIdentifier:@"com.mcoe.notificationcategory.timerbased.dismiss" title:@"Later" options:UNNotificationActionOptionDestructive]; NSArray *notificationActions = @[ checkoutAction, declineAction, laterAction ]; UNNotificationCategory *notificationCategory=[UNNotificationCategory categoryWithIdentifier:@"com.mcoe.notificationcategory.timerbased" actions:notificationActions intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction]; NSSet *categories = [NSSet setWithObject:notificationCategory]; [_notiCenter setNotificationCategories:categories];
安排通知
本地通知可以通过 3 种方式触发:
-
时间间隔
-
日历时间
- Location
时间间隔
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3.f repeats:NO];
Location
//Creating region object and generating Notification trigger object out of it. CLLocationCoordinate2D officeArea = CLLocationCoordinate2DMake(12.970540,80.251060); CLCircularRegion* officeRegion = [[CLCircularRegion alloc] initWithCenter:officeArea radius:10 identifier:@"My Office Bay"]; officeRegion.notifyOnEntry = YES; officeRegion.notifyOnExit = YES; UNLocationNotificationTrigger* locationTrigger = [UNLocationNotificationTrigger triggerWithRegion:officeRegion repeats:YES];
创建请求对象并将其添加到通知中心。
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"com.mcoe.notificationcategory.timerbased" content:notificationcontent trigger:timerbasedtrigger]; [_notiCenter addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (!error) { NSLog(@"added timer based NotificationRequest suceessfully!"); } }];
请注意,您分配给 UNNotificationCategory 对象的类别标识符以及通知内容扩展的 info.plist 中 UNNotificationExtensionCategory 的标识符名称应相同。
由于我们可以在项目中添加多个内容扩展,系统会使用收到的通知中的类别标识符名称,并联系其相应的扩展代码库来调用其委托方法。
通知内容扩展的 info.plist 中的 UNNotificationExtensionInitialContentSizeRatio 指示自定义界面的纵横比。其值在 0 到 1 之间。
1 表示自定义界面的高度与其宽度相同。
0 表示其高度将是其总宽度的一半。