美文网首页
Swift 模型自动编码/解码(暂不支持嵌套)

Swift 模型自动编码/解码(暂不支持嵌套)

作者: SoaringHeart | 来源:发表于2019-10-17 09:49 被阅读0次

因为 swift NSCoding 方法是 required 修饰,所以无法通过 Objc 分类实现默认的编解码;只能在对应的方法中调用通用方法。用于储存详情 model,特别方便

@objc public extension NSObject{
    
    /// 类的字符串名称
    static let identifier = String(describing: self)
    ///遍历成员变量列表
    func enumerateIvars(_ block: @escaping ((Ivar, String, Any?)->Void)) {
        var count: UInt32 = 0
        guard let list = class_copyIvarList(self.classForCoder, &count) else { return }
        defer {
            free(list)// 释放c语言对象
        }

        for i in 0..<Int(count) {
            let ivar = list[i]
            //转换成String字符串
            guard let name = ivar_getName(ivar),
                let strName = String(cString: name, encoding: String.Encoding.utf8) else {
                //继续下一次遍历
                continue
            }
            //利用kvc 取值
            let value = self.value(forKey: strName)
            block(ivar, strName, value)
        }
    }
    ///遍历属性列表
    func enumeratePropertys(_ block: @escaping ((objc_property_t, String, Any?)->Void)) {
        var count: UInt32 = 0
        guard let list = class_copyPropertyList(self.classForCoder, &count) else { return }
        defer {
            free(list)// 释放c语言对象
        }
        
        for i in 0..<Int(count) {
            let property: objc_property_t = list[i]
            //获取成员变量的名称 -> c语言字符串
            let name = property_getName(property)
            //转换成String字符串
            guard let strName = String(cString: name, encoding: String.Encoding.utf8) else {
                //继续下一次遍历
                continue
            }
            //利用kvc 取值
            let value = self.value(forKey: strName)
            block(property, strName, value)
        }
    }
    ///遍历方法列表
    func enumerateMethods(_ block: @escaping ((Method, String)->Void)) {
        var count: UInt32 = 0
        guard let list = class_copyMethodList(self.classForCoder, &count) else { return }
        defer {
            free(list)// 释放c语言对象
        }

        for i in 0..<Int(count) {
            let method: Method = list[i]
            //获取成员变量的名称 -> c语言字符串
            let name: Selector = method_getName(method)
            //转换成String字符串
            let strName = NSStringFromSelector(name)
            block(method, strName)
        }
    }
    ///遍历遵循的协议列表
    func enumerateProtocols(_ block: @escaping ((Protocol, String)->Void)) {
        var count: UInt32 = 0
        guard let list = class_copyProtocolList(self.classForCoder, &count) else { return }

        for i in 0..<Int(count) {
            let proto: Protocol = list[i]
            //获取成员变量的名称 -> c语言字符串
            let name = protocol_getName(proto)
            //转换成String字符串
            guard let strName = String(cString: name, encoding: String.Encoding.utf8) else {
                //继续下一次遍历
                continue
            }
            block(proto, strName)
        }
    }

    /// 模型自动编码
    func se_encode(with aCoder: NSCoder) {
        enumeratePropertys { (property, name, value) in
            guard let value = self.value(forKey: name) else { return }
            //进行编码
            aCoder.encode(value, forKey: name)
        }
    }
    
    /// 模型自动解码
    func se_decode(with aDecoder: NSCoder) {
        enumeratePropertys { (property, name, value) in
            //进行解档取值
            guard let value = aDecoder.decodeObject(forKey: name) else { return }
            //利用kvc给属性赋值
            self.setValue(value, forKeyPath: name)
        }
    }

    /// 字典转模型
    convenience init(dic: [String: Any]) {
        self.init();
        self.setValuesForKeys(dic)
    }
    ///详情模型转字典(不支持嵌套)
    func toDictionary() -> [AnyHashable : Any] {
        var dic: [AnyHashable : Any] = [:]
        self.enumeratePropertys { (property, name, value) in
            dic[name] = value ?? ""
        }
        return dic
    }
}

🌰🌰:
@objcMembers
class CCSParkItemModel: NSObject, HandyJSON, NSCoding {

    var arm_version: String = ""

    var channel_list: [CCSParkChannelModel]?

    var park_code: String = ""

    var parking_name: String = ""

    required override init() {}
    func mapping(mapper: HelpingMapper) {

    }
    
    // MARK: -NSCoding
    required init?(coder aDecoder: NSCoder) {
        super.init()
        se_decode(with: aDecoder)
    }
    
    func encode(with aCoder: NSCoder) {
        se_encode(with: aCoder)
    }
    
//    required init?(coder aDecoder: NSCoder) {
//        arm_version = aDecoder.decodeObject(forKey: "arm_version") as! String
//        channel_list = aDecoder.decodeObject(forKey: "channel_list") as? [CCSParkChannelModel]
//        park_code = aDecoder.decodeObject(forKey: "park_code") as! String
//        parking_name = aDecoder.decodeObject(forKey: "parking_name") as! String
//    }
//
//    func encode(with aCoder: NSCoder) {
//        aCoder.encode(arm_version, forKey: "arm_version")
//        aCoder.encode(channel_list, forKey: "channel_list")
//        aCoder.encode(park_code, forKey: "park_code")
//        aCoder.encode(parking_name, forKey: "parking_name")
//    }
    
}

相关文章

网友评论

      本文标题:Swift 模型自动编码/解码(暂不支持嵌套)

      本文链接:https://www.haomeiwen.com/subject/jrcmmctx.html