Swift - UserNotifications框架使用詳解7(自定義通知詳情視圖)

iOS 10?中添加了兩個與通知相關(guān)的?extension:Service Extension?和?Content Extension枣申。前者我在上文中已經(jīng)介紹過了讼呢,本文介紹下后者:可以用來自定義通知的詳細(xì)頁面視圖的?Content Extension蔗怠。

十五、創(chuàng)建 Notification Content Extension

1逃糟,操作步驟

(1)首先我們點(diǎn)擊"File" -> "New" -> "Target..."捷绑,使用?NotificationContent?的模板來創(chuàng)建一個?NotificationContent。

(2)使用模版創(chuàng)建完畢后劫谅,會自動生成如下三個文件:

(3)NotificationViewController.swift

這個是一個實現(xiàn)了?UNNotificationContentExtension?的?UIViewController?子類见坑。

該?extension?中有一個必須實現(xiàn)的方法?didReceive(_:)。當(dāng)系統(tǒng)需要顯示自定義樣式的通知詳情視圖時捏检,這個方法將被調(diào)用荞驴,然后我們可以在其中配置更新我們的?UI。

默認(rèn)生成的代碼如下:直接將通知內(nèi)容顯示在?label?中贯城。我們先不做修改熊楼。

import?UIKit

import?UserNotifications

import?UserNotificationsUI


class?NotificationViewController:?UIViewController,?UNNotificationContentExtension?{


????@IBOutlet?var?label:?UILabel?


????override?func?viewDidLoad() {

????????super.viewDidLoad()

????}


????func?didReceive(_ notification:?UNNotification) {

????????self.label?.text = notification.request.content.body

????}

}

(4)MainInterface.storyboard

這里定義了該?extension?對應(yīng)的詳情視圖?UI。

默認(rèn)生成的?UI?如下:只有一個?label?文本標(biāo)簽能犯。我們先不做修改鲫骗。

(5)Info.plist

這里指定了該?extension?的各種配置。我們可以通過?Info.plist?控制通知詳細(xì)視圖的尺寸踩晶,以及是否顯示原始的通知执泰。

要特別注意的是?UNNotificationExtensionCategory?這個?key?值,它指定這個通知樣式所對應(yīng)的?category?標(biāo)識符渡蜻。系統(tǒng)在接收到通知后會通過?category?標(biāo)識符先查找有沒有能夠處理這類通知的?content extension术吝,如果存在,那么就交給這個extension?來進(jìn)行處理茸苇。

默認(rèn)生成的?category?標(biāo)識符是?myNotificationCategory排苍。我們先不做修改。

2学密,使用樣例

(1)下面代碼在頁面加載完畢后會自動創(chuàng)建個?5?秒后的推送通知淘衙。注意的是我們將通知的?categoryIdentifier?設(shè)置成上面?content extension?的?category?標(biāo)識符。

import?UIKit

import?UserNotifications


class?ViewController:?UIViewController?{


????override?func?viewDidLoad() {

????????super.viewDidLoad()


????????//設(shè)置推送內(nèi)容

????????let?content =?UNMutableNotificationContent()

????????content.title =?"hangge.com"

????????content.body =?"做最好的開發(fā)者知識平臺"


????????//設(shè)置category標(biāo)識符

????????content.categoryIdentifier =?"myNotificationCategory"


????????//設(shè)置通知觸發(fā)器

????????let?trigger =?UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats:?false)


????????//設(shè)置請求標(biāo)識符

????????let?requestIdentifier =?"com.hangge.testNotification"


????????//設(shè)置一個通知請求

????????let?request =?UNNotificationRequest(identifier: requestIdentifier,

????????????????????????????????????????????content: content, trigger: trigger)


????????//將通知請求添加到發(fā)送中心

????????UNUserNotificationCenter.current().add(request) { error?in

????????????if?error ==?nil?{

????????????????print("Time Interval Notification scheduled: \(requestIdentifier)")

????????????}

????????}

????}


????override?func?didReceiveMemoryWarning() {

????????super.didReceiveMemoryWarning()

????}

}

(2)可以看到通知的詳情視圖已經(jīng)變成我們自定義的視圖了则果。

十六幔翰、自定義通知詳情視圖(并添加 UI 交互功能)

1,效果圖

(1)這里我們推送一條使用自定義詳情視圖的通知西壮,這個通知里其實包含了三條新聞資訊遗增。

(2)打開通知詳情時,會顯示第一條資訊的標(biāo)題款青、內(nèi)容摘要做修、以及相關(guān)圖片牡整。下方還有三個交互按鈕:

點(diǎn)擊“換一條”按鈕慷蠕,這個通知視圖會繼續(xù)顯示,不過內(nèi)容會切換成下一條資訊。

點(diǎn)擊“打開”按鈕欺殿,則自動打開應(yīng)用再沧。我們可以在程序中進(jìn)行下一步操作饶囚,比如打開對應(yīng)的新聞詳情頁面军援。

點(diǎn)擊”取消“按鈕,則自動清除通知屏箍,且不會打開應(yīng)用绘梦。

2,Notification Content Extension 配置

(1)MainInterface.storyboard

這里我們在視圖上添加兩個?Label?和一個?ImageView赴魁,分別用來顯示新聞資訊的標(biāo)題卸奉、內(nèi)容摘要、以及圖片颖御。

同時還要設(shè)置好各個組件的約束榄棵,并在代碼中做好?@IBOutlet?關(guān)聯(lián)。

(2)NotificationViewController.swift

我們在這里對詳情視圖進(jìn)行顯示和更新操作潘拱。特別注意的是疹鳄,雖然我們可以使用包括按鈕在內(nèi)的各種?UI?組件,但是系統(tǒng)不允許我們與這些?UI?進(jìn)行交互芦岂。點(diǎn)擊通知視圖本身會直接將我們導(dǎo)航到應(yīng)用中尚辑,因此我們需要通過?action?按鈕的方式來對視圖進(jìn)行更新。

didReceive(_:completionHandler:)方法介紹:

它是?UNNotificationContentExtension?的一個可選方法盔腔,它會在用戶選擇了某個?action?時被調(diào)用。我們可以根據(jù)情況給?completionHandler?傳遞不同的值實現(xiàn)不同操作:

如果需要更新詳情視圖月褥,可以選擇傳遞?.doNotDismiss?來保持通知繼續(xù)被顯示弛随。

如果沒有繼續(xù)顯示的必要,傳遞?.dismissAndForwardAction?會打開應(yīng)用宁赤,并把通知的?action?繼續(xù)傳遞給應(yīng)用的?UNUserNotificationCenterDelegate?中的?userNotificationCenter(:didReceive:withCompletionHandler)

而傳遞?.dismiss則直接將這個通知清除舀透,同時也不會打開這個應(yīng)用。

import?UIKit

import?UserNotifications

import?UserNotificationsUI


//資訊條目

struct?NewsItem?{

????let?title:?String

????let?abstract:?String

????let?url:?URL

}


class?NotificationViewController:?UIViewController,?UNNotificationContentExtension?{


????//顯示資訊標(biāo)題

????@IBOutlet?var?titleLabel:?UILabel!


????//顯示資訊內(nèi)容摘要

????@IBOutlet?weak?var?abstractLabel:?UILabel!


????//顯示資訊圖片

????@IBOutlet?weak?var?imageView:?UIImageView!


????//當(dāng)前顯示的資訊索引

????private?var?index:?Int?= 0


????//所有資訊條目

????var?items: [NewsItem] = []


????override?func?viewDidLoad() {

????????super.viewDidLoad()

????}


????//收到通知

????func?didReceive(_ notification:?UNNotification) {

????????//處理資訊條目

????????let?content = notification.request.content

????????if?let?news = content.userInfo["news"]?as? [[String:?String]] {

????????????for?i?in?0..<news.count {

????????????????let?title = news[i]["title"] ???""

????????????????let?abstract = news[i]["abstract"] ???""

????????????????let?url = content.attachments[i].url

????????????????let?presentItem =?NewsItem(title: title, abstract: abstract, url: url)

????????????????self.items.append(presentItem)

????????????}

????????}


????????//顯示第一條資訊

????????updateNews(index: 0)

????}


????//更新顯示的資訊內(nèi)容

????private?func?updateNews(index:?Int) {

????????let?item = items[index]


????????//更新標(biāo)題和內(nèi)容摘要

????????self.titleLabel!.text = item.title

????????self.abstractLabel.text = item.abstract


????????//更新圖片

????????if?item.url.startAccessingSecurityScopedResource() {

????????????self.imageView.image =?UIImage(contentsOfFile: item.url.path)

????????????item.url.stopAccessingSecurityScopedResource()

????????}


????????self.index = index

????}


????//Action按鈕點(diǎn)擊響應(yīng)

????func?didReceive(_ response:?UNNotificationResponse, completionHandler completion:

????????@escaping?(UNNotificationContentExtensionResponseOption) ->?Void) {

????????if?response.actionIdentifier ==?"change"?{

????????????//切換下一條資訊

????????????let?nextIndex = (index + 1) % items.count

????????????updateNews(index: nextIndex)

????????????//保持通知繼續(xù)被顯示

????????????completion(.doNotDismiss)

????????}?else?if?response.actionIdentifier ==?"open"?{

????????????//取消這個通知并繼續(xù)傳遞Action

????????????completion(.dismissAndForwardAction)

????????}?else?if?response.actionIdentifier ==?"dismiss"?{

????????????//直接取消這個通知

????????????completion(.dismiss)

????????}?else?{

????????????//取消這個通知并繼續(xù)傳遞Action

????????????completion(.dismissAndForwardAction)

????????}

????}

}

