简体   繁体   English

UserDefaults state 不刷新

[英]UserDefaults state not refresh

I use "UserDefaults" to store the date time of the user to reload the page.我使用“UserDefaults”来存储用户重新加载页面的日期时间。 However, I found that it does not refresh even if the time passed但是,我发现即使时间过去了它也不会刷新

final class ModelData: ObservableObject {
    @Published var lastLaunchDate: Date = UserDefaults.standard.value(forKey: "lastLaunch") as? Date ?? Date()

    func getTimeStamp() -> Date {
                    
            let now_components = Calendar.current.dateComponents([.month, .day, .hour, .minute], from: Date())
            let lastLaunch_components = Calendar.current.dateComponents([.month, .day, .hour, .minute], from: lastLaunchDate)
            
            print(now_components.minute, lastLaunch_components.minute)
            
            if now_components.minute != lastLaunch_components.minute {
                lastLaunchDate = Date()
                UserDefaults.standard.setValue(lastLaunchDate, forKey: "lastLaunch")
            }
            print(now_components.minute, lastLaunch_components.minute)
        }
        return lastLaunchDate
    }
}

Since I am testing, I use 'minute' to ease my test.由于我正在测试,我使用“分钟”来简化我的测试。 I expect that when there is change of minute, the above piece of code will update my userDefaults.我希望当分钟发生变化时,上面的代码将更新我的 userDefaults。

struct HomeView: View {

    @EnvironmentObject var modelData: ModelData
    
    var body: some View {
        Text("\(modelData.getTimeStamp())")
    }
}

I found that I browse into another page, go back to HomeView.我发现我浏览到另一个页面 go 回到 HomeView。 The timestamp did not get update at all.时间戳根本没有得到更新。 I printed the lastLaunchDate, it also did not update as well.我打印了 lastLaunchDate,它也没有更新。

I found that I browse into another page, go back to HomeView.我发现我浏览到另一个页面 go 回到 HomeView。 The timestamp did not get update at all.时间戳根本没有得到更新。

If you navigate back to a parent View , SwiftUI does not re-render it unless something changes.如果您导航回父View , SwiftUI 不会重新渲染它,除非有什么变化。
Instead... you will need to use the .onAppear view modifier to call your function.相反......您将需要使用.onAppear视图修饰符来调用您的 function。

Also, Text("\(modelData.getTimeStamp())") is not very SwiftUI especially in your case.此外, Text("\(modelData.getTimeStamp())")不是很SwiftUI ,尤其是在您的情况下。
Since you have @Published var lastLaunchDate , use it as it's meant to be used:既然您有@Published var lastLaunchDate ,请按原意使用它:

Text("\(modelData.lastLaunchDate)")

Now when lastLaunchDate is changed, the SwiftUI engine will automatically update the View .现在,当lastLaunchDate更改时, SwiftUI引擎将自动更新View

Solution:解决方案:

final class ModelData: ObservableObject {
    @Published var lastLaunchDate = UserDefaults.standard.value(forKey: "lastLaunch") as? Date ?? Date()
    
    func refresh() {
        let compareDate = Date()
        let refreshInterval = TimeInterval(3) //3 second interval for test purpose
        
        if compareDate.timeIntervalSince(lastLaunchDate) > refreshInterval {
            lastLaunchDate = compareDate
            UserDefaults.standard.setValue(lastLaunchDate, forKey: "lastLaunch")
        }
    }
}

struct ContentView: View {
    @EnvironmentObject var modelData: ModelData
    
    var body: some View {
        NavigationView {
            VStack {
                Text("\(modelData.lastLaunchDate)")
                NavigationLink(destination: Text("Destination"),
                               label: { Text("Navigate") })
            }
            .onAppear {
                modelData.refresh()
            }
        }
    }
}

NOTE:笔记:
if now_components.minute.= lastLaunch_components.minute is error prone. if now_components.minute.= lastLaunch_components.minute容易出错。
Example: compare last-update-time of 00:01 with current-time of 01:01.示例:比较上次更新时间 00:01 和当前时间 01:01。
Check will fail.检查将失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM