Search code examples
iosswiftxcodeswiftuiuserdefaults

Cannot get UserDefautls updated values in realtime


I'm new to swift and I cannot get the UserDefaults updated values in the same session. Only after the application restarts.

Here is what I mean in some code:

//This is where I have the userdefaults
@ObservedObject var userSettingsController = UserSettingsController

//These are the auxiliar vars I created to help me achieve the conditional renders I need. I'm looking to get rid of these and use the usersettings updated values
@State private var showMap = false
@State private var showTutorial = true

//Partial code of my view, where I'm using the variables
if(!self.userSettingsController.showActionSheet && self.showMap) {
   showMapView()
     .onTapGesture {
        if (self.userSettingsController.showNextDeparturesTutorial && self.showTutorial {
          self.showTutorial = false
          self.userSettingsController.showNextDeparturesTutorial.toggle()
        } else {
        //code that has nothing to do with the question

No, here is my UserSettings and UserSettingsController classes:

UserSettings

import Foundation

struct UserSettings {
    var settings: UserDefaults

    init() {
        self.settings = UserDefaults.standard
        self.settings.register(
            defaults: [
                "userCity": "",
                "showUserCityActionSheet": true,
                "showNextDeparturesTutorial": true,
        ])
    }
}

UserSettingsController

import Foundation
import Combine
import SwiftUI

class UserSettingsController: ObservableObject {
    @Published var userSettings = UserSettings()

    var userCity : String {
        get {
            return self.userSettings.settings.string(forKey: "userCity") ?? ""
        }
        set {
            self.userSettings.settings.set(newValue, forKey: "userCity")
        }
    }

    var showUserCityActionSheet: Bool {
        get {
            return self.userSettings.settings.bool(forKey: "showUserCityActionSheet")
        }
        set {
            self.userSettings.settings.set(newValue, forKey: "showUserCityActionSheet")
        }
    }

    var showNextDeparturesTutorial: Bool {
        get {
            return self.userSettings.settings.bool(forKey: "showNextDeparturesTutorial")
        }
        set {
            self.userSettings.settings.set(newValue, forKey: "showNextDeparturesTutorial")
        }
    }
}

My question is, how can I get the updated values of the UserDefault values showNextDeparturesTutorial and showActionSheet in realtime? I've already tried to store them in other variables but to no avail.

Thanks.

EDIT

I accepted @Asperi answer because it was the most efficient one considering my project. However, @pawello2222 answer would also solve my problem.

Thanks, all.


Solution

  • The possible solution is to activate ObservableObject publisher explicitly in every setter, like below

    var userCity : String {
        get {
            return self.userSettings.settings.string(forKey: "userCity") ?? ""
        }
        set {
            self.userSettings.settings.set(newValue, forKey: "userCity")
            self.objectWillChange.send()   // << this one !!
        }
    }