ios - 当设备时间改变时执行一个函数
问题描述
当设备时钟改变时,我试图执行一个函数。这个函数将返回一个学生的下一门课程,所有课程都在一个数组中。
如果我理解正确,当设备的时钟发生变化时,我们无法执行函数。我读了一些主题,人们说要进行 60 秒或其他时间的计时器,但是如果用户在 08:05:07 启动应用程序,则函数将在 7 秒后执行。我想使用一段时间,但我认为它会大量使用 CPU,因此也会消耗电池。不 ?
有人有想法吗?
解决方案
如果你只是说你想在某个特定的未来触发一个计时器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()
}
我想使用一段时间,但我认为它会大量使用 CPU,因此也会消耗电池。不 ?
是的,循环旋转,等待一段时间过去,总是一个坏主意。通常,您只需设置一个计时器。
这个函数将返回一个学生的下一门课程,所有课程都在一个数组中。
这就引出了应用程序是否会在前台运行的问题。如果您想在未来某个时间通知用户,无论他们是否正在运行应用程序,请考虑“用户通知”。例如请求通知权限:
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)
推荐阅读
- python - Python:努力使用 unicode 字符转换 .txt 文件
- rust - /usr/bin/link: 编译位标志时在 '\377\376"' 之后缺少操作数
- java - 如何找到在我的 mac 上下载的 JDK 的路径?
- c++ - 从 QT Creator 中运行的 QT+openCV 项目构建一个独立的 exe 文件
- javascript - 用对象数组更新对象数组
- javascript - 从 Html 文件 HtmlService.createHtmlOutputFromFile 内部调用脚本
- postgresql - Google 签名令牌 - 请求签名无效 (Postgresql)
- python - Python3搜索正在运行的windows进程的虚拟内存
- javascript - 如何更新firestore中数组内的对象?
- git - 在 TeamCity 构建完成器触发器中定义分支模式