IOS开发

49. 自定义model类对象转json

2017-08-25  本文已影响43人  noonez

每次写完model都想看下数据是否正确都要写一些输出格式的字符串,为了方便写了简单的工具类。当然使用有些限制:
其中model类必须继承自NSObject类,不能转化为json的部分(比如枚举类型)会被直接丢弃,空属性不会导出.

支持model属性使用嵌套model,使用数组和字典属性,支持继承

/// model转json工具.其中model类必须继承自NSObject类,不能转化的部分会被直接丢弃,空属性不会导出
class ModelToJSON: NSObject {
    
    static func handle(model:NSObject)->String{
        let mtj = ModelToJSON(model: model)
        return mtj.json
    }
    
    let model:NSObject
    var json:String = ""
    init(model:NSObject) {
        self.model = model
        super.init()
        let dict = handleModel(model: model)
        do{
            let json = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
            if let str = String(data: json, encoding: .utf8){
                self.json = str
            }
        }catch{
            print("JSON化失败")
        }
    }
    
    func handleModel(model:NSObject) -> [String:Any] {
        var dict = [String:Any]()
        var mirror:Mirror? = Mirror(reflecting: model)
        while mirror != nil {
            if let list = mirror?.children {
                for item in list {
                    if let prop = item.label {
                        if let value = handleValue(value: item.value) {
                            dict[prop] = value
                        }
                    }
                }
            }
            mirror = mirror?.superclassMirror
        }
        return dict
    }
    func handleValue(value:Any) -> Any? {
        if let number = value as? NSNumber {
            return number
        }else if let str = value as? String {
            return str
        }else if let b = value as? Bool {
            return b
        }else if let arr = value as? [Any] {
            return handleArray(arr: arr)
        }else if let dict = value as? [String:Any] {
            return handleDict(dict: dict)
        }else if let other = value as? NSObject {
            return handleModel(model: other)
        }
        return nil
    }
    func handleArray(arr:[Any]) -> [Any] {
        var jsonArr = [Any]()
        for item in arr {
            if let tmp = handleValue(value: item) {
                jsonArr.append(tmp)
            }
        }
        return jsonArr
    }
    func handleDict(dict:[String:Any]) -> [String:Any] {
        var jsonDict = [String:Any]()
        for (key, value) in dict {
            if let tmp = handleValue(value: value) {
                jsonDict[key] = tmp
            }
        }
        return jsonDict
    }
}

调用很简单:

print("json:", ModelToJSON.handle(model: model))

甚至可以将它添加为NSObject类的扩展

/// NSObject 扩展输出json串
extension NSObject{
    func toJSON() -> String {
        return ModelToJSON.handle(model: self)
    }
}
/// 调用
print("json:", model.toJSON())

有其它需求可以自行修改

测试用例:

class BaseModel: NSObject {
    var id = 0
    var name = "John"
}

class TestModel: BaseModel {
    var age:Int = 30
    var list:[Any] = [1, "test", ["name":"hel", "age": 20]]
    var dict:[String:Any] = ["aaa":3, "bbb":[1, 3, 5, "test", ["name":"ggo"]]]
    var other:BaseModel = BaseModel()
    var empty:String?
    var optionalStr:String? = "eee"
    var optionalInt:Int? = 1
    var optionalFloat:Float = 0.03
    var optionalDouble:Double = 0.02
    var optionalNumber:NSNumber? = 5.1
}

let model = TestModel()
print(model.toJSON())

输出结果:

{
  "name" : "John",
  "optionalDouble" : 0.02,
  "optionalStr" : "eee",
  "optionalFloat" : 0.03,
  "optionalNumber" : 5.1,
  "id" : 0,
  "optionalInt" : 1,
  "list" : [
    1,
    "test",
    {
      "name" : "hel",
      "age" : 20
    }
  ],
  "age" : 30,
  "dict" : {
    "bbb" : [
      1,
      3,
      5,
      "test",
      {
        "name" : "ggo"
      }
    ],
    "aaa" : 3
  },
  "other" : {
    "id" : 0,
    "name" : "John"
  }
}
上一篇下一篇

猜你喜欢

热点阅读