Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Going crazy with UserDefaults in Swift[UI]

Launching myself into Swift and SwiftUI, I find the process of migrating from UIKit quite hard. Presently stomped by UserDefaults, even after trying to make sense of the many tutorials I found on the web.

Please tell me what I'm doing wrong here : VERY simple code to :

  1. register a bool value to a UserDefault,
  2. display that bool in a text !

Doesn't get any simpler than that. But I can't get it to work, as the call to UserDefaults throws this error message :

Instance method 'appendInterpolation' requires that 'Bool' conform to '_FormatSpecifiable'

My "app" is the default single view app with the 2 following changes :

1- In AppDelegate, I register my bool :

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    UserDefaults.standard.register(defaults: [
    "MyBool 1": true
    ])


    return true
}

2- in ContentView, I try to display it (inside struct ContentView: View) :

let defaults = UserDefaults.standard

var body: some View {
    Text("The BOOL 1 value is : Bool 1 = \(defaults.bool(forKey: "MyBool 1"))")
}

Any ideas ?

Thanks

like image 789
Esowes Avatar asked Mar 03 '23 13:03

Esowes


2 Answers

Your issue is that the Text(...) initializer takes a LocalizedStringKey rather than a String which supports different types in its string interpolation than plain strings do (which does not include Bool apparently).

There's a couple ways you can work around this.

You could use the Text initializer that takes a String and just displays it verbatim without attempting to do any localization:

var body: some View {
    Text(verbatim: "The BOOL 1 value is : Bool 1 = \(defaults.bool(forKey: "MyBool 1"))")
}

Alternatively, you could extend LocalizedStringKey.StringInterpolation to support bools and then your original code should work:

extension LocalizedStringKey.StringInterpolation {
    mutating func appendInterpolation(_ value: Bool) {
        appendInterpolation(String(value))
    }
}
like image 164
dan Avatar answered Mar 05 '23 14:03

dan


To solve your problem, just add description variable, like:

var body: some View {
    Text("The BOOL 1 value is : Bool 1 = \(defaults.bool(forKey: "MyBool 1").description)")
}
like image 30
YardenV4 Avatar answered Mar 05 '23 16:03

YardenV4