iOS app如何给用户弹通知,提示使用时间(比如定时20分钟)到了

iOS app实现定时提示使用时间到期(如20分钟),核心依赖于 Local Notification(本地通知) 功能,无需依赖服务器,所有定时逻辑均在设备本地完成,支持App前台、后台甚至退出状态下的通知推送。本文将详细讲解20分钟定时通知的完整实现流程,包括权限申请、通知配置、定时任务设置与回调处理。

一、前置条件与核心说明

注意:与远程通知(Push Notification)不同,本地通知无需配置APNs(苹果推送服务),无需服务器支持,仅在设备本地完成定时与推送,非常适合「定时提醒」「闹钟」「使用时长提示」等场景。

二、步骤1:配置项目与导入框架

  1. 打开Xcode项目,选中项目目标(Target),切换到「Info」标签页
  2. 导入UserNotifications框架,在需要使用的文件头部添加导入语句:
// 导入本地通知框架
import UserNotifications

// 遵守通知相关代理协议(处理通知回调)
class ViewController: UIViewController, UNUserNotificationCenterDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置通知代理(接收通知回调)
        UNUserNotificationCenter.current().delegate = self
    }
}

三、步骤2:申请本地通知权限

在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)
}

四、步骤3:创建20分钟定时通知

授权成功后,创建本地通知内容、设置20分钟定时触发器,最后将通知发送到系统通知中心。

3.1 构建通知内容

定义通知的标题、副标题、正文、声音等内容,贴合「使用时间到期提醒」的场景。

3.2 设置20分钟定时触发器

使用 UNTimeIntervalNotificationTrigger 构建时间间隔触发器,设置时间间隔为20分钟(1200秒)。

3.3 发送本地通知

// 创建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分钟后推送")
        }
    }
}

五、步骤4:处理通知回调(前台/后台)

实现代理方法,处理通知的回调事件,包括App在前台时的通知展示、用户点击通知后的跳转逻辑。

4.1 App在前台时展示通知

// 当App在前台时,收到本地通知的回调(控制是否展示通知)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    // 即使App在前台,也展示通知(包含提示音、横幅)
    completionHandler([.alert, .sound, .badge])
}

4.2 用户点击通知后的回调

// 当用户点击通知(横幅/通知中心)后的回调
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分钟定时通知已取消")
}

七、常见问题与解决方案

返回主页