iOS app实现定时提示使用时间到期(如20分钟),核心依赖于 Local Notification(本地通知) 功能,无需依赖服务器,所有定时逻辑均在设备本地完成,支持App前台、后台甚至退出状态下的通知推送。本文将详细讲解20分钟定时通知的完整实现流程,包括权限申请、通知配置、定时任务设置与回调处理。
UserNotifications(iOS 10及以上推荐使用)// 导入本地通知框架
import UserNotifications
// 遵守通知相关代理协议(处理通知回调)
class ViewController: UIViewController, UNUserNotificationCenterDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// 设置通知代理(接收通知回调)
UNUserNotificationCenter.current().delegate = self
}
}
在App首次启动或需要使用定时提醒功能时,向用户申请本地通知权限,只有获得授权后,才能推送通知给用户。
// 申请本地通知权限
func requestNotificationPermission() {
// 定义需要申请的通知权限类型
let authOptions: UNAuthorizationOptions = [.alert, .sound, .badge]
// 向用户申请权限
UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { (granted, error) in
DispatchQueue.main.async {
if granted {
// 用户授权成功,可创建并发送定时通知
print("本地通知授权成功")
// 立即创建20分钟后的使用时间提醒通知
self.create20MinutesLaterNotification()
} else {
// 用户拒绝授权,提示用户前往设置开启
print("本地通知授权失败:\(error?.localizedDescription ?? "未知错误")")
self.showNotificationPermissionTips()
}
}
}
}
// 提示用户前往设置开启通知权限
func showNotificationPermissionTips() {
let alert = UIAlertController(title: "通知权限申请失败", message: "请前往「设置」→「本App」→「通知」中开启通知权限,以接收使用时间提醒", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "前往设置", style: .default, handler: { _ in
// 跳转至系统设置的本App通知页面
if let settingsUrl = URL(string: UIApplication.openSettingsURLString) {
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl)
}
}
}))
alert.addAction(UIAlertAction(title: "取消", style: .cancel))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
}
授权成功后,创建本地通知内容、设置20分钟定时触发器,最后将通知发送到系统通知中心。
定义通知的标题、副标题、正文、声音等内容,贴合「使用时间到期提醒」的场景。
使用 UNTimeIntervalNotificationTrigger 构建时间间隔触发器,设置时间间隔为20分钟(1200秒)。
// 创建20分钟后的使用时间提醒通知
func create20MinutesLaterNotification() {
// 1. 构建通知内容
let notificationContent = UNMutableNotificationContent()
notificationContent.title = "使用时间提醒"
notificationContent.subtitle = "20分钟使用时长已到期"
notificationContent.body = "您已连续使用本App 20分钟,建议休息5分钟,保护眼睛哦~"
notificationContent.sound = UNNotificationSound.default // 通知提示音
notificationContent.badge = 1 // App图标角标(显示数字1)
// 2. 设置定时触发器:20分钟后(1200秒),不重复
let timeInterval: TimeInterval = 20 * 60 // 20分钟 = 1200秒
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval, repeats: false)
// 3. 创建通知请求(唯一标识:用于后续取消通知)
let notificationId = "UsageTimeReminder_20Minutes"
let notificationRequest = UNNotificationRequest(identifier: notificationId, content: notificationContent, trigger: trigger)
// 4. 发送通知请求到系统通知中心
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
if let error = error {
print("发送20分钟定时通知失败:\(error.localizedDescription)")
} else {
print("20分钟定时通知已创建成功,将在20分钟后推送")
}
}
}
实现代理方法,处理通知的回调事件,包括App在前台时的通知展示、用户点击通知后的跳转逻辑。
// 当App在前台时,收到本地通知的回调(控制是否展示通知)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// 即使App在前台,也展示通知(包含提示音、横幅)
completionHandler([.alert, .sound, .badge])
}
// 当用户点击通知(横幅/通知中心)后的回调
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// 获取通知唯一标识,判断是否为使用时间提醒通知
let notificationId = response.notification.request.identifier
if notificationId == "UsageTimeReminder_20Minutes" {
print("用户点击了20分钟使用时间提醒通知")
// 执行点击后的逻辑(如跳转至休息页面、展示统计数据等)
self.jumpToRestPage()
}
// 必须调用完成回调
completionHandler()
}
// 跳转至休息提示页面
func jumpToRestPage() {
let restVC = RestViewController()
restVC.title = "休息一下吧"
self.navigationController?.pushViewController(restVC, animated: true)
}
若用户在20分钟内主动结束使用,可取消已创建的定时通知,避免不必要的提醒。
// 取消20分钟定时通知
func cancel20MinutesNotification() {
let notificationId = "UsageTimeReminder_20Minutes"
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [notificationId])
print("20分钟定时通知已取消")
}
willPresent 代理方法,并在 completionHandler 中返回 .alert 选项repeats 属性设置为 true,并注意iOS的重复通知频率限制