使用少量 getter 风格的选项,懒惰地将 JSON 反序列化为强类型 Swift 对象。
您的应用程序正在使用它吗?告诉我!
使用 CocoaPods 快速安装
pod 'LazyObject'
或手动安装
让我们看一下一个示例模型来展示一些功能
class Bank: LazyObject {
var money: Double { return try! objectFor(#function) } // Automagically converts #function to a "money" string
var getPaid: Bool? { return try? objectFor("get_paid") } // Will be nil if called and key/value don't exist
var security: [Person]? { return try? objectFor(#function) } // Works with arrays of other LazyObjects as well
var debt: Double { return try! objectFor("accounting.books.cooked") } // Nested key paths are supported
}
模型从 JSON 字典实例化
// The dictionary passed here is the JSON response
let bank = Bank(dictionary: ["money": 9999, "get_paid": true])
还有一个方便的扩展,可以从 JSON 数组中实例化
let banks = Bank.fromArray(jsonArrayOfDictionaries)
由于许多服务有不同的日期格式,LazyObject 提供了一种简单的方法来指定您希望遵守的哪个标准或自定义格式。
class Retirement: LazyObject, ISO8601Formattable {
var date: NSDate? { return try? dateFor(#function) }
}
注意:对于日期,您必须明确使用 dateFor()
方法,这样它将从缓存中选择正确的格式化程序。
您的任何基类或子类都可以符合支持的协议之一
或者,您可以根据需要扩展 LazyDateFormattable
来创建自定义日期转换(请参阅如何实现上述协议的示例)。
上述所有格式化程序都只创建一次并缓存以供重用,并建议您在创建自定义格式化程序时也这样做,因为它们通常创建成本很高。
“objectFor”方法支持几个关键名称变体
#function
:将属性名称转换为字符串(例如,var help
转换为 "help"
)。请注意,类似于 myProperty
的属性名称将转换为 "myProperty"
,而不是 my_property
,因此如果您需要,可以自由扩展 LazyObject。keyPath
:可以是一个包含单个键的字符串,例如 first_name
,或者是一个指向嵌套值的键路径,例如 location.latitude
请注意,在示例中,您可以使用 try?
来确保属性的可用性安全。如果您很有信心,可以使用 try!
来强制转换,但如果它未能成功,您可能会遇到一些运行时错误。
除了标准的 JSON 数据类型,以下类型也得到无缝支持
如果您想无缝转换自定义值,例如从字符串值创建一个 NSNumber
,您可以创建自己的 LazyConvertible
扩展,如下所示
// Note: this example is actually already part of the library, so no need to extend NSNumber
import Foundation
extension NSNumber: LazyConvertible {
public static func convert(value: AnyObject?) throws -> NSNumber {
guard let string = value as? String else {
throw LazyMappingError.UnexpectedTypeError(value: value, type: String.self)
}
let formatter = NSNumberFormatter()
guard let number = formatter.numberFromString(string) else {
throw LazyMappingError.CustomError(message: "'\(string)' is not a valid input for NSNumber instantiation")
}
return number
}
}
这将允许您通过使用正常的 objectFor
方法无缝支持任何类型的有效 NSNumber
,无论它是从字符串还是从数字值转换而来。
LazyObject 主要关注只读模型,但在必要时您仍然可以轻松地在模型上公开设置器。
class Object: LazyObject {
var id: NSNumber? {
get {
return try? objectFor(#function)
}
set {
setObject(newValue, setter: #function)
}
}
}
注意:与获取方法类似,设置器 #function
可以使用,或者可以使用 keyPath
来引用要更新的键名。
Swift,ARC 和 iOS 9+
请随时进行分支操作并创建修补程序或改进功能的拉取请求,同时确保保持通用的编码风格,增加测试,并在必要时添加注释。
这个库受到了 CottonObject 和 Mapper 的启发。