You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift iOS不用NSTimer实现满一周增变量、检测用户活跃并推送的方案咨询

iOS 跨进程时间追踪及周度触发方案

NSTimer 依赖应用进程存活,应用被杀死、进入后台超过系统保活时长后都会失效,完全不适合跨周度的时间追踪需求,下面是可落地的无NSTimer实现方案:


1. 周度变量自增逻辑实现

核心思路是用本地持久化存储关键时间戳,每次应用激活时做差值校验:

  • 用UserDefaults或沙盒文件持久化两个时间戳:上次执行周度自增的时间、上次应用启动的时间
  • 在应用启动回调didFinishLaunchingWithOptions、从后台激活回调applicationDidBecomeActive中分别触发校验逻辑
  • 时间差计算优先使用系统日历API,避免时区、夏令时、闰秒导致的计算误差,Swift示例代码如下:
// 读取上次周更时间
let lastUpdateDate = UserDefaults.standard.object(forKey: "LastWeeklyUpdateDate") as? Date ?? Date()
let calendar = Calendar.current
// 计算两个日期的间隔天数
let intervalDays = calendar.dateComponents([.day], from: lastUpdateDate, to: Date()).day ?? 0
if intervalDays >= 7 {
    // 执行指定变量自增逻辑
    targetCount += 1
    // 更新本次周更时间到本地
    UserDefaults.standard.set(Date(), forKey: "LastWeeklyUpdateDate")
}
// 每次激活都更新上次启动时间
UserDefaults.standard.set(Date(), forKey: "LastAppLaunchDate")

2. 一周未启动推送提醒实现

该需求完全不需要应用后台存活,直接用系统本地推送能力即可实现:

  • 首先需要在应用首次启动时向用户申请通知权限,权限通过后才能正常推送
  • 每次应用激活时,先取消之前调度的未触发的周度提醒推送,再重新调度一个7天后触发的推送
  • 逻辑说明:如果用户7天内打开过应用,推送触发时间会被不断延后7天;如果用户始终未打开,系统会在7天后自动弹出预设提醒,Swift示例代码如下:
let notifyCenter = UNUserNotificationCenter.current()
// 取消之前的同类型待触发推送
notifyCenter.removePendingNotificationRequests(withIdentifiers: ["WeeklyOpenReminder"])

// 构造推送内容
let content = UNMutableNotificationContent()
content.title = "好久不见"
content.body = "你已经一周没打开应用啦,快来看看新内容~"
content.sound = .default

// 设置7天后触发
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 7 * 24 * 3600, repeats: false)
let request = UNNotificationRequest(identifier: "WeeklyOpenReminder", content: content, trigger: trigger)
notifyCenter.add(request)

注意事项

  • 不要用设备开机时长、进程运行时长做计算基准,用户重启设备、杀进程都会导致数据重置,必须用系统真实时间戳
  • 如果担心用户手动修改系统时间作弊,可以在应用联网时同步服务器时间做校验,纯本地场景用系统时间可以覆盖绝大多数正常用户需求
  • 本地推送只有在用户同意通知权限后才能正常触发,需要做好权限申请引导和权限未开启的兼容处理

内容的提问来源于stack exchange,提问作者Kiran Lim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:39:03