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
Nsattributedstring, Change the Font Overall But Keep All Other Attributes
Class Conforming to Protocol as Function Parameter in Swift
How to Create a Multi-Line Text Inside a Scrollview in Swiftui
String Length in Swift 1.2 and Swift 2.0
What Is the Cause of This Type Error
How to Display My App Documents in the Files App For Iphone
Swift: How to Add a Protocol Extension to a Protocol
Swift - Extra Argument in Call
Constant Unassigned Optional Will Not Be Nil by Default
Get a Swift Variable'S Actual Name as String
How to Disable Pasting in a Textfield in Swift
Delete Folder With Contents from Firebase Storage
Swift Generic Coercion Misunderstanding
Can Swift Convert a Class/Struct Data into Dictionary
How to Dispatch_Sync, Dispatch_Async, Dispatch_After, etc in Swift 3, Swift 4, and Beyond
Why My Return Is Nil But If I Press the Url in Chrome/Safari, I Can Get Data