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