本地通知(Local Notification)

法蘭克的 iOS 世界
9 min readFeb 7, 2017

--

法蘭克為什麼要特別強調 iOS10,因為在 iOS10 之後使用通知的方式已不同以往了,Apple 整合並重構了原本復雜的 SDK,有關於通知的歷史法蘭克就不在此細說囉,有興趣的可以自行 Google 看看,把重點放在新的 SDK 上。然而就通知來說已是 App 不可或缺的功能之一了,例如 Facebook 的 APP,若有人在你的貼文上面留言或傳送訊息給您等等,手機桌面就會出現一條 Title 為 FaceBook 的訊息,這就是通知。

Desktop Notifacition

然而通知又可分本地通知遠程通知兩種,前者是透過使用者的手機系統所發送出來的,而後者則是要透過服務商發出的,遠程通知目前 Apple 自家和 Google 都有提供這樣的服務。遠程通知就 Apple(APNS) 來說則必須要有開發者的帳號才能享有此服務,因為這是必須在開發者後台設定才有辦法使用的;Google 則是在 Firebase 就有提供該服務,只要有 Google 帳號即可使用,相較之下是比較容易使用的,且也是目前唯一跨平台的解決方案。而今天法蘭克就要來說明如何建立本地通知和簡單的應用,遠程通知將會在下一篇文章介紹

內容大綱:

  1. 如何建立本地通知。
  2. 透過代理 UNUserNotificationCenterDelegate 讓通知可在前景模式下收到。
  3. 建立有圖片的本地通知。
  4. 建立點擊本地通知後所觸發的事件。

前置作業:

▼建立 Single View Application 的專案

▼專案名稱為 TestLocalNotification

1. 如何建立本地通知

1.1 在使用本地通知之前必須引入 UserNotifications 的套件,並且在一啟動 App 時就詢問使用者同不同意接受通知的選項

第 2 行 => import UserNotifications 的套件。

第 12 行 =>利用 UNUserNotificationCenter.current() 取得通知中心的物件,並呼叫 requestAuthorization(options:completionHandler:) 來詢問使用者是否接受圖文(alert)、聲音(sound)、數字(badge)三種類型的通知,並在使用者點選 Don’t Allow 或 Allow 後回傳一個閉包,granted true 則是選擇 Allow 反之為 Don’t Allow。

▼以下為啟動 App 詢問使用者同不同意接受通知的畫面:

若是使用者選擇 Don’t Allow,將無法接收到該 App 的通知且

以後啟動就再也不會詢問使用者了

唯一辦法就是使用者必須自行到 設定 → TestLocalNotification App 裡打開接受通知的設定…

備註:模擬器點選 comman + shift + H 可返回桌面

1.2 在 ViewController.swift 的 viewDidLoad 生成一個建立通知的按鈕,這邊的用意是當法蘭克點選該按鈕即會產生一個通知,當然大家也不一定要這麼做,可以在 viewDidLoad 就直接產生通知也是可以的

1.3 建立點擊建立通知按鈕觸發的事件

第 3 行 => 生成通知內容的物件。

第 4~6 行 => 設定通知的抬頭、主旨、內容。

第 7 行 => 設定 App Icon 顯示的數字。

第 8 行 => 設定收到通知的音效。

第 10 行 => 生成通知的 Trigger,第一個參數的單位為秒數,第二個參數可設定是否重覆發送,這邊法蘭克指定 5 秒後發送通知且不重覆發送,另外 Apple 為了避免有心人士一直發送通知,所以重覆發送通知的最小間隔秒數為 60 秒。除了可設定秒數來發送通知外,尚有其它發送通知的方式。

  • UNTimeIntervalNotificationTrigger = 每幾秒發送。
  • UNCalendarNotificationTrigger => 指定日期發送。
  • UNLocationNotificationTrigger => 當靠近某個位置時觸發。
  • UNPushNotificationTrigger => 從後台發送。

