1. HandyJSON的应用
想要通过HandyJSON
实现序列化和反序列化, 必须实现HandyJSON
协议, 不需要继承NSObject对象, 实现协议必须实现public init(){} 方法.
序列化和反序列化支持struct和enumerate类型.
HandyJSON可支持非基础类型
var bool: Bool = true
var intOptional: Int?
var doubleImplicitlyUnwrapped: Double!
var anyObjectOptional: Any?
var arrayInt: Array<Int> = []
var arrayStringOptional: Array<String>?
var setInt: Set<Int>?
var dictAnyObject: Dictionary<String, Any> = [:]
var nsNumber = 2
var nsString: NSString?
1.1 反序列化
class BasicTypes: HandyJSON {
var int: Int = 2
var doubleOptional: Double?
var stringImplicitlyUnwrapped: String!
required init() {}
}
let jsonString = "{\"doubleOptional\":1.1,\"stringImplicitlyUnwrapped\":\"hello\",\"int\":1}"
if let object = BasicTypes.deserialize(from: jsonString) {
print(object.int)
print(object.doubleOptional!)
print(object.stringImplicitlyUnwrapped)
}
// HandyJSON提供的几种序列化的方法
let person = SOHomeModel.deserialize(from: <#T##NSDictionary?#>)
let person = SOHomeModel.deserialize(from: <#T##NSDictionary?#>, designatedPath: <#T##String?#>)
let person = SOHomeModel.deserialize(from: <#T##String?#>)
let person = SOHomeModel.deserialize(from: <#T##String?#>, designatedPath: <#T##String?#>)
let persons = [SOHomeModel].deserialize(from: <#T##String?#>)
let persons = [SOHomeModel].deserialize(from: <#T##String?#>, designatedPath: <#T##String?#>)
1.2 序列化
序列化, 支持序列化成字符串, dictionary.
let object = BasicTypes()
object.int = 1
object.doubleOptional = 1.1
object.stringImplicitlyUnwrapped = “hello"
print(object.toJSON()!) // serialize to dictionary
print(object.toJSONString()!) // serialize to JSON string
print(object.toJSONString(prettyPrint: true)!) // serialize to pretty JSON string
1.3 可指定解析路径
let jsonString = "{\"code\":200,\"msg\":\"success\",\"data\":{\"cat\":{\"id\":12345,\"name\":\"Kitty\"}}}"
if let cat = Cat.deserialize(from: jsonString, designatedPath: "data.cat") {
print(cat.name)
}
注意,如果Model的属性不是基本类型或集合类型,那么它必须是一个服从HandyJSON协议的类型。 如果是泛型集合类型,那么要求泛型实参是基本类型或者服从HandyJSON协议的类型。
1.4 HandyJSON支持自定义解析规则
还没看明白, 还不会用
1.5 排除指定属性
如果在Model中存在因为某些原因不能实现HandyJSON协议的非基本字段,或者不能实现HandyJSONEnum协议的枚举字段,又或者说不希望反序列化影响某个字段,可以在mapping函数中将它排除。如果不这么做,可能会出现未定义的行为。 (其实这个还不太明白, 就是说如果不想让序列化影响某个字段, 就在mapping方法中忽略吗? 测试发现忽略后一样会赋值)
class NotHandyJSONType {
var dummy: String?
}
class Cat: HandyJSON {
var id: Int64!
var name: String!
var notHandyJSONTypeProperty: NotHandyJSONType?
var basicTypeButNotWantedProperty: String?
required init() {}
func mapping(mapper: HelpingMapper) {
mapper >>> self.notHandyJSONTypeProperty
mapper >>> self.basicTypeButNotWantedProperty
}
}
let jsonString = "{\"name\":\"cat\",\"id\":\"12345\"}"
if let cat = Cat.deserialize(from: jsonString) {
print(cat)
}
2.SwiftyJSON的应用
// 初始化
let json = JSON(data: jsonData)
if let number = json[0]["phones"][0]["number"].string {
// 找到电话号码
print("第一个联系人的第一个电话号码:",number)
}
与Alamofire结合
//创建URL对象
let url = URL(string:"http://www.hangge.com/getJsonData.php")!
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)
}
}
2.1 可选值和不可选值
1.可选值获取(Optional getter)
通过.number、.string、.bool、.int、.uInt、.float、.double、.array、.dictionary、int8、Uint8、int16、Uint16、int32、Uint32、int64、Uint64等方法获取到的是可选择值,我们需要自行判断是否存在,同时不存在的话可以获取具体的错误信息。
//int
if let age = json[0]["age"].int {
print(age)
} else {
//打印错误信息
print(json[0]["age"])
}
//String
if let name = json[0]["name"].string {
print(name)
} else {
//打印错误信息
print(json[0]["name"])
}
2.不可选值获取(Non-optional getter)
使用 xxxValue 这样的属性获取值,如果没获取到的话会返回一个默认值。省得我们再判断拆包了。
//If not a Number or nil, return 0
let age: Int = json[0]["age"].intValue
//If not a String or nil, return ""
let name: String = json[0]["name"].stringValue
//If not a Array or nil, return []
let list: Array<JSON> = json[0]["phones"].arrayValue
//If not a Dictionary or nil, return [:]
let phone: Dictionary<String, JSON> = json[0]["phones"][0].dictionaryValue
3.获取原始数据(Raw object)
let jsonObject = json.object as AnyObject
let jsonObject = json.rawValue as AnyObject
//JSON转化为Data
let data = json.rawData()
//JSON转化为String字符串
if let string = json.rawString() {
//Do something you want
}
//JSON转化为Dictionary字典([String: AnyObject]?)
if let dic = json.dictionaryObject {
//Do something you want
}
//JSON转化为Array数组([AnyObject]?)
if let arr = json.arrayObject {
//Do something you want
}
4.设置值
json[0]["age"].int = 101
json[0]["name"].string = "hangge.com"
json[0]["phones"].arrayObject = [["name":"固话", "number":110],["name":"手机", "number":120]]
5.下标访问(Subscript)
//方式1
let number = json[0]["phones"][0]["number"].stringValue
//方式2
let number = json[0,"phones",0,"number"].stringValue
//方式3
let keys:[JSONSubscriptType] = [0,"phones",0,"number"]
let number = json[keys].stringValue
6.循环遍历JSON对象中的所有数据
(1)如果JSON数据是数组类型(Array)
for (index,subJson):(String, JSON) in json {
print("\(index):\(subJson)")
}
(2)如果JSON数据是字典类型(Dictionary)
for (key,subJson):(String, JSON) in json[0] {
print("\(key):\(subJson)")
}
Reference:
https://github.com/alibaba/HandyJSON/blob/master/README_cn.md
http://www.hangge.com/blog/cache/detail_968.html