Reset day not working after quitting the app

Hi, currently the app works the following way (regarding this):
  • I open the app, it checks if it's the same day.

  • I put it in background, it stores the last day

  • If when it comes back from background, it checks that it's a new day, then it resets the array of elements to it's initial state.

Right now the above is working, the problem is when I close the app and I start it again, it's like if it looses track of everything. When I open it after being closed, it doesn't reset anything, what's going on?

Code Block
// --------- This sets the auto time Meal reset ----------
@State var lastDay: Date = Date()
@State var isToday = false
// --------------------------------------------------------
let getThemeConstants = GetThemeConstants()
var body: some View {
VStack {
if viewRouter.currentPage == "onboardingView" {
OnboardingView()
} else if viewRouter.currentPage == "homeView" {
TabView {
HomeView(mealsController: self.mealsController)
.tabItem {
Image(systemName: "house")
Text("Menu")
}
SettingsView(mealsController: self.mealsController)
.tabItem {
Image(systemName: "slider.horizontal.3")
Text("Settings")
}
}
.accentColor(Color(getThemeConstants.accentThemeColor))
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
// store the date whenever you go into background
print("Stored last day")
UserDefaults.standard.set(Date(), forKey: "lastDay")
}
}
}
// Try to retrieve the date when you come back from background
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
// Check if the same is the same
if let temDate = UserDefaults.standard.object(forKey: "lastDay") {
self.lastDay = temDate as! Date
// If same day
if Calendar.current.isDate(Date(), inSameDayAs: self.lastDay) {
self.isToday = true
print("Same day = true")
} else {
// If new day, set day as needs to be reset
print("Day needs to be reset set to true")
self.settingsUserDefaults.dayNeedsToBeReset = true
}
}
// If new day and day needs to be reset
if(self.settingsUserDefaults.dayNeedsToBeReset == true) {
if let thisHour = Calendar.current.dateComponents([.hour], from: Date()).hour {
print("Inside new day")
// If it is 6 am or later do something
if (thisHour >= self.settingsUserDefaults.dayStartTime) {
print("----> It is 8am or later --> Reset Meal Times")
self.resetDayViewModel.resetDay(mealsController: self.mealsController)
self.settingsUserDefaults.dayNeedsToBeReset = false
} else {
print("Still is not time to change")
}
}
}
}
}
}

Accepted Reply

Never mind, I fixed the problem with .onAppear(){}

The problem I'm having now is that I'm repeating that whole code twice, how can I optimize this?

Replies

Never mind, I fixed the problem with .onAppear(){}

The problem I'm having now is that I'm repeating that whole code twice, how can I optimize this?
Howdy!

Generally, @State is for short term state completely owned by views for their purposes. If you want to persist values, you should store them in some kind of model and pass that along to a view, for example an ObservableObject via .environmentObject(). Your onReceive callbacks could also call methods in your model to update its persisted values.

Here's an example, though I'm not positive I fully understand your use case :)
Code Block
class MyModel: ObservableObject {
    // Store this in UserDefaults if you want!
    @Published var lastDay = Date()
    var lastDayIsToday: Bool {
        Calendar.current.isDateInToday(lastDay)
    }    
    func updateLastDay() {
        // Logic here
    }
}
struct ContentView: View {
    @EnvironmentObject private var model: MyModel
    
    var body: some View {
        VStack {
            if model.lastDayIsToday {
                Text("Is Last Day!")
            } else {
                Button(action: model.updateLastDay) {
                    Text("Update Last Day")
                }
            }
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
            model.updateLastDay()
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
            model.updateLastDay()
        }
    }
}