(3)extension?的?Info.plist

通知擴(kuò)展對應(yīng)的?category?標(biāo)識符這里不做修改决左。主要修改下?UNNotificationExtensionInitialContentSizeRatio?這個?key?值愕够,它是?UI?界面默認(rèn)的高寬比,將其修改成?0.8佛猛,這樣在界面出來的時候不會有很突兀的?frame?改變惑芭。

3,Notification Content Extension 使用

(1)AppDelegate.swift

這里要注意的是我們注冊一個通知?category继找,里面包含三個?Action?按鈕遂跟。

import?UIKit

import?UserNotifications


@UIApplicationMain

class?AppDelegate:?UIResponder,?UIApplicationDelegate?{


????var?window:?UIWindow?


????func?application(_ application:?UIApplication, didFinishLaunchingWithOptions

????????launchOptions: [UIApplicationLaunchOptionsKey:?Any]?) ->?Bool?{


????????UNUserNotificationCenter.current()

????????????.requestAuthorization(options: [.alert, .sound, .badge]) {

????????????????(accepted, error)?in

????????????if?!accepted {

????????????????print("用戶不允許消息通知。")

????????????}

????????}


????????//注冊category

????????registerNotificationCategory()


????????return?true

????}


????func?applicationWillResignActive(_ application:?UIApplication) {

????}


????func?applicationDidEnterBackground(_ application:?UIApplication) {

????}


????func?applicationWillEnterForeground(_ application:?UIApplication) {

????}


????func?applicationDidBecomeActive(_ application:?UIApplication) {

????}


????func?applicationWillTerminate(_ application:?UIApplication) {

????}


????//注冊一個category

????private?func?registerNotificationCategory() {

????????let?newsCategory:?UNNotificationCategory?= {

????????????//創(chuàng)建三個普通的按鈕action

????????????let?changeAction =?UNNotificationAction(

????????????????identifier:?"change",

????????????????title:?"換一條",

????????????????options: [])


????????????let?openAction =?UNNotificationAction(

????????????????identifier:?"open",

????????????????title:?"打開",

????????????????options: [.foreground])


????????????//創(chuàng)建普通的按鈕action

????????????let?cancelAction =?UNNotificationAction(

????????????????identifier:?"cancel",

????????????????title:?"取消",

????????????????options: [.destructive])


????????????//創(chuàng)建category

????????????return?UNNotificationCategory(identifier:?"myNotificationCategory",

??????????????????????????????????????????actions: [changeAction, openAction, cancelAction],

??????????????????????????????????????????intentIdentifiers: [], options: [])

????????}()


????????//把category添加到通知中心

????????UNUserNotificationCenter.current().setNotificationCategories([newsCategory])

????}

}

(2)ViewController.swift

我們同樣是頁面打開后就推送個?5?秒后的通知。注意的是這里會給通知添加附加信息(包含資訊標(biāo)題和內(nèi)容摘要)幻锁,以及資訊使用的圖片附件凯亮。

