Arnav Motwani
Arnav Motwani

Reputation: 817

Views dependant on UserDefaults not updating on change

So I have a class that records the state of a toggle and a selection of a picker into UserDefaults

import Foundation
import Combine

class UserSettings: ObservableObject {
    @Published var shouldSort: Bool {
        didSet {
            UserDefaults.standard.set(shouldSort, forKey: "shouldSort")
        }
    }
    
    @Published var sortKey: String {
        didSet {
            UserDefaults.standard.set(sortKey, forKey: "sortKey")
        }
    }
    
    public var sortKeys = ["alphabetical", "length", "newest", "oldest"]
    
    init() {
        self.shouldSort = UserDefaults.standard.object(forKey: "shouldSort") as? Bool ?? true
        self.sortKey = UserDefaults.standard.object(forKey: "sortKey") as? String ?? "Name"
    }
}

On my settings page I use the following code

@ObservedObject var userSettings = UserSettings()

...

Toggle(isOn: $userSettings.shouldSort, label: {Text("Sort Books")})

Picker(selection: $userSettings.sortKey, label: Text("Sort By"), content: {
                            ForEach(userSettings.sortKeys, id: \.self){ key in
                                Text(key)
                            }
                        })

This code changes the value just fine because if I close and open the app, the views update based on the data. I am reading the data with

@State var sorted =  UserDefaults.standard.bool(forKey: "shouldSort")
@State var sort =  UserDefaults.standard.string(forKey: "sortKey")

in my content view. (shouldSort calls a function to sort if true and sortKey determines how the data is sorted)

Am I reading the data wrong with the @State variable (can @State even detect changes in state of UserDefaults)?

Upvotes: 0

Views: 508

Answers (1)

swiftPunk
swiftPunk

Reputation: 1

Forget all what you learnt about UserDefaults in UIKit and say Hello to AppStorage in SwiftUI, use this Codes:

@AppStorage("shouldSort") var sorted: Bool = false
@AppStorage("sortKey") var sort: String = ""

Upvotes: 3

Related Questions