UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: How do I encode/decode a @State property?

Forums > SwiftUI

Suppose this view

struct SymbolView: View, Identifiable {
  var imageName:String = ""
  var code:String = ""
  @State var position:CGPoint = CGPoint(x:200, y:200)

  ... bla bla 
  }

If I encode this struct using this

  extension SymbolView: Codable {
  private enum CodingKeys: String, CodingKey {
    case imageName
    case code
    case position
  }

  init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    self.imageName = try values.decode(String.self, forKey: .imageName)
    self.code = try values.decode(String.self, forKey: .code)
    self.position = try values.decode(CGPoint.self, forKey: .position)
  }

  public func encode(to encoder:Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    do {
      try container.encode(self.imageName, forKey: .imageName)
      try container.encode(self.code, forKey: .code)
      try container.encode(self.position, forKey: .position)
    } catch (let error) {
      print(error.localizedDescription)
    }
  }
}

the equivalent JSON will have position equal to 200,200, even if position changes after creating the view.

3      

Since I don't know what the rest of your SymbolView looks like, I used this to test your encoding code:

struct SymbolView: View {

    var imageName: String = ""
    var code: String = ""
    @State var position:CGPoint = CGPoint(x:200, y:200)

    var body: some View {
        VStack(spacing: 20) {
            Text("imageName: \(imageName)")
            Text("code: \(code)")
            Text("position: {\(position.x), \(position.y)}")

            Button("Move position!") {
                position = CGPoint(x: 3000, y: 10)
            }

            Button("Encode!") {
                do {
                    let encodedView = try JSONEncoder().encode(self)
                    print(String(data: encodedView, encoding: .utf8))
                } catch {
                    print(error)
                }
            }
        }
    }
}

And it worked just fine. If I encoded without changing position, I got 200, 200. If I changed position and then encoded, I got 3000, 10.

Perhaps you aren't really changing position before you encode it? Or maybe something else is going on in the code you didn't post?

I would, however, recommend not directly encoding your SymbolView. Pull the data into a type you can (en|de)code separately and use as an @State value in the View.

3      

Thanks.

I have this on SymbolView

var body: some View {
    Image(imageName)
      .position(position)
      .gesture(
        DragGesture()
          .onChanged({ newValue in
              self.position =  newValue.location
            print(self.position)
          })

So, as I drag the image I see the position changing but when I encode the variable positon, it stays at the initial value.

3      

Again, that works fine for me. The changed position gets encoded.

When are you doing the encoding? Have you tried printing position just before you encode it to make sure it's the value you are expecting? If the code you have posted is working for someone else, I'm going to assume the problem likely lies in the code you haven't posted.

You can try adding an onEnded handler to that DragGesture. Maybe that will help.

                        .onEnded { finalValue in
                            self.position = finalValue.location
                            print(self.position)
                        }

3      

After trying a lot of code the only thing that worked for me was to create an ObservableObject class to store the position and use @Published instead of @State.

Thanks for all help.

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.