如果不迅速执行任何操作,如何重复本地通知

时间:2018-10-02 18:07:48

标签: ios swift uilocalnotification

我正在为本地通知实现代码。我的应用程序显示通知,它有两个按钮,两个按钮都有一些特定的动作。现在,我想在通知将显示且用户忽略通知且不单击任何按钮时进行操作,则它应在一分钟后重复通知。请告诉我该怎么做。

import UIKit
import UserNotifications


class ViewController: UIViewController, UNUserNotificationCenterDelegate {

    var isGrantedAccess = false
    let time:TimeInterval = 10.0
    var triggered = false

    @IBOutlet weak var checkinDateLbl: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(
            options: [.alert,.sound,.badge],
            completionHandler: { (granted,error) in
                self.isGrantedAccess = granted
                if granted{
                    self.setCategories()
                } else {
                    let alert = UIAlertController(title: "Notification Access", message: "In order to use this application, turn on notification permissions.", preferredStyle: .alert)
                    let alertAction = UIAlertAction(title: "Okay", style: .default, handler: nil)
                    alert.addAction(alertAction)
                    self.present(alert , animated: true, completion: nil)
                }
        })

    }


    @IBAction func saveBtn(_ sender: Any) {

        let checkin = checkinDateLbl.text
        if checkin == "0000-00-00 00:00:00" {
            if isGrantedAccess{
                let content = UNMutableNotificationContent()
                content.title = "Attendance Alert"
                content.body = "Please Check In"
                content.sound = UNNotificationSound.default()
                content.categoryIdentifier = "alarm.category"


                var datee = DateComponents()
                datee.hour = 21
                datee.minute = 50
                let triggerDate = UNCalendarNotificationTrigger(dateMatching: datee, repeats: true)
                addNotification(content: content, trigger: triggerDate , indentifier: "Alarm")




            }
        }
    }

    //MARK: - Functions
    func setCategories(){
        let snoozeAction = UNNotificationAction(identifier: "snooze", title: "Notify after 30 Minutes", options: [])
        let commentAction = UNTextInputNotificationAction(identifier: "comment", title: "Ignore", options: [])
        let alarmCategory = UNNotificationCategory(identifier: "alarm.category",actions: [snoozeAction,commentAction],intentIdentifiers: [], options: [])
        UNUserNotificationCenter.current().setNotificationCategories([alarmCategory])
    }

    func addNotification(content:UNNotificationContent,trigger:UNNotificationTrigger?, indentifier:String){
        let request = UNNotificationRequest(identifier: indentifier, content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request, withCompletionHandler: {
            (errorObject) in
            if let error = errorObject{
                print("Error \(error.localizedDescription) in notification \(indentifier)")
            }
        })

    }

    // MARK: - Delegates
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert,.sound])
    }
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let identifier = response.actionIdentifier
        let request = response.notification.request



        if identifier == "snooze"{
            let newContent = request.content.mutableCopy() as! UNMutableNotificationContent
            newContent.title = "Notification"
            newContent.body = "hi"



            let newTrigger = UNTimeIntervalNotificationTrigger(timeInterval: time, repeats: true)
            addNotification(content: newContent, trigger: newTrigger, indentifier: request.identifier)




        }

//        if identifier == "comment"{
//            UNUserNotificationCenter.current().removeAllDeliveredNotifications()
//
//        }

        completionHandler()
    }

}

1 个答案:

答案 0 :(得分:0)

当在后台实际收到但未点击本地通知时,没有回调到iOS应用。实现此目的的唯一方法是 -安排您的通知,然后每x分钟安排一次提醒通知列表 -当用户点击您的按钮时,删除所有“提醒”通知

我们唯一的问题是可以安排的本地通知数量有限。

import UIKit
import UserNotifications


class ViewController: UIViewController  {

