65.9K
CodeProject 正在变化。 阅读更多。
Home

iOS 10 用户通知功能

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.29/5 (5投票s)

2016年10月25日

CPOL

4分钟阅读

viewsIcon

18121

downloadIcon

150

快速了解 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.hNotificationService.minfo.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.hNotificationViewController.mMainInterface.storyboardinfo.plist 文件。

请使用 MainInterface.storyboard 来自定义通知视图。选择 Notification View Controller Scene,然后点击 Main View,转到 Size inspector,并将高度设置为与其宽度相同。

NotificationViewController 类扩展了 UNNotificationContentExtension,并有两个主要委托方法:didReceiveNotificationdidReceiveNotificationResponse

当用户点击任何操作按钮时,系统会在此扩展中调用 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.plistUNNotificationExtensionCategory 的标识符名称应相同。

由于我们可以在项目中添加多个内容扩展,系统会使用收到的通知中的类别标识符名称,并联系其相应的扩展代码库来调用其委托方法。

通知内容扩展的 info.plist 中的 UNNotificationExtensionInitialContentSizeRatio 指示自定义界面的纵横比。其值在 0 到 1 之间。

1 表示自定义界面的高度与其宽度相同。

0 表示其高度将是其总宽度的一半。

© . All rights reserved.