#12UserNotificationCenter
Published in
17 min readDec 9, 2022
Apple程式範例檔21
程式功能:
- 允許推播通知
- 背景推播通知
- 前景推播通知
- 推播通知
實作技術功能:
- UNUserNotificationCenterDelegate
- UNNotificationAction
- UNNotificationCategory
- UNMutableNotificationContent
- willPresent
- didReceive
感想 :利用Apple程式範例檔,去本地化推播理解UserNotificationCenter,搭配彼得潘的文章,可以清楚理解推播的流程.看著推播通知出現,感覺還蠻有趣,挺可愛的功能.
讓我們開始Coding吧!
設定按鈕和Label
@IBOutlet var InfoLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
InfoLabel.font = UIFont.systemFont(ofSize: 20)
InfoLabel.text = "彼得潘愛你喔!😘"
//本地推播
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "允許推播", style: .plain, target: self, action: #selector(registerLocal))
//推播排程
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "推播", style: .plain, target: self, action: #selector(scheduleLocal))
}
詢問使用者許允推播嗎?
//詢問使用者許允推播嗎?
/*彼得潘的幸福通知同時包含感人的圖文(alert),好聽的聲音(sound),以及在 App Icon 顯示數字(badge),提醒使用者有新的通知。因此我們傳入 [.alert, .sound, .badge]。
completionHandler: 在使用者開心同意或狠心拒絕我們時執行,我們傳入 closure,將 closure 的參數取名為 granted 和 error。Bool 型別的 granted 告訴我們使用者是否同意,若有錯誤則可從 Error 型別的 error 了解錯誤原因。*/
//按下後執行 允許推播
@objc func registerLocal() {
//UNUserNotificationCenter 推播通知器
let center = UNUserNotificationCenter.current()
//執行requestAuthorization函式 回傳兩著參數
center.requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
if granted {
print("可推播")
DispatchQueue.main.async {
self.InfoLabel.text = "使用者同意了,開始收到連環推播訊息!😘"
}
} else {
print("不可以推播")
self.InfoLabel.text = "使用者不同意,不想看到推播"
}
}
}
開發者文件的參數
/*提供主要內容
var title: String
提供通知主要描述的本地化文字。
var subtitle: String
提供通知次要描述的本地化文字。
var body: String
提供通知主要內容的本地化文字。
提供補充內容
var attachments: [UNNotificationAttachment]
與通知的主要內容一起顯示的視覺和音訊附件。
var userInfo: [AnyHashable : Any]
與通知關聯的自定義資料。
配置應用程式行為
var launchImageName: String
由於通知,當您的應用程式啟動時要使用的影象或故事板的名稱。
var badge: NSNumber?
您的應用程式圖示顯示的數字。
var targetContentIdentifier: String?
您的應用程式用於確定要顯示哪個場景來處理通知的值。
與系統整合
var sound: UNNotificationSound?
系統發出通知時播放的聲音。
var interruptionLevel: UNNotificationInterruptionLevel
通知的重要性和所需的交付時間。
enum UNNotificationInterruptionLevel
指示通知重要性和交付時間的常量。
var relevanceScore: Double
系統用於確定通知是否是摘要的特色通知的分數。
var filterCriteria: String?
系統評估的標準,以確定它是否在當前Focus中顯示通知。
分組通知
var threadIdentifier: String
對相關通知進行分組的識別符號。
var categoryIdentifier: String
通知類別的識別符號。
var summaryArgument: String
系統新增到通知摘要中的文字,以提供額外的上下文。
var summaryArgumentCount: Int
當通知代表多個專案時,系統新增到通知摘要中的數字。
*/
設計按下推播後,出現的按鈕
//提示類別 設計兩個按鈕
func registerCategories() {
let center = UNUserNotificationCenter.current()
center.delegate = self
let show = UNNotificationAction(identifier: "show", title: "彼得潘愛心😍", options: .foreground)
//Challenge 2
let remindLater = UNNotificationAction(identifier: "remindLater", title: "彼得潘小王子🤓", options: .foreground)
//類別通知器
let category = UNNotificationCategory(identifier: "alarm", actions: [show,remindLater], intentIdentifiers: [], options: [])
//設定類別選擇器
center.setNotificationCategories([category])
}
@objc func scheduleLocal() {
registerCategories()
let center = UNUserNotificationCenter.current()
//移除requestAuthorization
center.removeAllPendingNotificationRequests()
//本地化通知器
//跳出通知
let content = UNMutableNotificationContent()
//標題
content.title = "彼得潘推播"
content.body = "現在報名課程,說潘世穎老師的名字,課程直接打5折🥳🥳🥳"
// var categoryIdentifier: String
// 通知類別的識別符號。
//呼叫上述的類別通知器
content.categoryIdentifier = "alarm"
// var userInfo: [AnyHashable : Any]
// 與通知關聯的自定義資料。
content.userInfo = ["customData": "fizzBuzz"] //This is to identify the notification user came through to the app.
content.sound = .default
//圖片不能放在Assets,要放在檔案裡面,不然會讀不到
let imageURL = Bundle.main.url(forResource: "pic", withExtension: "jpg")
//圖片放在UNNotificationAttachment
let attachment = try! UNNotificationAttachment(identifier: "", url: imageURL!, options: nil)
content.attachments = [attachment]
//設定日期推播
var dateComponents = DateComponents()
dateComponents.hour = 11
dateComponents.minute = 53
//可以設定定點出現推播通知
// let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
/*其實總共有四種方法可以觸發通知,UNTimeIntervalNotificationTrigger 只不過是其中一種,有興趣的朋友可進一步研究以下幾種不同的方法 :
UNTimeIntervalNotificationTrigger: 幾秒鐘後觸發。
UNCalendarNotificationTrigger: 指定某個時刻觸發。(相關程式碼連結)
UNLocationNotificationTrigger: 使用者靠近某個位置時觸發。比方當你靠近彼得潘家時,手機馬上會收到通知,提醒你找彼得潘喝下午茶。
UNPushNotificationTrigger: 從千里之外的後台傳送到使用者手機的通知,比方彼得潘失戀時緊急發送給大家的討拍拍通知。*/
//觸發,在五秒鐘之後
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
//通知器的request 參數trigger是nil的話=立即推播
//通知器的request 參數trigger是trigger的話 裡面條件的推播
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
//把本地化通知器 加入通知器
center.add(request)
}
前景通知
//前景通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
//如果有字典,
if let customData = userInfo["customData"] as? String {
print("customData received \(customData)")
switch notification.request.identifier {
case UNNotificationDefaultActionIdentifier:
//User swiped on the notification to unlock
print("default action")
let ac = UIAlertController(title: "預設推播", message: "打開了彼得潘App", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
case "show":
print("show more information...")
InfoLabel.text = "彼得潘超棒😀"
let ac = UIAlertController(title: "彼得潘大神", message: "課程資訊就在網上😄", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
case "remindLater":
print("Remind me later action pressed")
InfoLabel.text = "期待嗎?🤗"
let ac = UIAlertController(title: "彼得潘", message: "彼得潘的推播明天就來囉!!", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
remindMeLater()
default:
break
}
}
completionHandler([.badge, .sound, .banner])
}
背景推播
/*判斷使用者點選通知的哪一個按鈕
要判斷使用者點選哪一個按鈕,可以修改 userNotificationCenter(_:didReceive:withCompletionHandler:),加入以下程式碼,從 response.actionIdentifier 判斷使用者點選哪一個按鈕。*/
//設定按鈕和 背景通知
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
//如果有字典,
if let customData = userInfo["customData"] as? String {
print("customData received \(customData)")
switch response.actionIdentifier {
case UNNotificationDefaultActionIdentifier:
//User swiped on the notification to unlock
print("default action")
//Challenge 1
let ac = UIAlertController(title: "預設推播", message: "打開了彼得潘App", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
case "show":
print("show more information...")
InfoLabel.text = "彼得潘超棒😀"
//Challenge 1
let ac = UIAlertController(title: "彼得潘大神", message: "網上有課程資訊😄", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
//Challenge 2
case "remindLater":
print("Remind me later action pressed")
InfoLabel.text = "期待嗎?🤗"
let ac = UIAlertController(title: "彼得潘", message: "彼得潘的推播明天就來囉!!", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
remindMeLater()
default:
break
}
}
completionHandler()
}
明天的通知
//另一個推播通知
func remindMeLater() {
registerCategories()
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
let content = UNMutableNotificationContent()
content.title = "彼得潘推播"
content.body = "現在報名課程,說潘世穎老師的名字,課程直接打5折"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzBuzz"]
content.sound = .default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 86400, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
參考文章:
程式碼: