今天的內容一樣是代辦清單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