Eason 1.0.5

Eason 1.0.5

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布最后发布2016年4月
SPM支持SPM

Jie Cao维护。



Eason 1.0.5

  • 作者:
  • Jie

EASON中文介绍

EASON = Easy JSON. 它简化了Swift中的JSON反序列化。它提供:

  • 将字符串、数组字典反序列化为JSON格式中的对象。
  • 一个强大的JSONObject结构,可以以不同方式分配和访问。
  • 将JSONObject实例转换为自定义类的一系列Utils方法和协议。
  • 一组自定义运算符,使得反序列化和对象映射过程变得更简单。
  • 与Swift中许多JSON反序列化框架相比,反序列化过程具有高性能。

安装

Podfile

platform :ios, '8.0'
use_frameworks!
pod 'EASON'

在项目中,您可以导入EASON框架

import EASON

手动

这里获取源代码。您可以手动将源代码添加到您的项目中。您只需要导入以下一个文件:EASON.swift

用法

使用JSONObject

导入之后,您可以将从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的字段

可以使用下标访问JSONObject中的字段。例如

let jsonString = "{\"name\": \"hello\", \"id\":123}"
let jsonObject = JSONObject(string: jsonString)
print(jsonObject["name"].stringValue)
print("\(jsonObject["id"].intValue)")

不用担心访问超出数组或字典边界的下标值。在这些情况下不会抛出异常,并将返回nil。

使用迭代访问JSONObject的字段

通常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转换为用户定义的类

将网络服务返回的 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.objectTransformeruser 字段转换为 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 样本响应反序列化推文的示例。

在下一节中,我们将使用自定义运算符来简化此过程。

使用自定义运算符: =~ =? =!

注意,在前面的章节中,我们需要决定类中的字段是否需要分配字符串或整数值。您可以使用以下自定义运算符来简化此操作。它们的定义如下。

  1. =~ 运算符
    如果 JSONObject 实例可以转换为给定的类,则使用转换后的值分配实例对象。如果 JSONObject 实例不能转换为具有给定类的对象,则运算符不会执行任何操作。使用该运算符将 JSONOjbect 实例转换为任何非可选类型 T。

  2. =? 运算符
    如果 JSONObject 实例可以转换为给定的类,则使用转换后的值分配实例对象。如果 JSONObject 实例不能转换为具有给定类的对象,则将左侧对象赋值为 nil。使用此运算符将 JSONObject 实例转换为任何可选类型 T?

  3. =! 运算符
    如果 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 许可证 许可。