第 12 行 => 生成通知請求物件,並將剛剛生成的通知內容和觸發的時間點傳入。第一個參數的識別字可自行命名,這個識別字

很重要!很重要!很重要!因為它可以用來管理通知,除了新增外,也可以取消和修改已送出或未送出的通知

第二個參數則是剛剛設定的 UNMutableNotificationContent 物件,第三個參數為 UNTimeIntervalNotificationTrigger 物件。順帶一提通知不一定要有 Trigger 才會觸發,我們可以在第 3 個參數傳入 nil,該通知就會馬上被發送出去,就端看於情境為何。

let request = UNNotificationRequest(identifier: “notification”, content: content, trigger: nil)

以上都設定完成,啟動模擬器後,點選建立通知的按鈕,並點選 command + shift + H 切換至桌面等待通知的發送。

title、subtitle、body 等前綴字元是法蘭克刻意加上去好讓各位好辦識,App Icon 右上角的數字 1 即為 badge 的設定。

備註:務必切換至桌面才能接收到通知,後續會講解在前景模式也才收到通知的範例。

2. 透過遵循 UNUserNotificationCenter 的 delegate 讓通知可在前景模式下收到

前景模式指的是我們在操作該 App 或其它 App 的狀態下。若是沒有設定可在前景模式下收到通知,就會如同第一個範例必須切換至桌面才能接收到通知,如此有時會讓使用者錯失第一手的訊息,既然如此該設定是非做不可了。

首先必須讓 AppDelegate 代理 UNUserNotificationCenterDelegate,並遵循 userNotificationCenter 的協議

第 1 行 => 設定 AppDelegate 去代理 UNUserNotificationCenterDelegate。

第 18 行 => 設定 AppDelegate 去代理 UNUserNotificationCenterDelegate。

第 46 行 => App 在前景狀態時接收到通知所會觸發的 function。

第 47 行 => 純粹是法蘭克在前景收到通知時在 console 印出是否有執行該協議而己。

試著執行看看則會有以下的執行結果:

通知

3. 建立有圖片的本地通知

有時只有文字太過單調,需要圖片來豐富一下通知。非常簡單,我們只要在 UNMutableNotificationContent 的物件多設定一個附件的屬性即可達到。

3.1 找一張圖片並放置在 bundle 底下

3.2 設定 UNMutableNotificationContent.attachments 的屬性

加入第 10~13 行程式碼片段,其它同前一個範例不用做修改

第 11 行 => 取得 bundle 的圖片。

第 12 行 => 生成通知的附件,第一個參數可任意命名,第二個參數傳入第 11 行生成的物件。

第 13 行 => 設定 UNMutableNotificationContent 的屬性 attachments,將第 12 行生成的物件指定給它。

試著執行看看則會有以下的執行結果:

備註:拖曳通知可展開圖片

4. 建立點擊本地後所通知所觸發的事件

很多時侯我們必須實作這個功能,例如點擊這個通知直接開啟法蘭克的Facebook,法蘭克就用這個例子來講解。

4.1 設定 UNMutableNotificationContent.userinfo 的屬性

userinfo 的型別是 Dictionary,所以我們就可以利用 key、value 的方法去設定它,法蘭克在第 16 行加入 Facebook 的 link,其它同前一個範例不用做修改

4.2 實作點擊通知的協議

在 AppDelegate 下實作點擊通知的協議

第 3 行 => 取得 userInfo 的所有資料。

第 5 行 => 呼叫閉包的 func,該行若沒有實作則無法取得 userinfo 的資料。

第 8 行 => 取出 userInfo 的 link。

第 9行 => 開啟 Facebook 外部連結。

試著執行看看則會有以下的執行結果:

點擊通知

結論:

通知不僅僅只有法蘭克提到的這幾項功能,這幾項只是比較常用到的。其它尚有在通知的下面產生按鈕、通知的刪除等等較進階的功能是法蘭克沒提到的,下一篇法蘭克將要介紹遠程通知。此範例已放上 GitHub,若還有其它問題歡迎透過問與答的方式提出。

--

--