iOS10 推送必看 UNNotificationContentExtension

来源:徐不同(@2016徐小爷)

链接:http://www.jianshu.com/p/45933f5450a4

大伙久等啦~这绝对是最全最详细的 UNNotificationContentExtension讲解哟~

这篇文章中,我会给大家补充完推送内容的后续部分,希望大家看完这篇文章后,便可以轻松的玩转推送了。

1、UNNotificationContentExtension

1.1、UNNotificationContentExtension简介

简单来说,UNNotificationContentExtension这个类,也是iOS10推送的新特性,官方文档用这么一句话,简单的解释了一下,Presents a custom interface for a delivered local or remote notification.(当你收到远程或者本地通知的时候,弹出一个自定义界面)。效果如下图所示

上面的两张图就是我们将要做出的效果,在自定义View的区域,你可以放上个视频,放上个日历,放上个显示地理位置的Label,总而言之,我们可以自定义View!

1.2、如何新建一个UNNotificationContentExtension

创建这个UNNotificationContentExtension的Target,类似于创建UNNotificationServiceExtension的步骤。

第一步:创建

第二步:选择创建类型

之后便可以看到生成了这些内容

1.3、如何使用以及相关Demo

说到如何使用这个类,我们就一定要先说一下,系统帮我们生成的这几个文件分别代表了什么意思。

>0.Info.plist

在这个NSExtensionAttributes的字典下面,我们有三个属性可以添加

一.UNNotificationExtensionCategory.

(必须要有,系统已经创建好)

解释:对应这个key的值,可以是一个字符串,也可以是一个数组,每一个字符串都是一个identifier,这个identifier对应着每一个UNMutableNotificationContent的categoryIdentifier的属性。

简单来说,就是在收到通知的时候,我们可以让服务器把这个通知的categoryIdentifier带上,作用是,我们可以根据视频,音乐,图片,来分别自定义我们的通知内容。不同的分类标识符,也会在我们讲到UNNotificationAction的时候,帮助我们区分是什么类型的通知,方便我们对不同类型的通知做出不同的操作行为。上面的截图中,我是一个字符串的形式。下图为数组形式:

使用的时候,我们参照如下代码:

// 1.这个方法是UNNotificationServiceExtension类里面的方法,可以参照我上一篇文章讲的UNNotificationServiceExtension,我要在这里重写我的通知。

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {

self.contentHandler = contentHandler;

// copy发来的通知,开始做一些处理

self.bestAttemptContent = [request.content mutableCopy];

// Modify the notification content here...

self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];

// 重写一些东西

self.bestAttemptContent.title = @"我是标题";

self.bestAttemptContent.subtitle = @"我是子标题";

self.bestAttemptContent.body = @"来自徐不同";

// 附件

NSDictionary *dict =  self.bestAttemptContent.userInfo;

NSDictionary *notiDict = dict[@"aps"];

NSString *imgUrl = [NSString stringWithFormat:@"%@",notiDict[@"imageAbsoluteString"]];

!!!!! 这里是重点!!!!!!!!!!!!

// 我在这里写死了category1,其实在收到系统推送时,每一个推送内容最好带上一个catagory,跟服务器约定好了,这样方便我们根据categoryIdentifier来自定义不同类型的视图,以及action

self.bestAttemptContent.categoryIdentifier = @"category1";

}

大家注意上面的

!!!!! 这里是重点!!!!!!!!!!!!

// 我在这里写死了category1,其实在收到系统推送时,每一个推送内容最好带上一个catagory,跟服务器约定好了,这样方便我们根据categoryIdentifier来自定义不同类型的视图,以及action

self.bestAttemptContent.categoryIdentifier = @"category1";

这里设置categoryIdentifier,最好让服务器的推送内容带上这个,然后我们好更加的定制化。不建议本地写死。

具体可以参考我的demo地址

二.UNNotificationExtensionInitialContentSizeRatio.

(必须要有,系统已经创建好)

