Home > Net >  Swift - How to change JSON Struct Element Values
Swift - How to change JSON Struct Element Values

Time:04-27

I have converted JSON data file to a deviceParameters instance of Struct using JSONDocode and it works fine. However I am struggling to change the values of properties on the Struct programmatically afterwards. Any Suggestings?

struct DeviceParameters : Codable, Hashable {
    
    let id : String
    let version : String
    let encoding : String
    let deviceType : String // name of XML file is converted to deviceName, unique identifier
    var Point : [PointData]
    
    enum CodingKeys: String, CodingKey {
        case id, version, encoding, Point
        case deviceType = "name"
    }
}

struct PointData : Codable, Hashable {
    let id : String
    var name : String
    let type : String
    var address : Address
    let calculate : Calculate
    let pointEnum: [String: String]
    var presentValue : String
    
    enum CodingKeys: String, CodingKey {
        case id, name
        case type = "Type"
        case address = "Address"
        case calculate = "Calculate"
        case pointEnum = "Enum"
        case presentValue
    }
    
}

struct Calculate: Codable, Hashable {
    let scaling, decimals, min, max: String?
}

struct Address: Codable, Hashable {
    var index: String
    let type: String
    let format: String
}

Using ForEach I can scroll print the struct parameters, but I cannot assign new values to the variables. What is the correct way for this? And perhaps the simplest?

func updatePresentValue(pointNo : Int) {
    
    deviceParameters.Point.forEach {
        print($0.name) // prints the name of the "Point" OK
        print($0.address.index) // prints the name of the "Point.Address" OK
        $0.presentValue = "200" // Not working telling $0 inmutable
        $0.address.index = "20"  // Not working telling $0 inmutable
    }
}

CodePudding user response:

Firstly make sure you name your variables starting with a lowercase letter, that is an accepted coding practice.

Closure parameters are immutable, you cannot assign a new value. But you could use a map operator where you make a copy of your struct, assign new values and return that copy in your closure.

func updatePresentValue(pointNo : Int) {
    deviceParameters.points = deviceParameters.points.map { point in
        var p = point
        p.address.index = "New value"
        return p
    }
}

CodePudding user response:

Thank you Au Ris. Found also another way, assuming that the point number is unique.

func updatePresentValue(pointNo : String) {
            
  if let idx = deviceParameters.Point.firstIndex(where: { $0.address.index == pointNo }) {
             
                deviceParameters.Point[idx].address.index = "New Value"
                
            }
}
  • Related