如何 delay/debounce 定时器通知 (swift3)
how to delay/debounce notification on timer (swift3)
如果按下开始按钮,我的通知将继续每 30 秒消失一次。我想做的是,每次用户点击开始按钮时,倒计时都会重置,并且通知只会在按下开始按钮后的 30 秒内出现。因此,如果用户在 30 秒结束之前无限次点击开始按钮,用户将永远不会看到通知。
import UIKit
import UserNotifications
class ViewController: UIViewController,UNUserNotificationCenterDelegate {
var isGrantedAccess = false
private var timer = Timer()
func startTimer(){
let timeInterval = 30.0
if isGrantedAccess && !timer.isValid { //allowed notification and timer off
timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true, block: { (timer) in
self.sendNotification()
})}}
func stopTimer(){
//shut down timer
timer.invalidate()
//clear out any pending and delivered notifications
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}
func sendNotification(){
if isGrantedAccess{
let content = UNMutableNotificationContent()
content.title = "HIIT Timer"
content.body = "30 Seconds Elapsed"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "timer.category"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.001, repeats: false)
let request = UNNotificationRequest(identifier: "timer.request", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error{
print("Error posting notification:\(error.localizedDescription)")
}}}}
@IBAction func startButton(_ sender: UIButton) {
startTimer()
}
func timeString(time:TimeInterval) -> String {
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format: " %02i : %02i", minutes, seconds)
}
override func viewDidLoad() {
super.viewDidLoad()
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound]) { (granted, error) in
self.isGrantedAccess = granted
}
let stopAction = UNNotificationAction(identifier: "stop.action", title: "Stop", options: [])
let timerCategory = UNNotificationCategory(identifier: "timer.category", actions: [stopAction], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([timerCategory])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "stop.action"{
stopTimer()
}
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert,.sound])
}}
您只需要让定时器失效,重新安排即可。试试这个。
func startTimer(){
stopTimer()
let timeInterval = 30.0
if isGrantedAccess { //allowed notification and timer off
timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true, block: { (timer) in
self.sendNotification()
})
}
}
如果按下开始按钮,我的通知将继续每 30 秒消失一次。我想做的是,每次用户点击开始按钮时,倒计时都会重置,并且通知只会在按下开始按钮后的 30 秒内出现。因此,如果用户在 30 秒结束之前无限次点击开始按钮,用户将永远不会看到通知。
import UIKit
import UserNotifications
class ViewController: UIViewController,UNUserNotificationCenterDelegate {
var isGrantedAccess = false
private var timer = Timer()
func startTimer(){
let timeInterval = 30.0
if isGrantedAccess && !timer.isValid { //allowed notification and timer off
timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true, block: { (timer) in
self.sendNotification()
})}}
func stopTimer(){
//shut down timer
timer.invalidate()
//clear out any pending and delivered notifications
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}
func sendNotification(){
if isGrantedAccess{
let content = UNMutableNotificationContent()
content.title = "HIIT Timer"
content.body = "30 Seconds Elapsed"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "timer.category"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.001, repeats: false)
let request = UNNotificationRequest(identifier: "timer.request", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error{
print("Error posting notification:\(error.localizedDescription)")
}}}}
@IBAction func startButton(_ sender: UIButton) {
startTimer()
}
func timeString(time:TimeInterval) -> String {
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format: " %02i : %02i", minutes, seconds)
}
override func viewDidLoad() {
super.viewDidLoad()
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound]) { (granted, error) in
self.isGrantedAccess = granted
}
let stopAction = UNNotificationAction(identifier: "stop.action", title: "Stop", options: [])
let timerCategory = UNNotificationCategory(identifier: "timer.category", actions: [stopAction], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([timerCategory])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "stop.action"{
stopTimer()
}
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert,.sound])
}}
您只需要让定时器失效,重新安排即可。试试这个。
func startTimer(){
stopTimer()
let timeInterval = 30.0
if isGrantedAccess { //allowed notification and timer off
timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true, block: { (timer) in
self.sendNotification()
})
}
}