import?UIKit

import?UserNotifications


class?ViewController:?UIViewController?{


????override?func?viewDidLoad() {

????????super.viewDidLoad()


????????//設(shè)置推送內(nèi)容

????????let?content =?UNMutableNotificationContent()

????????content.body =?"今日資訊精選【2017-12-12】"


????????//設(shè)置通知category標(biāo)識符

????????content.categoryIdentifier =?"myNotificationCategory"


????????//設(shè)置通知附件圖片

????????let?imageNames = ["image1",?"image2",?"image3"]

????????let?attachments = imageNames.flatMap { name ->?UNNotificationAttachment??in

????????????if?let?imageURL =?Bundle.main.url(forResource: name, withExtension:?"png") {

????????????????return?try??UNNotificationAttachment(identifier:?"\(name)", url: imageURL,

?????????????????????????????????????????????????????options:?nil)

????????????}

????????????return?nil

????????}

????????content.attachments = attachments


????????//設(shè)置通知附加信息(資訊標(biāo)題和內(nèi)容摘要)

????????content.userInfo = ["news": [

????????????["title":?"全國人民喜迎油價上漲",

?????????????"abstract":?"據(jù)國內(nèi)多家測評機(jī)構(gòu)的分析,國內(nèi)成品油零售限價將迎來“兩連漲”..."],

????????????["title":?"房價同比下降城市大幅擴(kuò)容",

?????????????"abstract":?"70個大中城市中一二三線城市房價同比漲幅繼續(xù)回落哄尔。這意味著假消,往年..."],

????????????["title":?"比特幣市值再創(chuàng)新高",

?????????????"abstract":?"一項名為SegWit2X的技術(shù)取消升級,導(dǎo)致在本周一比特幣市值蒸發(fā)多達(dá)380億美元..."]

????????????]]


????????//設(shè)置通知觸發(fā)器

????????let?trigger =?UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats:?false)


????????//設(shè)置請求標(biāo)識符

????????let?requestIdentifier =?"com.hangge.testNotification"


????????//設(shè)置一個通知請求

????????let?request =?UNNotificationRequest(identifier: requestIdentifier,

????????????????????????????????????????????content: content, trigger: trigger)


????????//將通知請求添加到發(fā)送中心

????????UNUserNotificationCenter.current().add(request) { error?in

????????????if?error ==?nil?{

????????????????print("Time Interval Notification scheduled: \(requestIdentifier)")

????????????}

????????}

????}


????override?func?didReceiveMemoryWarning() {

????????super.didReceiveMemoryWarning()

????}

}

原文出自:www.hangge.com??轉(zhuǎn)載請保留原文鏈接:https://www.hangge.com/blog/cache/detail_1855.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岭接,一起剝皮案震驚了整個濱河市富拗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亿傅,老刑警劉巖媒峡,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異葵擎,居然都是意外死亡谅阿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門酬滤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來签餐,“玉大人,你說我怎么就攤上這事盯串÷乳埽” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵体捏,是天一觀的道長冠摄。 經(jīng)常有香客問我,道長几缭,這世上最難降的妖魔是什么河泳? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮年栓,結(jié)果婚禮上拆挥,老公的妹妹穿的比我還像新娘。我一直安慰自己某抓,他們只是感情好纸兔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著否副,像睡著了一般汉矿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上副编,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天负甸,我揣著相機(jī)與錄音流强,去河邊找鬼。 笑死呻待,一個胖子當(dāng)著我的面吹牛打月,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚕捉,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼奏篙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迫淹?” 一聲冷哼從身側(cè)響起秘通,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎敛熬,沒想到半個月后肺稀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡应民,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年话原,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诲锹。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡繁仁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出归园,到底是詐尸還是另有隱情黄虱,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布庸诱,位于F島的核電站捻浦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桥爽。R本人自食惡果不足惜默勾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望聚谁。 院中可真熱鬧,春花似錦滞诺、人聲如沸形导。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朵耕。三九已至,卻和暖如春淋叶,著一層夾襖步出監(jiān)牢的瞬間阎曹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留处嫌,地道東北人栅贴。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像熏迹,于是被迫代替她去往敵國和親檐薯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359