'Swift add a new property to Model

I have a model that I set after receiving data from the server.

public struct Model1: Codable {
    let type1: String
    let type2: Int
    let type3: String
}

But model1 (also model2 and model 3, but will not duplicate the code) is missing one property that I want to add dynamically. So I change the model to

public struct Model1: Codable {
    let type1: String
    let type2: Int
    let type3: String
    var missingType: String
}

The models are stored in the enum as an associated value.

public enum WalletSection {
    case model1(items: [Model1])
    case model2(items: [Model2])
    case model3(items: [Model3])
}

Once I want to set the value I am trying to do the following:

switch section {
case .model1(let items):
case .model2(let items):
case .model3(let items):
    for item in items {
        item.missingType = setMissingType()
    }
}

And the error I have is: Cannot assign to property: 'item' is a 'let' constant. So the values in the enum are constant and I can not change them. I also tried to add mutating func setType(), but it also does not work. So any ideas how can I set this missing property in my model?



Solution 1:[1]

Just set the item in loop as var : But the result is that is work only if model is a class :

// This is just to show you how to declared method
// that work on struct/class in protocol extension
protocol MissingType {
    // struct/class must have a property named
    // missingType (can be computed var or not)
    var missingType: String {get set}
}

// a extension so that all models with this protocole
// (ie having a missingType property) can use
// this function
extension MissingType {
    mutating func setMissingType(str: String) {
        self.missingType = str
    }

    func printMissingType() {
        print("Missing type : \(self.missingType)")
    }

}

struct testModels {
    public class Model1: Codable, MissingType {
        let type1: String
        let type2: Int
        let type3: String
        var missingType: String
        init(type1: String, type2: Int, type3: String, missingType: String) {
            self.type1 = type1
            self.type2 = type2
            self.type3 = type3
            self.missingType = missingType
        }
    }
    public struct Model2: Codable {
        let type1: String
        let type2: Int
        let type3: String
        var missingType: String
        func printMissingType() {
            print("Missing type : \(self.missingType)")
        }
    }
    
    public struct Model3: Codable {
        let type1: String
        let type2: Int
        let type3: String
        var missingType: String
        func printMissingType() {
            print("Missing type : \(self.missingType)")
        }
    }

    public enum WalletSection {
        case model1(items: [Model1])
        case model2(items: [Model2])
        case model3(items: [Model3])
        
        func setMissingType() -> String {
            return "MT"
        }
    }
    
    func test() {
        func setMissingType() -> String {
            return "MT"
        }
        let section1 = WalletSection.model1(items: [Model1(type1: "t1", type2: 2, type3: "3", missingType: "mt"), Model1(type1: "t12", type2: 22, type3: "23", missingType: "m2t")])
        let section2 = WalletSection.model2(items: [Model2(type1: "2t1", type2: 222, type3: "3", missingType: "mt2"), Model2(type1: "t12", type2: 22, type3: "23", missingType: "m2t3")])

        for section in [section1, section2] {
            switch section {
                case .model1(let items):
                    print("modify section1")
                    // this use a function not declared in the type model1
                    for var item in items {
                        item.setMissingType(str: "11111")
                    }
                    print("items : \(items)")
                case .model2(let items):
                    print("modify section2")
                    for var item in items {
                        item.missingType = setMissingType()
                    }
                case .model3(let items):
                    for var item in items {
                        item.missingType = setMissingType()
                    }
            }
        }
        
        for section in [section1, section2] {
            switch section {
                case .model1(let items):
                    // here value has been modified
                    items.first?.printMissingType()
                case .model2(let items):
                    // here value was not modified
                    items.first?.printMissingType()
                case .model3(let items):
                    items.first?.printMissingType()
            }
        }

    }
    
}

let b = testModels()
b.test()

Hope this can help you

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1