今天的內容一樣是代辦清單App,已經介紹過了推播通知的功能,現在我們要先增一個定時提醒的功能,並在提醒時間到時,發出推播通知。
現在,我們馬上開始!
主要是推播功能相關代碼,請參考Day31的文章,這邊僅列出修改要點
Day31 石虎的推播通知
https://ithelp.ithome.com.tw/articles/10228613
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 前景通知
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
if granted {
print("使用者同意接收推播通知")
}
}
return true
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent
notification: UNNotification, withCompletionHandler completionHandler: @escaping
(UNNotificationPresentationOptions) -> Void) {
completionHandler([.badge, .sound, .alert])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response:
UNNotificationResponse, withCompletionHandler completionHandler: @escaping () ->
Void) {
let content = response.notification.request.content
print("title \(content.title)")
print("userInfo \(content.userInfo)")
print("actionIdentifier \(response.actionIdentifier)")
completionHandler()
}
}
這邊UI的設計思維,是一開始先將日期的元件隱藏,等到Switch開關打開後,再顯示
而推播的通知也跟者Save功能,一起被送出
@IBAction func dateSwitchChanged(_ sender: UISwitch) {
//countDatePicker.isHidden = !sender.isOn
if sender.isOn {
taskDatePicker.isHidden = false
} else {
taskDatePicker.isHidden = true
}
}
註解的一行寫法意思一樣,不過保留原寫法比較好閱讀
當開關打開,Date Picker也跟者顯示
@IBAction func saveButtonPressed(_ sender: UIButton) {
guard let content = taskTextField.text,
let id = todo?.id else { return }
if !content.isEmpty {
let filter = "id == '\(id)' and status != 'deleted'"
let realm = try! Realm()
guard let realmTodo = RealmHelper.loadToDoListWithFilter(filter: filter) .first else { return }
try! realm.write {
realmTodo.content = content
}
if dateSwitch.isOn {
let date = taskDatePicker.date
let components = Calendar.current.dateComponents([ .year, .month, .day, .hour, .minute], from: date)
print("date: \(date)")
print("conponents: \(String(describing: components.date))")
let notificationContent = UNMutableNotificationContent()
notificationContent.title = content
notificationContent.body = "任務將於 \(date) 到期"
notificationContent.badge = 3
notificationContent.sound = UNNotificationSound.default
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
let request = UNNotificationRequest(identifier: "todoNotification", content: notificationContent, trigger:
trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else {
// remove notifications
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ["todoNotification"])
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["todoNotification"])
}
// return List
navigationController?.popViewController(animated: true)
}
}
先判斷開關是否有開啟(dateSwitch.isOn),有開啟才加入通知
開關沒有開啟就取消通知
簡單地用任務名稱當作title
內容用『任務將於 (date) 到期』來顯示
這邊只列出編輯的代碼,新增的也是差不多
編輯任務
等待通知
推播通知提醒
今天我們練習將特定時間推播通知的功能,整合到ToDoList專案內,當中卡了一些時間,處理時區的問題。由於時間的關係,新增相關的UI/程式碼的部分尚未實作,就留給有興趣的讀者們去完成。
此篇剛好也作為整個鐵人賽的Ending。
今天的內容就到這邊,感謝讀者們的閱讀。
https://github.com/chiron-wang/IT30_11
深入淺出 iPhone 開發 (使用 Swift4) - WeiWei
https://www.udemy.com/course/iphone-swift4/
iOS 12 App 開發快速入門與實戰(繁體中文)
https://www.udemy.com/course/ios-12-app/
心智圖軟體Xmind
https://www.xmind.net/
apple doc datepicker
https://developer.apple.com/documentation/uikit/uidatepicker
swift起步走
https://itisjoe.gitbooks.io/swiftgo/content/uikit/uidatepicker.html