在使用SwiftyJSON做数据传输的时候,经常需要从JSON格式中取值到对象中,在开发ios应用时,对象的字段和类型通常也是固定的,如何在接口获取到数据的时候优雅的进行类型转换是一个很值得考虑的细节。

优雅不仅是在可读性上提高,同时也方便后期对于数据格式的管理维护。

否则每次做细节调整的时候,需要查找所用的工作量就不可小觑了。

在网上也有通过反射机制来实现所有类自动转换的,见参考1。逻辑上是成立的,没有仔细研究。实际测试发现无法转换(与语言版本等可能有关)。

这里我先用比较务实的方式,做一层封装。主要完成的是将JSON赋值操作,写入到对象的结构体中,这样的话我们就不用在业务流程中进行复杂的赋值操作了。

1. 设计一个用于支持JSON互转的接口

这里我设计了两种初始化的方式,实际上一种就够了 主要是调用的时候写法略有不同,且便捷初始化开销更小一点。 我个人会喜欢以函数名来区分不同的运作方式,所以额外增加了静态的fromJSON方法


protocol JSONable {

    /** 便利初始化方式将对象注册为Object */
    convenience init( data:JSON )

    /** 静态函数方式 */
    static func fromJSON( data:JSON ) -> Self

    /** 将对象导出到JSON格式 */
    func toJSON() -> JSON?
}

2. 模型、结构体继承并实现接口


struct Category:JSONable{

    var id:String
    var count:Int
    var covers: [String]

    convenience init( data:JSON ){
        id = data["id"].stringValue
        count = data["count"].intValue
        covers = data["covers"].arrayValue as! [String]
    }

    static func fromJSON( data:JSON ){
        return self.init( id: data["id"].stringValue, count: data["count"].intValue, covers: data["covers"].arrayValue as! [String] )
    }

    func toJSON() -> JSON?{
        var j = JSON()
        j["id"].string = id
        j["count"].int = count
        j["covers"].array = covers
    }
}

3. 调用


let testJSONString = "{\"id\":\"test001\",\"count\":100,\"covers\":[\"a\",\"b\",\"c\"]}"
let testJSON = JSON.init(parseJSON: testJSONString)

// JSON转Model
// 方式1
var category = Category( data: testJSON )

// 方式2
var category = Category.fromJSON( data: testJSON )

// 转换到JSON
let jString = category.toJSON()

参考:

Swift反射之自定义对象转成JSON字符串

文章地址:




标签: swift, swiftyJSON, json, model

添加新评论