    override func viewDidLoad() {

        super.viewDidLoad()

        UNUserNotificationCenter.current().delegate = self
        setCategories()

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge]) { granted, error  in

        }

        // 10 seconds from now
        var triggerComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date(timeInterval: 10, since: Date()))
        triggerComponents.calendar = Calendar.current


        let content = scheduleAlarm(title: "Alarm", body: "You will be reminded", atDate: triggerComponents)

        // Schedule 10 reminders every 10 seconds
        scheduleReminders(content: content, fromDate: triggerComponents, repeatCount: 10, every: 1, unit: .second)
    }


    func scheduleAlarm(title: String, body: String, atDate dateComponents: DateComponents) -> UNNotificationContent {
        let content = UNMutableNotificationContent()
        content.title = title
        content.body = body
        content.sound = UNNotificationSound.default
        content.categoryIdentifier = "alarm.category"

        let calendarTrigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
        addNotification(content: content, trigger: calendarTrigger , indentifier: "Alarm")

        return content
    }

    /**
     Schedules a serie of reminder notifications from an original notification
     - Parameter content: The content to be scheduled.
     - Parameter fromDate: The date at which was scheduled the original notification
     - Parameter repeatCount: The number of reminders to schedule
     - Parameter every: The interval at which the reminder should be scheduled
     - Parameter unit: The unit of the interval

    */
    func scheduleReminders(content: UNNotificationContent, fromDate dateComponents: DateComponents, repeatCount: Int, every: Int = 1, unit: Calendar.Component = .minute) {

        // schedule the reminders
        let calendar = Calendar.current
        guard let triggerDate = dateComponents.date else { fatalError() }
        for count in 1..<repeatCount {
            // Add the reminder interval and unit to the original notification
            guard let date = calendar.date(byAdding: unit, value: every * count, to: triggerDate)  else { fatalError() }

            let reminderDateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
            let reminderTrigger = UNCalendarNotificationTrigger(dateMatching: reminderDateComponents, repeats: false)
            addNotification(content: content, trigger: reminderTrigger , indentifier: "reminder-\(date.timeIntervalSince1970)")
        }
    }

    /// Removes all pending reminder notifications
    func removeReminderNotifications() {
        let center = UNUserNotificationCenter.current()
        center.getPendingNotificationRequests() { requests in
            // get all pending notifications with identifiers starting with "reminder"
            let reminderIdentifiers = requests.filter({ $0.identifier.starts(with: "reminder")}).map { $0.identifier }
            print("Removing pending reminders: \(reminderIdentifiers)")
            center.removePendingNotificationRequests(withIdentifiers: reminderIdentifiers)
        }
    }

    func setCategories() {
        let snoozeAction = UNNotificationAction(identifier: "snooze", title: "Notify after 30 Minutes", options: [])
        let commentAction = UNNotificationAction(identifier: "ignore", title: "Ignore", options: [])
        let alarmCategory = UNNotificationCategory(identifier: "alarm.category",actions: [snoozeAction,commentAction],intentIdentifiers: [], options: [])
        UNUserNotificationCenter.current().setNotificationCategories([alarmCategory])
    }

    func addNotification(content: UNNotificationContent, trigger: UNNotificationTrigger, indentifier: String) {
        print("Scheduling notification at \(trigger)")
        let request = UNNotificationRequest(identifier: indentifier, content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request) { error in
            if let error = error {
                print("Error \(error.localizedDescription) in notification \(indentifier)")
            }
        }
    }
}

extension ViewController: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert,.sound])
        UNUserNotificationCenter.current().getPendingNotificationRequests() { requests in
            print("Pending requests: \(requests.count)")

        }
    }
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        // the user tapped the ignore button, remove all reminders
        if response.actionIdentifier == "ignore" {
            removeReminderNotifications()
        }
        completionHandler()
    }
}

实际上,使用现在不推荐使用的UINotification曾经有一种更简单的方法,但是我不建议您使用不推荐使用的框架:https://openradar.appspot.com/26855019