我想在选择按钮后24小时后发送本地通知。该按钮当前仅在24小时后启用一次,等待时间保存在UserDegaults中。我想知道我将如何能够发送一个本地通知,一旦24小时过去了用户自动。

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

最佳答案

不应该使用计时器触发本地通知。此函数可以作为UIViewController的扩展添加,它将允许您创建一个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)
    }
}

可以在UIViewController中使用,如下所示:
let MyViewController: UIViewController {

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

}

10-08 15:05