解释:这个值的类型是一个浮点类型,代表的是高度与宽度的比值。系统会使用这个比值,作为初始化view的大小。举个简单的例子来说,如果该值为1,则该视图为正方形。如果为0.5,则代表高度是宽度的一半。

注意这个值只是初始化的一个值,在这个扩展添加后,可以重写frame,展示的时候,在我们还没打开这个视图预览时,背景是个类似图片占位的灰色,那个灰色的高度宽度之比,就是通过这个值来设定。

三.UNNotificationExtensionDefaultContentHidden.

(可选)

解释:这个值是一个BOOL值,当为YES时,会隐藏上方原本推送的内容视图,只会显示我们自定义的视图。(因为在自定义视图的时候,我们可以取得推送内容,然后按照我们想要的布局,展示出来)如果为NO时(默认为NO),推送视图就会既有我们的自定义视图,也会有系统原本的推送内容视图(这里附件是不会显示的,只会显示body里面的文字哟)

四.至于NSExtensionMainStoryboard以及NSExtensionPointIdentifier,系统默认生成,大家直接用就好,如果需要更改的,只能更改使用的storyboard的名字(不过应该没人会把系统的删除在建立一个吧 O(∩_∩)O)

>1.MainInterface.storyboard

这个就是个简单的storyboard文件,内部有一个View,这个View就是在上面的图层中的自定义View视图了。它与NotificationViewController所绑定。

>2.NotificationViewController

这是是系统帮我们默认创建了一个控制器,继承UIViewController,其实就是一个控制器啦。

说道这个控制器我们需要讲解一个方法:

1.遵守UNNotificationContentExtension的协议,我们需要用到一下的方法

// 这个方法是说,只要你收到通知,并且保证categoryIdentifier的设置,跟info.plist里面设置的一样,你就会调用这个方法。注意:一个会话的多个通知,每个通知收到时,都可以调用这个方法。

- (void)didReceiveNotification:(UNNotification *)notification;

使用如下:

- (void)didReceiveNotification:(UNNotification *)notification {

这个方法,可以给自己的控件赋值啊,调整frame啊等等,我在这里打印出来了通知的内容,供大家使用。

NSDictionary *dict =  notification.request.content.userInfo;

// 这里可以把打印的所有东西拿出来

NSLog(@"%@",dict);

/****************************打印的信息是************

aps =     {

alert = "This is some fancy message.";

badge = 1;

from = "大家好,我是徐不同";

imageAbsoluteString = "http://upload.univs.cn/2012/0104/1325645511371.jpg";

"mutable-content" = 1;

sound = default;

};

}

*******************************************/

}

说到这里,简单的UNNotificationContentExtension已经说完了,我在给大家补充一点。在UNNotificationContentExtension.h中,有着这么一个枚举

typedef NS_ENUM(NSUInteger, UNNotificationContentExtensionMediaPlayPauseButtonType) {

// 没有播放按钮

UNNotificationContentExtensionMediaPlayPauseButtonTypeNone,

// 有播放按钮,点击播放之后,按钮依旧存在,类似音乐播放的开关

UNNotificationContentExtensionMediaPlayPauseButtonTypeDefault,

// 有播放按钮,点击后,播放按钮消失,再次点击暂停播放后,按钮恢复

UNNotificationContentExtensionMediaPlayPauseButtonTypeOverlay,

}

看到这么枚举,大家一定纳闷怎么使用啊。请看下面的几个属性

// 设置播放按钮的属性

@property (nonatomic, readonly, assign) UNNotificationContentExtensionMediaPlayPauseButtonType mediaPlayPauseButtonType;

// 设置播放按钮的frame

@property (nonatomic, readonly, assign) CGRect mediaPlayPauseButtonFrame;

// 设置播放按钮的颜色

@property (nonatomic, readonly, copy) UIColor *mediaPlayPauseButtonTintColor;

// 开始跟暂停播放

