-
Notifications
You must be signed in to change notification settings - Fork 7
Home
PonyCui edited this page Jul 1, 2015
·
9 revisions
PPJSONSerialization 是使用Swift语言编写的JSON解析Helper类,它可以帮助你将JSON数据转换成Swift实体类。
感谢 SwiftyJSON (https://github.com/SwiftyJSON/SwiftyJSON) 为我们开源了一个相当易用的JSON库。
使用 SwiftyJSON 的方法就像下面这样。
let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string{
//Now you got your value
}
我的个人看法是,既然苹果给予了我们一个强类型的语言,我们为什么不去好好利用呢?
所以,当你使用 PPJSONSerialization 的时候,代码会是这样子的。
// 定义一个类 ```SimpleStruct```;
// 所有的属性都必须给定一个默认值并且指明类型。
class SimpleStruct: PPJSONSerialization {
var simpleStr = ""
var simpleInt = 0
var simpleBool = false
var simpleDouble = 0.0
var simpleArray = [0]
}
let simpleJSON = "{\"simpleStr\":\"String Value\", \"simpleInt\":1024, \"simpleBool\": true, \"simpleDouble\": 1024.00, \"simpleArray\": [1,0,2,4]}"
if let simpleObject = SimpleStruct(JSONString: simpleJSON) {
print(simpleObject.simpleStr) // 使用JSON的值就像使用类的属性一样简单
}
不用担心类型问题,你为SimpleStruct当中的属性指定了类型,PPJSONSerialization会尽一切能力将值转换过来。
func testTypeTransfer() {
let typeErrorJSON = "{\"simpleStr\": 1024, \"simpleInt\": \"1024\", \"simpleBool\": null, \"simpleDouble\": \"Bool Value\", \"simpleArray\": {}}"
if let simpleObject = SimpleStruct(JSONString: typeErrorJSON) {
XCTAssert(simpleObject.simpleStr == "1024", "Pass")
XCTAssert(simpleObject.simpleInt == 1024, "Pass")
XCTAssert(simpleObject.simpleBool == false, "Pass")
XCTAssert(simpleObject.simpleDouble == 0.0, "Pass")
XCTAssert(simpleObject.simpleArray.count <= 0, "Pass")
}
}
你定义的结构类可能包含另一个结构类,又或者数组里面包含的是另一个结构类的集合,PPJSONSerialization可以轻松应对这种情况。
// 定义一个结构类,BuildingStruct
class BuildingStruct: PPJSONSerialization {
var buildNumber = ""
var managementRoom = RoomStruct()
var buildRooms = [RoomStruct()]
}
// 定义另一个结构类,RoomStruct
class RoomStruct: PPJSONSerialization {
var roomNumber = 0
var roomSize: Double = 0.0
// 如果这个结构会被数组包含,那么改写copyWithZone并返回自身的新实例是必要的。
override func copyWithZone(zone: NSZone) -> AnyObject {
return RoomStruct()
}
}
func testDictionaryContainsJSON() {
let dictionaryContainsJSON = "{\"buildNumber\": \"B\", \"managementRoom\":{\"roomNumber\":101, \"roomSize\":10.14}, \"buildRooms\":[{\"roomNumber\":632, \"roomSize\":6.6}, {\"roomNumber\":633, \"roomSize\":6.7}]}"
if let buildingObject = BuildingStruct(JSONString: dictionaryContainsJSON) {
XCTAssert(buildingObject.buildNumber == "B", "Pass")
XCTAssert(buildingObject.managementRoom.roomNumber == 101, "Pass")
XCTAssert(buildingObject.managementRoom.roomSize == 10.14, "Pass")
XCTAssert(buildingObject.buildRooms.count == 2, "Pass")
XCTAssert(buildingObject.buildRooms[0].roomNumber == 632, "Pass")
XCTAssert(buildingObject.buildRooms[0].roomSize == 6.6, "Pass")
XCTAssert(buildingObject.buildRooms[1].roomNumber == 633, "Pass")
XCTAssert(buildingObject.buildRooms[1].roomSize == 6.7, "Pass")
}
}
改写mapping()方法,返回自己的map数据,这样你就可以将JSON的字段映射到Class里面的自定义字段了。
// Define a Map Struct and override mapping() return, you can map the JSON key to Custom Property key
class MapStruct: PPJSONSerialization {
override func mapping() -> [String : String] {
return ["mapStr": "simpleStr"]
}
var simpleStr = ""
}
func testMapping() {
let simpleJSON = "\"mapStr\": \"String Value\""
if let simpleObject = MapStruct(JSONString: simpleJSON) {
XCTAssert(simpleObject.simpleStr == "String Value", "Pass")
}
}
PPJSONSerialization 仍然在开发中,欢迎fork和pull request。
- iOS 7.0+ / Mac OS X 10.10+
- Xcode 6.3
- 暂时不支持 Xcode7.0 beta, Swift2.0仍然在改动中,在Swift2.0正式发布后,PPJSONSerialization再作兼容。
将 PPJSONSerialization.swift
添加到你的工程里面
MIT License 自由使用
感谢 @onevcat 喵大建议加入Failable init