iOS10 新通知功能UserNotifications应用

介绍

这个demo可以帮助你快速的了解iOS10中引入的新通知功能,该功能向用户呈现了强大而灵活的通知。本文将会介绍如何给通知附加媒体内容、自定义通知UI等。

背景

iOS10为开发人员提供了更强大、更灵活的本地和远程通知,它引进了两个新的框架

  • UserNotifications.framework
  • UserNotificationsUI.framework

新的功能

  • 通知支持视频、音频、图片
  • App在前台仍然可以显示通知
  • 给通知添加action操作
  • 可以快速回复文本
  • 支持gif图
  • 自定义通知的界面

代码

我们基于iOS10的新的通知功能创建一个本地通知
在Xcode中,到工程设置Build Phases -> Link Binary With Libraries中添加UserNotifications.frameworkUserNotificationsUI.framework

添加库截图.png

引入头文件

import <UserNotifications/UserNotifications.h> 

当应用处于前台时获取通知
首先需要遵守UNUserNotificationCenterDelegate协议,实现userNotificationCenter:willPresentNotification:withCompletionHandler:代理方法

- (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;

初始化这个属性

  _notiCenter = [UNUserNotificationCenter currentNotificationCenter];
    _notiCenter.delegate=self;
    [_notiCenter  requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        //Enable or disable features based on authorization.
        if(granted)
        {
            [_notiCenter setDelegate:self];
                [self generateTimerBasedNotification];
                [self generateLocationBasedNotification];
                // _categoryActionSet has collected all the actions from different kind of notifications and adding it to notification Center
                [[self notiCenter] setNotificationCategories:_categoryActionSet];
        }
    }];

可以通过iOS10UNUserNotificationCenter的API获取到通知设置的属性

// 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");
        }
    }];

iOS10中新添加了两个扩展

  • 通知服务(Notification Service)
  • 通知内容(Notification Content)

Notification Service
它是运行在后台以用来下载远程通知中指定的URL,或者将远程通知的内容在展示给用户之前进行替换
在file->New->Target选择Notification Service Extension
添加完target后将会创建NotificationService.hNotificationService.minfo.plist三个文件
NotificationService类派生自UNNotificationServiceExtension,这个基类只有两个方法,而且通知服务仅用于远程通知

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *contentToDeliver))contentHandler;

此方法用于下载远程通知中的URL内容以展示给用户

- (void)serviceExtensionTimeWillExpire;

如果程序无法在给定的时间内(从设备接受到远程通知到传递给用户的时间)完成下载,那么此方法为备用方案,
一旦设备接受到远程通知并且将其展示给用户之前,系统将运行该服务扩展,首先,系统将会调用didReceiveNotificationRequest,在这里可以从UNNotificationRequest中获取到通知的数据,并获取到媒体的URL开始下载。如果再给定的时间下载失败或者下载没有完成,系统将会调用serviceExtensionTimeWillExpire告诉我们分配给下载内容的时间将要过去,在这里可以有一些代替的解决方案,我们可以替换为本地的图片、视频、音频等。
Notification Content
在file->New->Target选择Notification Content
此内容扩展可以帮助我们添加自定义的视图,以及处理用户对通知的操作.
添加了target之后将会创建NotificationViewController.hNotificationViewController.mMainInterface.storyboardinfo.plist
使用MainInterface.storyboard自定义我们的通知视图,在Notification View Controller Scene拖拽我们想要的通知样式
当用户点击任何操作按钮时,系统都会调用didReceiveNotificationResponse委托方法

带有媒体文件的通知

将图片添加到通知
使用UNMutableNotificationContent类可以像通知中添加许多内容、
在本地通知中,我们可以将图片,音频或者视频的路径添加到UNMutableNotificationContent.attachments

    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];
    // category identitifer should be unique and  should match with identitifer of its corresponding UNNotificationCategory
    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种操作

  • Default Actions - 默认操作是用户从通知打开应用
  • Custom Actions - 可以直接从通知本身执行,无需启动应用
  • Dismiss Actions - 关闭操作
 // Adding custom actions
    
    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 ];
    
    // categoryWithIdentifier should match with the value of UNNotificationExtensionCategory in info.plist of its corresponding content extension
    UNNotificationCategory *TimernotificationCategory=[UNNotificationCategory categoryWithIdentifier:@"com.mcoe.notificationcategory.timerbased" actions:NotificationActions intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    
    
    
    [_categoryActionSet addObject:TimernotificationCategory];

计划通知

本地通知可以通过三种方式触发

  • 时间间隔
  • 日历时间
  • 位置信息

时间间隔

UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger 
                                                             triggerWithTimeInterval:3.f repeats:NO];

位置信息

    //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对象的 category identifier 和通知内容扩展的info.plist中的UNNotificationExtensionCategory标示符名称应该相同
  • 由于我们可以向项目中添加多个扩展,系统使用接受到的通知中的类别标示符名称找到其对应的扩展代码以调用其委托方法
  • UNNotificationExtensionInitialContentSizeRatio在通知内容扩展的info.plist中指示自定义视图的宽高比,其范围在0到1之间。1标示自定义界面高度等于其宽度,0标示其高度是其宽度的一半
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容