0

I'm currently developing an application using SwiftUI.

I want to use a UserDefaults value in this app. So I made a code below.

But in this case, when I reboot the app(the 4'th process in the process below), I can't get value from UserDefaults...

  1. Build and Run this project.

  2. Pless the home button and the app goes to the background.

  3. Double-tap the home button and remove the app screen.

  4. press the app icon and reboot the app. Then I want to get value from UserDefaults.

enter image description here

to resolve this problem how should I set and get a value in UserDefaults?


Here is the code:

import SwiftUI

struct ContentView: View {
    
    @State var text = "initialText"
    
    var body: some View {
        VStack {
            Text(text)
            TextField( "", text: $text)
        }.onAppear(){
            if let text = UserDefaults.standard.object(forKey: "text" ){
                self.text = text as! String
            }
        }
        .onDisappear(){
            UserDefaults.standard.set(self.text, forKey: "text")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

ADD

When I add this class following the first answer, that code has a couple of errors like this, is it usual?

enter image description here


Xcode: Version 11.7

Swift: Swift 5

Tio
  • 944
  • 3
  • 15
  • 35
  • check this, https://stackoverflow.com/questions/56822195/how-do-i-use-userdefaults-with-swiftui – Ronak Patel Sep 08 '20 at 11:13
  • What is your iOS version target? Perhaps worth mentioning as a comment, if you’re prepared to wait for the release of Xcode 12 and iOS 14 you can use the SwiftUI @AppStorage property wrapper - so easy to use and requires very little code. – andrewbuilder Sep 08 '20 at 13:45
  • @andrewbuilder, Thank you for your comment, the target of this project is ios 13.7 – Tio Sep 08 '20 at 13:48

1 Answers1

1

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
    }
}
}
Joannes
  • 2,569
  • 3
  • 17
  • 39
  • Thank you for your help, when I add the class `UserSettings` that code has a couple of errors like the photo I attached, is it usual? – Tio Sep 08 '20 at 13:50
  • Thank you for your lots of supports! now it works well. – Tio Sep 08 '20 at 15:14