- (void)mediaPlay;

- (void)mediaPause;

还有以下的类,这个类虽然也有开始播放跟结束播放的方法,不过要注意,这个是属于NSExtensionContext的,而上面我们讲的方法是UNNotificationContentExtension协议方法里的。大家要注意。

@interface NSExtensionContext (UNNotificationContentExtension)

// 控制播放

- (void)mediaPlayingStarted

// 控制暂停

- (void)mediaPlayingPaused

@end

看到这些属性,想要知道如何使用,请看我下面的步骤:

分析:

首先这些属性都是readonly的,所以直接用self.属性去修改肯定是报错的,所以我们能用的就只有get方法了。

其次:根据button的类型,我们可以联想到,如果button没有,这个播放开始暂停的方法也没用了。如果有button,自然我们就有了播放的操作,联想别的UI空间,我们得出了一定要重写它的frame,来确定他的位置。设置颜色,来设置它的显示颜色。设置button的类型,让他显示出来。

// 返回默认样式的button

- (UNNotificationContentExtensionMediaPlayPauseButtonType)mediaPlayPauseButtonType

{

return UNNotificationContentExtensionMediaPlayPauseButtonTypeDefault;

}

// 返回button的frame

- (CGRect)mediaPlayPauseButtonFrame

{

return CGRectMake(100, 100, 100, 100);

}

// 返回button的颜色

- (UIColor *)mediaPlayPauseButtonTintColor{

return [UIColor blueColor];

}

通过上面的代码,我们的button已经可以显示出来了。如下图(请忽略下面的策略等按钮):

具体位置,大家可以通过重写frame来确定button的位置。

当我们点击这个蓝色button的时候,便可以执行一些播放暂停操作了,如下

- (void)mediaPlay{

NSLog(@"mediaPlay,开始播放");

}

- (void)mediaPause{

NSLog(@"mediaPause,暂停播放");

}

说道这里,还少说一个地方,那就是NSExtensionContext类的播放暂停事件我们需要什么时候调用呢?

经过我的研究,可以这么使用,如下

- (void)mediaPlay{

NSLog(@"mediaPlay,开始播放");

// 点击播放按钮后,4s后暂停播放

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.extensionContext mediaPlayingPaused];

});

}

- (void)mediaPause{

NSLog(@"mediaPause,暂停播放");

// 点击暂停按钮,10s后开始播放

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.extensionContext mediaPlayingStarted];

});

}

这里需要说几个注意点

1.在这个控制器中,我们可以直接电泳self.extensionContext,来调用它的播放暂停方法。

2.调用这个播放暂停方法,并不会重新调用- (void)mediaPlay{}或者- (void)mediaPause{},只能单纯的调用。经过我的测试,

- (void)mediaPlayingStarted{

NSLog(@"主动调用开始的方法");

}

- (void)mediaPlayingPaused

{

NSLog(@"主动调用暂停的方法");

}

用上述代码,是监听不到方法点击的哟~

有了自定义内容,自然也就有了自定义的action(行为),我明日补上~谢谢大家咯~

如果你喜欢我的文章,不要忘记关注我,谢谢大家了~

另外如果你要转载,希望可以注明出处,我会写出更多更好的文章,来回馈大家~

demo地址

https://github.com/CoderWQ/XZPushTest/tree/master

时间: 2024-10-22 11:06:16

iOS10 推送必看 UNNotificationContentExtension的相关文章

iOS10推送必看UNNotificationServiceExtension

转:http://www.cocoachina.com/ios/20161017/17769.html (收录供个人学习用) iOS10推送UNNotificationServic 招聘信息: 产品经理/Product Manager Unity开发工程师 高级iOS工程师 SDK产品经理 cocos2d-x游戏开发工程师 iOS高级开发工程师 [成都 | 远程办公] 招聘Android工程师 技术合伙人 移动应用开发项目经理 iOS开发工程师 移动APP研发工程师 如果大家还没有看我的这两篇文

