UserDefaults 未在 SwiftUI 中第一次保存和更新

UserDefaults not being saved and update after first time in SwiftUI

我创建了一个简单的系统来根据 UserDefaults 值在屏幕上导航,我有一个键 ”rootStatus” 那个键我放在枚举里面。我使用 @属性Wrapper 来存储用户默认值。

UserDefaults Key 放入枚举中。

  enum UserDefaultKey: String {
        case rootStatus           = "rootStatus"
    }

使用 属性 包装器在用户默认值中保存数据。

//MARK: UserDefault:- storage template to occupies the memory in the local Database.
@propertyWrapper
struct UserDefault<T> {

    //Key: to storing the value in the userDefault in with name of specific key.
    let key: String
    //defaultValue:- to  storing the data in  any format in the UserDefault.
    let defaultValue: T

    //Update value when use a UserDefaultStorage inside the Project.
    init(_ key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    // To Wrapping the Data inside the Project
    var wrappedValue: T {

        get{
             // Read value from UserDefaults
            return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }

        set{
            // Set value to UserDefaults.
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}

要存储在 UserDefaults 中的枚举值。

enum ScreenSwitch: String {
    case lauched
    case logIn
    case dashboard
    case withoutlogin
    case none
}

使用 ObservableObject 属性 包装器获取和设置 UserDefaults 值。

final class ScreenSwitchSettings: ObservableObject {

    let objectWillChange = PassthroughSubject<Void, Never>()

    @UserDefault(UserDefaultKey.rootStatus.rawValue, defaultValue: ScreenSwitch.lauched.rawValue)
    var screenSwitch: String {
        willSet {
            objectWillChange.send()
        }
    }
}

TO 在 SwiftView 中使用

 struct SwitchRootView: View {

            @ObservedObject var screenSwitchSettings = ScreenSwitchSettings()

        var body: some View {

 containedView()

        }

        func containedView() -> AnyView?{

            switch screenSwitchSettings.screenSwitch {

//// Introduction is a SwiftUIView for Navigation.
            case ScreenSwitch.lauched.rawValue : return AnyView(IntroductionView()) 

// LoginView is a SwiftUIView for Navigation.
            case ScreenSwitch.logIn.rawValue: return AnyView(LoginView())

// DashboardTabView is a SwiftUIView for Navigation. 
            case ScreenSwitch.withoutlogin.rawValue: return AnyView(DashboardTabView())

// DashboardTabView is a SwiftUIView for Navigation.
            case ScreenSwitch.dashboard.rawValue: return AnyView(DashboardTabView()) 

// EmptyView is a SwiftUIView for Navigation.
            case ScreenSwitch.none.rawValue: return AnyView(EmptyView()) 
            default : return AnyView(EmptyView())
            }
        }
    }

// 当应用程序第一次启动时,我最初设置了用户默认值。

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    @ObservedObject var screenSwitchSettings = ScreenSwitchSettings()

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        let contentView = SwitchRootView()
        screenSwitchSettings.screenSwitch = ScreenSwitch.lauched.rawValue
        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}

更改 SwiftUIView 中的值

struct ContentView: View {

    //MARK: Properties
    @ObservedObject var screenSwitchSettings = ScreenSwitchSettings()

    var body: some View {

        NavigationView{

            Button(action: {
                // here i change Userdefault Value.
                self.screenSwitchSettings.screenSwitch = ScreenSwitch.logIn.rawValue

            }) {

                NavigationLink(destination: SwitchRootView()) {

                    Text("Get Started")
                }
            }
        }
    }
}

在 ContentView 中,我更改了按钮选择上的用户默认值,但它没有更新。

可能是什么问题?

尝试以下而不是您的

final class ScreenSwitchSettings: ObservableObject {

  @UserDefault(UserDefaultKey.rootStatus.rawValue, defaultValue: ScreenSwitch.lauched.rawValue)
    var screenSwitch: String {
        willSet { // or even maybe on didSet
            self.objectWillChange.send()
        }
    }
}

and... 当您在其中放置导航 link 时按钮不起作用,因为后者会消耗点击手势,因此请使用类似以下内容的方式进行测试

@State private var isActive = false

...
NavigationView{

    Button(action: {
        // here i change Userdefault Value.
        self.screenSwitchSettings.screenSwitch = ScreenSwitch.logIn.rawValue
        self.isActive.toggle()

    }) {
            Text("Get Started")
    }
    NavigationLink(destination: SwitchRootView(), isActive: $isActive) {
        EmptyView()
    }
}