You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
3.1 KiB
77 lines
3.1 KiB
//
|
|
// CountdownScheduler.swift
|
|
// Countdown
|
|
//
|
|
// Created by Laurent Morvillier on 15/01/2023.
|
|
//
|
|
|
|
import Foundation
|
|
import UserNotifications
|
|
|
|
class CountdownScheduler {
|
|
|
|
static let master = CountdownScheduler()
|
|
|
|
static let notificationIdSeparator: String = "||"
|
|
|
|
func scheduleIfPossible(countdown: Countdown, handler: @escaping (Result<Date?, Error>) -> Void) {
|
|
DispatchQueue.main.async {
|
|
self.cancelCurrentNotifications(countdownId: countdown.stringId)
|
|
Conductor.maestro.startCountdown(countdown: countdown, handler: handler)
|
|
self._scheduleCountdownNotification(countdown: countdown, handler: handler)
|
|
}
|
|
}
|
|
|
|
fileprivate func _scheduleCountdownNotification(countdown: Countdown, handler: @escaping (Result<Date?, Error>) -> Void) {
|
|
let content = UNMutableNotificationContent()
|
|
content.title = NSLocalizedString("It's time!", comment: "")
|
|
|
|
let duration = countdown.duration
|
|
let body: String
|
|
if let name = countdown.activity?.name {
|
|
let timesup = NSLocalizedString("Time's up for %@!", comment: "")
|
|
body = String(format: timesup, name)
|
|
} else {
|
|
let timesup = NSLocalizedString("Your %@ countdown is over!", comment: "")
|
|
body = String(format: timesup, duration.minuteSecond)
|
|
}
|
|
|
|
content.body = body
|
|
|
|
self._createNotification(countdown: countdown, content: content, handler: handler)
|
|
|
|
// content.sound = UNNotificationSound.criticalSoundNamed(UNNotificationSoundName(rawValue: sound), withAudioVolume: 1.0)
|
|
// content.interruptionLevel = .critical
|
|
content.relevanceScore = 1.0
|
|
|
|
}
|
|
|
|
fileprivate func _createNotification(countdown: Countdown, offset: TimeInterval = 0.0, content: UNMutableNotificationContent, handler: @escaping (Result<Date?, Error>) -> Void) {
|
|
|
|
let duration = countdown.duration
|
|
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: duration + offset, repeats: false)
|
|
|
|
let identifier: String = [countdown.objectID.uriRepresentation().absoluteString, "\(offset)"].joined(separator: CountdownScheduler.notificationIdSeparator)
|
|
|
|
let request = UNNotificationRequest(identifier: identifier,
|
|
content: content,
|
|
trigger: trigger)
|
|
UNUserNotificationCenter.current().add(request) { error in
|
|
DispatchQueue.main.async {
|
|
if let error {
|
|
handler(.failure(error))
|
|
print("Scheduling error = \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func cancelCurrentNotifications(countdownId: String) {
|
|
UNUserNotificationCenter.current().getPendingNotificationRequests { requests in
|
|
let ids = requests.map { $0.identifier }.filter { $0.hasPrefix(countdownId) }
|
|
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ids)
|
|
}
|
|
}
|
|
|
|
}
|
|
|