Swift Json解析方法

语意php

序列化:将数据类型和对象转换成二进制数据json

反序列化:将返回的二进制数据转换成对象和其它数据结构swift


handyJSON

比较好用的JSON转义Model,使用中帮咱们把数据转成完成class、struct数组

**反序列化
//1.声明一个model,继承HandyJSON协议 (枚举继承 HandyJSONEnum协议)
//嵌套:遇到复杂的状况model嵌套model 只须要继承HandyHSON就能够
//继承:只须要父类继承HandyJSON就能够
class Model: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!

    required init() {}//若是是class类型,须要加入这一步,否则会报错
}
//2. jsonString 传入须要反序列化的数据
// 得到某个个结点的数据结构 用这个方法:designatedPath
if let animal = Model.deserialize(from: jsonString) {
    print(animal)//结果是model类型,须要用点语法得到属性值
}复制代码

**序列化
//1.声明一个model,继承HandyJSON协议
class Bob: HandyJSON {
     required init() {}
     var int: Int = 30
     var fou: Double?
     var strinfmp: String?
     }
     //2.生成对应的model对象
     let obje = Bob()
     obje.int = 1
     obje.fou = 1.1
     obje.strinfmp = "hello"
     //3.点语法方法,序列化   
     print(obje.toJSON()!) // dictionary(字典)
     print(obje.toJSONString()!) // JSON string(JSON)
     print(obje.toJSONString(prettyPrint: true)!) // pretty JSON string (映射json字符串)复制代码

**自定义(适用于更改model内属性的名称,解析麻烦的数据结构,如元祖类型数据)
//1.声明一个model,继承HandyJSON协议
class Cat: HandyJSON {
    var id: Int64!
    var name: String!
    var parent: (String, String)?

    required init() {}
	
	//2.实现函数 mapping方法
    func mapping(mapper: HelpingMapper) {
        //3. 使用specify(property:)自定义字段内容
        mapper.specify(property: &id, name: "cat_id")
        mapper.specify(property: &parent) { (rawString) -> (String, String) in
            let parentNames = rawString.characters.split{$0 == "/"}.map(String.init)
            return (parentNames[0], parentNames[1])
        }
    }
}复制代码

问:为何 mapping函数在继承的子类里很差使?
答:由于Swift类型相关的缘由,若是须要在子类里使用mapping函数,那么必须在父类(若是有多层父类,必须在最顶层的父类)里定义一个空的mapping函数,而后在子类去override它。同样状况的还有didFinishMapping函数。

swiftyJSON

方便的获取节点层面的信息,不用担忧数组越界并自动对可选类型进行拆包。
bash

**反序列化
(解析本地JSON)
//JSON 转 Data
let data = "{\"doubleOptional\":1.1,\"stringImplicitlyUnwrapped\":\"hello\",\"int\":1}"
if let dataFromString = data.data(using: .utf8, allowLossyConversion: false) {
	let json = try! JSON(data: dataFromString)
	//获取全部字段的的键值
	for (index,obj) in json {
        print("\(index) : \(obj)")
    }
	//获取指定字段头的value
	if let dou = json["stringImplicitlyUnwrapped"].string {
		print("data \(dou)")
	}else {
		//打印错误信息
	}
}
复制代码

**序列化

//简单数据类型
let json: JSON = "I'm a son"

//Array & Dictionary
var json: JSON =  ["name": "Jack", "age": 25, "list": ["a", "b", "c", ["what": "this"]]]
json["list"][3]["what"] = "that"
json["list",3,"what"] = "that"
let path:[JSONSubscriptType] = ["list",3,"what"]
json[path] = "that"复制代码

(获取网络URL解析数据)
//建立URL对象
let url = URL(string:"http://www.hangge.com/getJsonData.php")!
// Alamofire框架 
Alamofire.request(url).validate().responseJSON { response in
    switch response.result.isSuccess {
    case true:
        if let value = response.result.value {
            let json = JSON(value)
            if let number = json[0]["phones"][0]["number"].string {
                // 找到电话号码
                print("第一个联系人的第一个电话号码:",number)
            }
        }
    case false:
        print(response.result.error)
    }
}复制代码

Codable(原生)

Apple 在 Swift 4 的 Foundation 的模块中添加了对 JSON 解析成Model的原生支持。
网络

关于 Codable 同时声明了 Decodable 和 Encodable 两个协议,只须要单向处理能够只声明一个。
/// A type that can convert itself into and out of an external representation.
public typealias Codable = Decodable & Encodable复制代码
须要知足Codable协议。
须要JSON数据结构和Model对象结构同样,任何差异都会致使解析式失败。

**自定义键值名
struct UserList: Codable {
    let userInfos: [UserInfo]
    
    struct UserInfo: Codable {
        let userName: String
        let age: Int
        let bodyHeight: Float
        let sex: Bool
        
        private enum CodingKeys: String, CodingKey {
            case userName
            case age
            case bodyHeight = "height"
            case sex
        }
    }
}复制代码

**格式处理
包括属性和方法,可根据本身的须要设置想要的格式。

// outputFormatting属性,提升阅读体验
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted复制代码

**定义可选值
若是JSON的数据结构中,有些 Key - Value 不必定出现,Model中对应的要使用可选类型
例子:
(json)
{
    "userInfos": [
        {
            "userName": "小名",
            "age": 18,
            "sex": true
        },
        {
            "userName": "小方",
            "age": 18,
            "height": 162.56,
            "sex": false
        }
    ]
}
(model)
struct UserList: Codable {

    let userInfos: [UserInfo]

    struct UserInfo: Codable {

        let userName: String
        let age: Int
  	 	let height: Float?(可选)
        let sex: Bool
    }
}复制代码


好久不写swift有些生疏了,最近我也在回顾有关swift的代码,同时也一直在思考swift该如何写,才能驾轻就熟,才能更像一个优雅的工具,由于会用和用好它差异仍是挺大的,会一直不断探索iOS的更多有趣性。加油吧!
数据结构

相关文章
相关标签/搜索