Send a local notification when timer is up

北慕城南 提交于 2021-01-29 07:49:41

问题


I would like to send a local notification once 24 hours has passed after a button is selected. The button is currently only enabled once 24 hours has passed and the waiting time is saved in UserDegaults. I would like to know how I will be able to send a local notification to the user automatically once the 24 hours has passed.

 func getNextQuote(){
    let defaults = UserDefaults.standard

    defaults.integer(forKey: "savedIndexKey")
    let currentIndex = defaults.integer(forKey: "savedIndexKey")
    var nextIndex = currentIndex+1
    nextIndex = quotes.indices.contains(nextIndex) ? nextIndex : 0
    defaults.set(nextIndex, forKey: "savedIndexKey")
    let savedInteger = defaults.integer(forKey: "savedIndexKey")
    saved = savedInteger
    quotesLabel.text = quotes[savedInteger]
    self.quotesLabel.fadeIn()
    set24HrTimer()
    update()

}

  func update(){

    if let waitingDate = UserDefaults.standard.value(forKey: "waitingDate") as? Date{
        if let waitingDate = UserDefaults.standard.object(forKey: "waitingDate") as? Date,
            waitingDate < Date() {

        self.timeLabel.text = "Please check in for the day"
            self.remainingLabel.text = "Did you stay clean today?"
            self.remainingLabel.font = UIFont(name: "Arial", size: 32)
            self.quotesLabel.isHidden = true

            addButton.isHidden = false
            noButton.isHidden = false
            gridButton.isHidden = false
            self.view.setNeedsDisplay()
        print("time is up")

        }else if let waitingDate = UserDefaults.standard.value(forKey: "waitingDate") as? Date {
        self.timeLabel.attributedText = self.timeLeftExtended(date: waitingDate)
            addButton.isHidden = true
            noButton.isHidden = true
            gridButton.isHidden = true


            self.quotesLabel.isHidden = false
            self.remainingLabel.text = "Until next check in"
            self.quotesLabel.fadeIn()

            print("still running")

        }else{
            let newDate = Calendar.current.date(byAdding: .hour, value: 24, to: Date())
            UserDefaults.standard.set(newDate, forKey: "waitingDate")
            self.timeLabel.attributedText = self.timeLeftExtended(date: newDate!)
            print("last option")
        }

}
}

func set24HrTimer() {
    let currentDate = Date()
    let newDate = Date(timeInterval: 86400, since: currentDate as Date)
    UserDefaults.standard.setValue(newDate, forKey: "waitingDate")
    print("24 hours started")

}


 func timeLeftExtended(date:Date) ->NSAttributedString{

    let cal = Calendar.current
    let now = Date()
    let calendarUnits:NSCalendar.Unit = [NSCalendar.Unit.hour, NSCalendar.Unit.minute, NSCalendar.Unit.second]


    let components = cal.dateComponents([.hour, .minute, .second], from: now, to: date)
    let fullCountDownStr = "\(components.hour!)h \(components.minute!)m \(components.second!)s "

    let mutableStr = NSMutableAttributedString(string: fullCountDownStr, attributes: [NSAttributedString.Key.foregroundColor:UIColor.white])

    for (index, char) in mutableStr.string.enumerated()
    {
        if(char == "h" || char == "m" || char == "s")
        {
            mutableStr.removeAttribute(NSAttributedString.Key.foregroundColor, range: NSMakeRange(index, 1))
            mutableStr.addAttributes([NSAttributedString.Key.foregroundColor : UIColor.lightGray], range: NSMakeRange(index, 1))
        }
    }

    return mutableStr
}


func setupTimer()
{
    if(!timeWorking)
    {
        timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateCountDown), userInfo: nil, repeats: true)
        self.timeWorking = true
    }
}

回答1:


You shouldn't use a timer to trigger a local notification. This function could be added as an extension to UIViewController that will let you create a UNCalendarNotificationTrigger:

import UserNotifications
import UIKit

extension UIViewController {
    func createLocalNotification(title: String, hours: Int) {
        let seconds = hours * 3600
        let content = UNMutableNotificationContent()
        content.sound = UNNotificationSound.default
        content.title = title

        let nextTriggerDate = Calendar.current.date(byAdding: .second, value: seconds, to: Date())!

        let comps = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: nextTriggerDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: comps, repeats: false)
        let request = UNNotificationRequest(identifier: "\(seconds)", content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    }
}

And can be used within your UIViewController as follows:

let MyViewController: UIViewController {

    @IBAction func buttonPressed(_ sender: Any) {
        self.createLocalNotification(title: "24 hours have passed!", hours: 24)
    }

}


来源:https://stackoverflow.com/questions/58332313/send-a-local-notification-when-timer-is-up

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!