推播通知 UserNotifications with iOS 10 up
來使用推播傳遞你的心聲吧!
在iOS 10 之後,原本推播使用的LocalNotification已經被取代了。
今天來練習的就是目前最新的推播中心。
首先,要記得引入新的Modal: UserNotifications
import UserNotifications
接著,要建立一個常數來當作整個推播的控制中心
let center = UNUserNotificationCenter.current()
存取權限
既然是推播通知,那請一定要記得取得使用著的權限,才不會讓使用者收不到你辛辛苦苦寫好的通知。
取得使用者權限的程式碼,我是直接寫在 AppDelegate.swift裡的
application:didFinishLaunchingWithOptions:
讓使用者在開啟程式後就能選擇是否授權。
在通知的類別: Types的方面,總共有四種,分別是:alert, sound, badge, carPlay。
在貼上程式碼之前,要先來說一下在 UNUserNotificationCenter控制中心裡面的setting,必須要用 function
getNotificationSettings(CompletionHandler:)
才能進行讀取。
(而不是像以前一樣設定一個常數為notificationSetting)
在 AppDelegate.swift中,使用到的是 settings.authorizationStatus,在這之中,一共有三種狀況,分別是 .notDetermined, .authorized, .denied。
而現在的目的是取得使用者的授權,也就是在使用者第一次執行App時,還在 .notDetermined的狀態
self.center.requestAuthorization(options: options) {
(granted, error) in
if !granted {
print("Something went wrong")
}
}
使用 requestAuthorization(options: completionHandler:) 來取得使用者的授權。
建立一個推播通知 Notification Request
一個通知由三個要素組成:identifier、content以及 trigger。
Notification Identifier
identifier就是你這通知的唯一身份證,如果多個通知用一樣的身份證,新的通知會取代舊的。
let identifier = "MyUniqueIdentifier"
Notification Content
當你建立一個通知時,需要建立一個 UNMutableNotificationContent並且設定其中的參數:
● title: 通知的標題,為字串 String。向使用者告知為何需要這則通知。
● subtitle: 副標題,為字串 String,為optional。
● body: 通知的內容,為字串 String,一樣是optional
● badge: 標記的數字,可以像某些日期App設定顯示的數字。
● sound: 通知顯示的鈴聲,使用UNNotificationSound.default()取得預設鈴聲。
● launchImageName: 這個參數我還沒實驗,這裡可以設定一個特定的圖片名稱或是Storyboard裡的特定View Controller,在使用者點選該通知時,就會顯示你指定的圖片/頁面。
● userInfo: 為Dictionary[String: Any]形式的資料型態,可顯示在通知中。
● attachments: 為一個內容為 UNNotificationAttachment的陣列 Array,可以儲存影片、圖片或是音源檔。
簡單的一個例子:
let content = UNMutableNotificationContent()
content.title = "It's a notification"
content.body = "Hello, what's up?"
content.sound = UNNotificationSound.default()
Notification Trigger
最後一個要素是觸發器,格式可以使用Time、Canlendar或是 Location。
同時可以設定是否重複。
● TimeInterval: 設定觸發器為一個timeInterval,讓通知在多少秒數後觸發:
let trigger = UITimeIntervalNotificationTrigger(timeInterval:60, repeats: false)
上面的例子中,秒數間隔為60秒。要注意的是秒數至少要超過60,才可以設定為repeats。
● Calendar: 設定觸發器為calendar的形式,有特定的日期和時間,同時可以更容易設定repeats:像是每日重複或是每週重複。
let date = Date(timeIntervalSinceNow: 36000)
let triggerDate = Canlendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false)
每日重複(每日同一時間、分,秒):
let triggerDaily = Calendar.current.dateComponents([.hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
每週重複,除了設定時間外還要再多設定一個weekday:
let triggerWeekly = Calendar.current.dateComponents([.weekday, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
● Location: 設定觸發器當使用者靠近或離開一個特定地點 CoreLocation CLRegion。
let triggerLocation = UNLocationNotificationTrigger(triggerWithRegion: region, repeats: false)
Scheduling a Notification Request
現在identifier、content,trigger都設定好後,就可以來建立通知了!
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let error = error {
//Make some error handling here
}
})
這樣就完成設定推播通知啦!
Custom Actions
設定特定的動作,讓使用者在接收到通知時,藉由這些動作觸發更多功能。
蘋果官方的文件:
Action要正常運作還需要設定控制中心的Delegate:
UNUserNotificationCenterDelegate
最後來要介紹UNUserNotificationCenterDelegate,在這之中一共有兩個 optional methods:
userNotificationCenter(_:willPresent:withCompletionHandler:)
第一個方法是在你的推播在使用其他的 App跳出時,會用什麼樣的方式 (UNNotificationPresentationOptions) 顯示。
我在這邊設定的是 [.alert, .sound, .badge],也就是包含通知本身,聲音以及標記。
你也可以設定 .none來忽略推播。
userNotificationCenter(_:didReceive:withCompletionHandler:)
第二個方法是來設定當使用者選擇了特定的 UNNotificationAction時,做出的反應。
在上面範例中,我是拿鬧鐘的貪睡功能 Snooze來練習,
在按了 Snooze Action後,即會再多產生一個一樣的推播通知,在5秒後產生。
在實作時,為了在建立通知時確認使用者是否有授權,再次叫出了 settings.authorizationStatus,如果是 .denied的情況,就會有個 Alert請使用者去開啟權限!
Pending & Delivered Notification
最後再提一下,在UNUserNotificationCenter中,還有幾個方法可以來變更、查看,刪除在佇列或已傳送的通知。
getPendingNotificationRequests(completionHandler:)
removePendingNotificationRequests(withIdentifiers:)
removeAllPendingNotificationRequests()
印出Pending的Request:
getDeliveredNotificationRequests(completionHandler:)
removeDeliveredNotificationRequests(withIdentifiers:)
removeAllDeliveredNotificationRequests()