StreemMapper 7.2.0

StreemMapper 7.2.0

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

Emilien Stremsdoerfer 维护。



  • Keith Smiley 和 Emilien Stremsdoerfer

StreemMapper

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"
  }
}

默认可转换类型

现在此分支支持了许多可转换类型,以下是所有支持类型的列表,加粗的是新增类型。

  • String
  • Int
  • UInt
  • Int8
  • UInt8
  • Int16
  • UInt16
  • Int32
  • UInt32
  • Int64
  • UInt64
  • Float
  • Double
  • Bool
  • NSNumber
  • NSDictionary
  • NSArray
  • NSURL
  • NSDate 从时间戳中

数组

初始化

出于一致性原因,现在数组的初始化就像初始化对象一样。

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

此外,由于可选类型上的类型推断,方法optionalFromfrom已被合并为单个方法from

开启雷达

这些雷达影响了Mapper当前的实现

许可证

StreemMapper由Emilien Stremsdoerfer维护,并按照Apache 2.0许可证发布。详情请见LICENSE。
由以下项目提供赞助: