I have some objects, which are structs, that I initialize from JSON dictionaries ([String : Any]) via an init function provided from an extension on the Decodable protocol (see Init an object conforming to Codable with a dictionary/array).
So basically, I have objects that look like this:
struct ObjectModelA: Codable {
    var stringVal: String
    var intVal: Int
    var boolVal: Bool
    // Coding keys omitted for brevity
}
struct ObjectModelB: Codable {
    var doubleVal: Double
    var arrayOfObjectModelAVal: [ObjectModelA]
    // Coding keys omitted for brevity
    var complicatedComputedVar: String {
        // expensive operations using the values in arrayOfObjectModelAVal
    }
}
ObjectModelB contains an array of ObjectModelA, and it also has a property which I only really want to set if the arrayOfObjectModelAVal changes.
I can use a didSet on arrayOfObjectModelAVal, but that only catches future changes to the arrayOfObjectModelAVal property. The problem is that I'm using a webservice to retrieve JSON data to create an array of ObjectModelB ([[String : Any]]), and I build it like this:
guard let objectDictArray = responseObject as? [[String : Any]] else { return }
let objects = objectDictArray.compactMap({ try? ObjectModelB(any: $0) })
My objects get created inside the compactMap closure, and init doesn't trigger the didSet.
I also can't "override" the init provided by the init from the Decodable protocol (the one in the closure: try? ObjectModelB(any: $0)) because my object is a struct and this isn't inheritance, it's just an initializer provided by a protocol. Otherwise, I'd "override" the init in my object and then just do super.init followed by some sort of mutating function that updates my complicated property and I'd make my complicated property private(set).
The only other option I can think of is creating that mutating function I just mentioned, and calling it in both the didSet when arrayOfObjectModelAVal changes, and then update my object initialization call with something like this:
guard let objectDictArray = responseObject as? [[String : Any]] else { return }
let objects = objectDictArray
    .compactMap({ try? ObjectModelB(any: $0) })
    .forEach({ $0.updateProperties() })
But now updateProperties could be called at any time by anyone (which is bad because it's really taxing), and there's no guarantee that it even gets called when creating the array of objects because the dev could forget to do the forEach part. Hence why I want a way to automatically call the updateProperties function right after object initialization.
