How to Use Userdefaults With Swiftui

how should i store user name using NS Userdefault in swift UI

Use @AppStorage to store and get values for user defaults.

@AppStorage("Username") var username: String = ""

or you can use also use UserDefaults.

if !UserDefaults.standard.string(forKey: "Username") {
login()
} else {
home()
}

Going crazy with UserDefaults in Swift[UI]

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))
}
}

UserDefaults Text / SwiftUI

You can save textfield content by simply calling user defaults in button action

 Button(action: {
UserDefaults.standard.set(profilSurname, forKey: "Key")
}

To retrieve text from user defaults when app starts load user defaults data in init function like below

struct ContentView: View{
@State private var profilName = ""
@State private var profilSurname = ""

init() {
self._profilSurname = State(initialValue: UserDefaults.standard.object(forKey: "Key") as? String ?? "")
}

var body: some View{

Global Updates With UserDefaults In SwiftUI

Your problem is that weight isn't wrapped by any state.

In your AccountView, give weight a @State wrapper:

struct AccountView: View {

@AppStorage("weightInKilograms") var weightInKilograms = false

@State var weight = Weight(weight: 9.0))

var body: some View {
//...
}
}

In SecondaryView, ensure that weight is wrapped with @Binding:

struct SecondaryView: View {

@Binding var weight: Weight

var body: some View {
// ...
}
}

Then, pass weight as a Binding<Weight> variable to SecondaryView within your first View:

SecondaryView(weight: $weight)

Is there a way to create a global change that would update weightFormatted in SecondaryView below?

If you're looking to make a global change, you should consider setting up a global EnvironmentObject:

class MyGlobalClass: ObservableObject {

// Published variables will update view states when changed.
@Published var weightInKilograms: Bool
{ get {
// Get UserDefaults here
} set {
// Set UserDefaults here
}}

@Published var weight: Weight
}

If you pass an instance of MyGlobalClass as an EnvironmentObject to your main view, then to your secondary view, any changes made to properties in the global instance will update the views' state via the @Published wrapper:

let global = MyGlobalClass()

/* ... */

// In your app's lifecycle, or where AccountView is instantiated
AccountView().environmentObject(global)
struct AccountView: View {
@EnvironmentObject var global: MyGlobalClass

var body: some View {
// ...
Text(global.weight.weightFormatted)
// ...
SecondaryView().environmentObject(global)
}
}

SwiftUI - UserDefaults array of strings error

Array.append returns Void . You need to append to the array then set.

class AppManagerModel: ObservableObject {
@Published var userData = UserDefaults.standard.array(forKey: "userData") as? [String] ?? [String]()

func addUserData(_ data: String) {
userData.append(data)
UserDefaults.standard.set(userData, forKey: "userData")
}
}

Keep your persistence logic hidden in AppManagerModel rather than putting it in your View.

How should I get and set a value of UserDefaults?

Set in a class like this your values: Bool, String(see example), Int, etc...

#if os(iOS)
import UIKit
#else
import AppKit
#endif

import Combine

@propertyWrapper struct UserDefault<T> {

let key: String
let defaultValue: T

init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}

var wrappedValue: T {
get {
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}

final class UserSettings: ObservableObject {

let objectWillChange = PassthroughSubject<Void, Never>()

@UserDefault("myText", defaultValue: "initialText")
var myText: String {
willSet { objectWillChange.send() }
}

}

this to read:

let settings = UserSettings()
let count = settings.countSentence // default countsentence 1

this to update:

let settings = UserSettings()
settings.countSentence = 3 // default countsentence 3

Based on your code:

struct ContentView: View {

let UserDef = UserSettings()
@State var text = ""

var body: some View {
VStack {
Text(UserDef.myText)
TextField("placeholder", text: $text, onCommit: { self.UserDef.myText = self.text})
}.onAppear() {
self.text = self.UserDef.myText
}
}
}


Related Topics



Leave a reply



Submit