iOS开发 iOS10推送必看

iOS10更新之后,推送也是做了一些小小的修改,下面我就给大家仔细说说.希望看完我的这篇文章,对大家有所帮助. 一.简单入门篇---看完就可以简单适配完了 相对简单的推送证书以及环境的问题,我就不在这里讲啦,我在这里说的,是指原有工程的适配. 1.首先我们需要打开下面的开关.所有的推送平台,不管是极光还是什么的,要想收到推送,这个是必须打开的哟~ QQ20160914-4.png 之后,系统会生成一个我们以前没见过的文件,如图: QQ20160918-0.png-5.8kB QQ20160918

iOS10推送必看UNNotificationAttachment以及UNTimeIntervalNotificationTrigger

虽然这篇文章比较长,也不好理解,但是还是建议大家收藏,以后用到的时候,可以看看,有耐心的还是读一读. 这篇文章开始,我会跟大家好好讲讲,苹果新发布的iOS10的所有通知类. 一.创建本地通知事例详解: 注意啊,小伙伴们,本地通知也必须在appdelegate中注册中心,通知的开关打不打开无所谓的,毕竟是本地通知,但是通知的接收的代理,以及通知点击的代理,苹果给合二为一了.所以大家还是需要在appdelegate中写上这2个方法,还有不要忘记在- (BOOL)application:(UIAppl

iOS10 推送必看(基础篇)

来源:徐不同 链接:http://www.jianshu.com/p/f5337e8f336d iOS10更新之后,推送也是做了一些小小的修改,下面我就给大家仔细说说.希望看完我的这篇文章,对大家有所帮助. 一.简单入门篇—看完就可以简单适配完了 相对简单的推送证书以及环境的问题,我就不在这里讲啦,我在这里说的,是指原有工程的适配. 1.首先我们需要打开下面的开关.所有的推送平台,不管是极光还是什么的,要想收到推送,这个是必须打开的哟~ 之后,系统会生成一个我们以前没见过的文件,如图: 可能产生

iOS 10 推送必看(高阶1)

来源:徐不同 链接:http://www.jianshu.com/p/3d602a60ca4f iOS10 推送必看(基础篇) 虽然这篇文章比较长,也不好理解,但是还是建议大家收藏,以后用到的时候,可以看看,有耐心的还是读一读. 这篇文章开始,我会跟大家好好讲讲,苹果新发布的iOS10的所有通知类. 一.创建本地通知事例详解: 注意啊,小伙伴们,本地通知也必须在appdelegate中注册中心,通知的开关打不打开无所谓的,毕竟是本地通知,但是通知的接收的代理,以及通知点击的代理,苹果给合二为一了

iOS10推送通知适配

iOS10推送新增了UserNotifications Framework,使用起来其实很简单. 只是在iOS10以上系统上点击通知栏,回调方法不再走原来的这两个方法 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { } - (void)application:(UIApplication *)application didReceive

Xcode8开发iOS10推送通知过程

iOS10发布后,简书优先开发增加了iOS10的新通知.本文分享整个feature的开发过程遇到的问题. 1.工程配置 Xcode8发生了很大的变化,直接打开原来的工程编译运行,这个时候是获取不到Push token的,打印didFailToRegisterForRemoteNotificationsWithError中的error可以看到 fail to register with error Error Domain=NSCocoaErrorDomain Code=3000 "no vali

1011 ios10 推送问题

2016-10-11 10:22:02.090 Patient[599:60b] You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgr

Android消息推送:手把手教你集成小米推送

前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 该文档基于小米推送官方Demo,并给出简易推送Demo 看该文档前,请先阅读我写的另外两篇文章: 史上最全解析Android消息推送解决方案 Android推送:第三方消息推送平台详细解析 目录 1. 官方Demo解析 首先,我们先对小米官方的推送Demo进行解析. 请先到官网下载官方Demo和SDK说明文档 1.1 Demo