#12UserNotificationCenter

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)
}

參考文章:

程式碼:

--

--