EASON = Easy JSON. 它简化了Swift中的JSON反序列化。它提供:
platform :ios, '8.0'
use_frameworks!
pod 'EASON'
在项目中,您可以导入EASON框架
import EASON
从这里获取源代码。您可以手动将源代码添加到您的项目中。您只需要导入以下一个文件:EASON.swift
导入之后,您可以将从Array、Dictionary、String或NSData转换来的JSON实例转换为JSONObject实例。JSONObject实例是您可以与之交互的主要对象:例如
将字典转换为JSONObject
let object = ["name": "Hello", "id": 123]
let jsonObject = JSONObject(object)
print(jsonObject["name"].stringValue)
print("\(jsonObject["id"].intValue)")
将数组转换为JSONObject
let jsonArray:JSONObject = ["This", "is", "a", "string", 1, 2, 3, 4]
print(jsonArray[0].string)
print(jsonArray[1].string)
print(jsonArray[2].string)
print(jsonArray[3].string)
print("\(jsonArray[4].intValue)")
print("\(jsonArray[5].intValue)" + "\(jsonArray[6].intValue)")
将字符串转换为JSONObject
使用以下初始化函数将字符串转换为JSONObject
public struct JSONObject {
public init(string: String?)
...
let jsonString = "{\"name\": \"hello\", \"id\":123}"
let jsonObject = JSONObject(string: jsonString)
print(jsonObject["name"].stringValue)
print("\(jsonObject["id"].intValue)")
使用以下初始化函数将NSData转换为JSONObject
public struct JSONObject {
public init(data: NSData?)
...
if let path = NSBundle(forClass: BaseTests.self).pathForResource("twitter", ofType: "json") {
let data: NSData?
do {
data = try NSData(contentsOfFile: path, options: [])
} catch _ {
data = nil
}
let jsonArray = JSONObject(data:data)
for jsonObject in jsonArray{
print("\(jsonObject["id"].int)")
print(jsonObject["text"].string)
}
}
可以使用下标访问JSONObject中的字段。例如
let jsonString = "{\"name\": \"hello\", \"id\":123}"
let jsonObject = JSONObject(string: jsonString)
print(jsonObject["name"].stringValue)
print("\(jsonObject["id"].intValue)")
不用担心访问超出数组或字典边界的下标值。在这些情况下不会抛出异常,并将返回nil。
通常JSON对象是一个数组。您可以使用循环遍历数组中的元素
let data: NSData?
do {
data = try NSData(contentsOfFile: path, options: [])
} catch _ {
data = nil
}
let jsonArray = JSONObject(data:data)
for jsonObject in jsonArray{
print("\(jsonObject["id"].int)")
print(jsonObject["text"].string)
}
将网络服务返回的 JSON 响应转换为用户自定义类的实例是一个非常常见的任务。EASON 提供了一组 Utils 方法和协议来帮助您完成此任务。您可以将 JSONSerialization
协议添加到自定义类中。您需要实现所需的 init 方法。
init?(jsonObject: JSONObject)
在 init 方法中,您可以定义 JSON 字段和类属性之间的关系。例如,我定义了一个类来代表 Twitter 中的推文。
class Tweet: NSObject, JSONSerialization {
var id:Int?
var createdAt:NSDate?
var user:TweetUser?
var text:String?
required init?(jsonObject: JSONObject) {
self.id = jsonObject["id"].string
self.text = jsonObject["text"].string
self.createdAt = JSONObject.dateTransformer(jsonObject["created_at"], dateFormatter: "EEE MMM dd HH:mm:ss Z yyyy")
self.user = JSONObject.objectTransformer(jsonObject["user"])
}
}
JSONObject.dateTransformer
方法是一个辅助类,用于将字符串转换为 NSDate
对象。
请注意,在 Tweet
类中,user
属性也是一个用户定义的类实例,将字段转换为 TweetUser
实例。
TweetUser
类也需要实现 JSONSerialization
协议。之后,您可以使用辅助方法 JSONObject.objectTransformer
将 user
字段转换为 user
,类型为 TweetUser
类。下面是 TweetUser
类的定义:
class TweetUser: NSObject, JSONSerialization {
var id:Int?
var name:String?
var profile_image_url:NSURL?
required init?(jsonObject: JSONObject) {
self.name = jsonObject["name"].string
self.id = jsonObject["id"].string
self.profile_image_url = jsonObject["profile_image_url"].URL
}
}
在某些情况下,您希望将 JSON 响应中的子字段转换为用户定义类对象数组。您可以使用 JSONObject.arrayTransformer
辅助方法来实现这一点。例如,如果您想将 JSON 响应中的子字段转换为 [Tweet]
对象数组,可以使用以下命令:
var tweets = JSONObject.arrayTransformer(jsonObject["tweets"])
遵循此模式,可以将 JSON 响应转换为具有多层结构的用户自定义类。请参阅 Demonstration 项目中从 Twitter 样本响应反序列化推文的示例。
在下一节中,我们将使用自定义运算符来简化此过程。
注意,在前面的章节中,我们需要决定类中的字段是否需要分配字符串或整数值。您可以使用以下自定义运算符来简化此操作。它们的定义如下。
=~ 运算符
如果 JSONObject 实例可以转换为给定的类,则使用转换后的值分配实例对象。如果 JSONObject 实例不能转换为具有给定类的对象,则运算符不会执行任何操作。使用该运算符将 JSONOjbect 实例转换为任何非可选类型 T。
=? 运算符
如果 JSONObject 实例可以转换为给定的类,则使用转换后的值分配实例对象。如果 JSONObject 实例不能转换为具有给定类的对象,则将左侧对象赋值为 nil。使用此运算符将 JSONObject 实例转换为任何可选类型 T?
=! 运算符
如果 JSONObject 实例可以转换为给定的类,则分配实例对象与具有转换值的类。如果 JSONObject 实例不能转换为具有给定类的对象,则将左侧对象分配为类的默认值。此运算符可用于将 JSONObject 实例转换为任何类型 T、T? 或 T!。由于 EASON 不了解用户定义类的默认值,因此 =! 不能用于用户定义类。您可以使用 =? 或 =~ 进行转换。
使用自定义运算符,上一节中的转换过程可以简化如下:
class Tweet: NSObject, JSONSerialization {
var id:Int?
var createdAt:NSDate?
var user:TweetUser?
var text:String?
required init?(jsonObject: JSONObject) {
self.id =? jsonObject["id"]
self.text =? jsonObject["text"]
self.user =? jsonObject["user"]
// Use custom transformer to convert string to NSDate
self.createdAt = JSONObject.dateTransformer(jsonObject["created_at"], dateFormatter: "EEE MMM dd HH:mm:ss Z yyyy")
}
}
class TweetUser: NSObject, JSONSerialization {
var id:Int?
var name:String?
var profile_image_url:NSURL?
required init?(jsonObject: JSONObject) {
self.name =? jsonObject["name"]
self.id =? jsonObject["id"]
self.profile_image_url =? jsonObject["profile_image_url"]
}
}
所有源代码均受 MIT 许可证 许可。