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

如何让AppStorage中的exerciseTime变量每日自动重置?

实现每日自动重置exerciseTime的可行方案

核心思路

通过额外存储「上次重置的日期」,每次App进入前台或初始化时,对比当前日期与记录的日期,若跨天则重置exerciseTime并更新记录的日期。

具体实现步骤

  1. 新增日期存储变量
    在@AppStorage中添加变量记录上次重置的日期,用yyyy-MM-dd格式的字符串方便直接对比:

    @AppStorage("exerciseTime") var exerciseTime = 0.0
    @AppStorage("lastResetDate") var lastResetDate = Date().formatted(date: .numeric, time: .omitted)
    
  2. 添加场景监听与检查触发
    在View的onAppear和前台激活通知中触发日期检查,覆盖App启动和后台切前台的场景:

    .onAppear {
        checkDailyReset()
    }
    .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
        checkDailyReset()
    }
    
  3. 编写检查与重置逻辑
    实现核心函数,对比日期后执行重置操作:

    func checkDailyReset() {
        let today = Date().formatted(date: .numeric, time: .omitted)
        if today != lastResetDate {
            exerciseTime = 0.0
            lastResetDate = today
        }
    }
    

整合到你的现有代码

把逻辑嵌入到你的运动计时View中:

struct ExerciseTimerView: View {
    @AppStorage("exerciseTime") var exerciseTime = 0.0
    @AppStorage("lastResetDate") var lastResetDate = Date().formatted(date: .numeric, time: .omitted)
    
    // 你的timer、timerStruct等变量定义
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State var timerStruct = TimerStruct() // 假设你有对应的结构体
    
    var body: some View {
        Text("Time: \(format(seconds: timerStruct.countdownTimer))")
            .padding()
            .onReceive(timer) { _ in
                if timerStruct.countdownTimer > 0 && timerStruct.timerRunning == true {
                    timerStruct.countdownTimer -= 1
                    exerciseTime += 1.0
                } else {
                    timerStruct.timerRunning = false
                    if timerStruct.countdownTimer <= 0, timerStruct.timerRunning == false {
                        timerStruct.isAlertpresented = true
                        reset()
                    }
                }
            }
            .onAppear {
                checkDailyReset()
            }
            .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
                checkDailyReset()
            }
    }
    
    func checkDailyReset() {
        let today = Date().formatted(date: .numeric, time: .omitted)
        if today != lastResetDate {
            exerciseTime = 0.0
            lastResetDate = today
        }
    }
    
    // 你的format、reset等原有函数
    func format(seconds: Int) -> String {
        // 你的格式化逻辑
        return String(seconds)
    }
    
    func reset() {
        // 你的重置逻辑
    }
}

// 假设你的TimerStruct定义
struct TimerStruct {
    var countdownTimer = 0
    var timerRunning = false
    var isAlertpresented = false
}

补充说明

  • 若需适配时区差异,可以改用Calendar.current.startOfDay(for: Date())获取当天起始时间,再转成字符串对比,避免跨时区导致的日期判断错误。
  • 监听前台激活通知是为了处理用户跨天后台挂着App的场景,确保回到前台时自动重置数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:05:27