jeudi 16 septembre 2021

IOS - Generic Decoder with reflection

I am using Realm with Swift. I need to create a generic method to initialize Realm classes with the type "required init(from: decoder: Decoder) because i can't write an initializer for every class. Possibly, i need even a method to generate CodingKeys automatically, because they are always the same as the class fields.

I tried with reflection but i's not working, because "mirror.children" is always empty.

Could someone help me?

Thank you for your patience and help!

This is my actual Code, and i wanna generalize the init(from decoder:Decoder)

import Foundation
import RealmSwift

class Items: Object, Decodable {
    
    var id = RealmProperty<Int?>()
    @objc dynamic var prop1: String? = nil
    @objc dynamic var prop2: String? = nil
    
    override static func primaryKey() -> String? {
        "id"
    }
    
    override init() {
        super.init()
    }
    
    enum CodingKeys: String, CodingKey {
        case id, prop1, prop2
        
    }
    
    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let idV = Int(try (values.decodeIfPresent(String.self, forKey: .id) ?? "0"))
        id.value = idV
        prop1 = try values.decodeIfPresent(String.self, forKey: .prop1)
        prop2 = try values.decodeIfPresent(String.self, forKey: .prop2)
    }

    
}

This was the function i tried to do with reflection, but children is always empty. With this function i would loop over every field to specify how to decode it, in base of his type.

func reflect <T : Decodable>(_ t: T.Type){

let mirror = Mirror(reflecting: T.self)
        
for field in mirror.children {
    print("value: \(field.value)")
}

}

Thanks again!





Aucun commentaire:

Enregistrer un commentaire