测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | Apache 2 |
发布最后发布 | 2018 年 4 月 |
SPM支持 SPM | ✓ |
由 Emilien Stremsdoerfer 维护。
StreemMapper 是一个简单的 Swift 库,可以将 JSON 转换为强类型对象。
StreemMapper最初是从非常棒的mapper库分叉而来。
import StreemMapper
// Conform to the Mappable protocol
struct User: Mappable {
let id: String
let photoURL: NSURL?
// Implement this initializer
init(map: Mapper) throws {
try id = map |> "id"
photoURL = map |> "avatar_url"
}
}
// Create a user!
let json:Any = ...
let user = User.from(JSON:json) // This is a 'User?'
enum UserType: String {
case Normal = "normal"
case Admin = "admin"
}
struct User: Mappable {
let id: String
let type: UserType
init(map: Mapper) throws {
try id = map |> "id"
try type = map |> "user_type"
}
}
Mappable
对象struct User: Mappable {
let id: String
let name: String
init(map: Mapper) throws {
try id = map |> "id"
try name = map |> "name"
}
}
struct Group: Mappable {
let id: String
let users: [User]
init(map: Mapper) throws {
try id = map |> "id"
users = map |> "users" ?? []
}
}
Convertible
将其他类型透明地从 JSON 转换extension CLLocationCoordinate2D: Convertible {
static func from(value: Any?) throws -> CLLocationCoordinate2D {
guard let location = value as? NSDictionary,
let latitude = location["lat"] as? Double,
let longitude = location["lng"] as? Double else
{
throw MapperError.ConvertibleError(value: value, type: [String: Double].self)
}
return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
struct Place: Mappable {
let name: String
let location: CLLocationCoordinate2D
init(map: Mapper) throws {
try name = map |> "name"
try location = map |> "location"
}
}
let JSON = [
"name": "Lyft HQ",
"location": [
"lat": 37.7603392,
"lng": -122.41267249999999,
],
]
let place = Place.from(JSON:json)
private func extractFirstName(object: Any?) throws -> String {
guard let fullName = object as? String else {
throw MapperError.ConvertibleError(value: object, type: String.self)
}
let parts = fullName.characters.split { $0 == " " }.map(String.init)
if let firstName = parts.first {
return firstName
}
throw MapperError.CustomError(field: nil, message: "Couldn't split the string!")
}
struct User: Mappable {
let firstName: String
init(map: Mapper) throws {
try firstName = map.from(field:"name", transformation: extractFirstName)
}
}
struct User: Mappable {
let name: String
let JSON: Any
init(map: Mapper) throws {
// Access the 'first' key nested in a 'name' dictionary
try name = map |> "name.first"
// Access the original JSON (maybe for use with a transformation)
try JSON = map |> ""
}
}
请参阅文档字符串和测试以获取更多信息和使用示例。
此分支对原始项目进行了少量修改。
此分支包含一个自定义操作符,允许您以非常清洁的方式解析 Mapper 对象。
import Mapper
// Conform to the Mappable protocol
struct User: Mappable {
let id: String
let photoURL: NSURL?
// Implement this initializer
init(map: Mapper) throws {
try id = map |> "id"
photoURL = map |> "avatar_url"
}
}
现在此分支支持了许多可转换类型,以下是所有支持类型的列表,加粗的是新增类型。
出于一致性原因,现在数组的初始化就像初始化对象一样。
let users = [User].from(JSON:json) // Returns a [User]?
还当解析数组时,原始库不允许在 JSON 数组中有不规则的对象。它会直接返回 nil。此分支允许创建一个数组,并将忽略不规则的对象。
struct User: Mappable {
let name: String
init(map: Mapper) throws {
try self.name = map |> "name"
}
}
let JSON = [["name": "John"], ["firstname": "Bob"]]
let users = [User].from(JSON:JSON) // Returns 1 User object with name John
如果在 JSON 数组中无法解析任何对象,则此会返回空数组。如果 JSON 不是一个数组,则返回 nil。
使用 StreemMapper,您现在还可以解析带有给定根键的数组。例如,如果您有如下 JSON:
{
"data" : [
{"id":1, "name":"Alice"},
{"id":2, "name":"Bob"},
{"id":3, "name":"Carol"}
]
}
您可以直接解析数组,而无需添加包装对象。
struct User: Mappable {
let id: Int
let name: String
init(map: Mapper) throws {
try id = map |> "id"
try name = map |> "name"
}
}
let json = ["data":[["id":1, "name":"Alice"],["id":2, "name":"Bob"],["id":3, "name":"Carol"]]]
let users = [User].from(JSON:json, rootKey: "data")
最后,此分支允许您解析可选的枚举数组,这在您不确定收到的 JSON 时特别有用,您宁愿返回 nil 或空数组而不是抛出异常。
enum DaysOfWeek {
case Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
struct User: Mappable {
let name: String
let availableDays: [DaysOfWeek]?
init(map: Mapper) throws {
try self.name = map |> "name"
availableDays = map |> "available_days" //returns nil if key is not there
}
}
日期现在可以使用格式化程序或时间戳来解析
struct User: Mappable {
let date1: Date
let date2: Date?
init(map: Mapper) throws {
try date1 = map |> ("date1", "MMMM dd, yyyy h:mm:ss a zzz") // will try to parse as a string with the given format
date2 = map |> "date2" //will try to parse it as a timestamp
}
}
在创建对象时,无需再将初始对象解析为字典或数组。库将处理它,并将返回 nil 如果传递了一个数组而不是字典,反之亦然。
例如
let json:Any = ...
let user = User.from(JSON:json) // Returns nil if JSON is not dictionary
let users = [User].from(JSON:json) // Returns nil if JSON is not an array
此外,由于可选类型上的类型推断,方法optionalFrom和from已被合并为单个方法from。
这些雷达影响了Mapper当前的实现
??
运算符是不可持续的。Self
的非最终类不起作用StreemMapper由Emilien Stremsdoerfer维护,并按照Apache 2.0许可证发布。详情请见LICENSE。
由以下项目提供赞助: