Если вы просто говорите, что хотите запустить таймер в каком-то определенном будущем Date
, вы должны просто рассчитать количество времени между настоящим моментом и временем (используя timeIntervalSince
), а затем использовать это.
Например, в настоящее время это «2019-01-20 17:11:59 +0000», но если я хочу, чтобы оно сработало в 17:15, вы можете сделать:
weak var timer: Timer?
func startTimer() {
let futureDate = ISO8601DateFormatter().date(from: "2019-01-20T17:15:00Z")!
let elapsed = futureDate.timeIntervalSince(Date()) // will be roughly 180.56 in this example at this moment of time
timer?.invalidate() // invalidate prior timer, if any
timer = Timer.scheduledTimer(withTimeInterval: elapsed, repeats: false) { [weak self] _ in
// whatever you want to do at 17:15
}
}
Ясно, что вы придумали futureDate
, в вашем случае все будет иначе, но это иллюстрирует идею. Просто рассчитайте время, прошедшее между будущей целевой датой и сейчас, и используйте его для таймера.
Теперь, если вы действительно беспокоитесь об изменениях часов, в iOS вы можете наблюдать significantTimeChangeNotification
, например,
NotificationCenter.default.addObserver(forName: UIApplication.significantTimeChangeNotification, object: nil, queue: .main) { [weak self] _ in
// do something, maybe `invalidate` existing timer and create new one
self?.startTimer()
}
Я подумал использовать do некоторое время, но думаю, что он будет сильно загружать процессор и батарею. нет?
Да, вращение в цикле, ожидание в течение некоторого времени, всегда плохая идея. Обычно вы просто устанавливаете таймер.
Эта функция вернет следующий курс студента, все курсы в массиве.
Возникает вопрос, будет ли приложение работать на переднем плане или нет. Если вы хотите уведомить пользователя в будущем, независимо от того, запускает ли оно приложение прямо сейчас или нет, рассмотрите « уведомления пользователя ». Например, запросите разрешение на уведомление:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
if !granted {
// warn the user that they won't be notified after the user leaves the app unless they grant permission for notifications
DispatchQueue.main.async {
let alert = UIAlertController(title: nil, message: "We need permission to notify you of your class", preferredStyle: .alert)
if let url = URL(string: UIApplication.openSettingsURLString) {
alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
UIApplication.shared.open(url)
})
}
alert.addAction(UIAlertAction(title: "Cancel", style: .default))
self.present(alert, animated: true)
}
}
}
А затем, предполагая, что разрешения были предоставлены, затем запланировать уведомление:
let content = UNMutableNotificationContent()
content.title = "ClassTime"
content.body = "Time to go to math class"
let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: futureDate)
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
let request = UNNotificationRequest(identifier: "Math 101", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)