开心果 0.1.2

开心果 0.1.2

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2015年3月
SPM支持 SPM

Alexsander Akers 维护。



开心果 0.1.2

开心果是一个 Swift 通用模型框架。通过利用 透镜 和值转换器,它允许您为任何递归数据结构创建类型安全的适配器,无论是 JSON、YAML 还是 XML。

如果您已经熟悉 Argo,请查看 Pistachiargo

安装

使用方法

让我们从定义一个简单的模型开始

struct Origin {
  var city: String

  init(city: String = "") {
    self.city = city
  }
}
struct Person {
  var name: String
  var origin: Origin

  init(name: String = "", origin: Origin = Origin()) {
    self.name = name
    self.origin = origin
  }
}

透镜基本上是获取器和设置器的组合,提供对模型的视图

struct OriginLenses {
  static let city = Lens(get: { $0.city }, set: { (inout origin: Origin, city) in
    origin.city = city
  })
}
struct PersonLenses {
  static let name = Lens(get: { $0.name }, set: { (inout person: Person, name) in
    person.name = name
  })

  static let origin = Lens(get: { $0.origin }, set: { (inout person: Person, origin) in
    person.origin = origin
  })
}

它们可以用来自访问和修改您的模型

var person = Person(name: "Felix", origin: Origin(city: "Berlin"))
person = set(PersonLenses.name, person, "Robb")
get(PersonLenses.name, person) // == "Robb"

并且您可以用组合、提升、转换等对它们进行操作

let composed = PersonLenses.origin >>> OriginLenses.city
person = set(composed, person, "New York")
get(composed, person) // == "New York"
var persons = [ person ]

let arrayLifted: Lens<[Person], [String]> = lift(composed)
persons = set(arrayLifted, [ person ], [ "San Francisco" ])
get(arrayLifted, persons) // == [ "San Francisco" ]
var result: Result<[Person], NSError> = success(persons)

let resultLifted: Lens<Result<[Person], NSError>, Result<[String], NSError>> = lift(arrayLifted)
result = set(resultLifted, result, success([ "London" ]))
get(resultLifted, result) // == .Success(Box([ "London" ]))
let valueTransformer: ValueTransformer<String, Int> = SocialSecurityNumberValueTransformer

let transformed = transform(PersonLenses.name, valueTransformer)
person = set(transformed, person, 1234567890)
get(PersonLenses.name, person) // == "Felix"

值转换器可以翻转、组合和提升

let flipped = flip(valueTransformer)
flipped.transformedValue(1234567890) // == "Felix"
let composed = flipped >>> UppercaseValueTransformer
flipped.transformedValue(1234567890) // == "FELIX"
let dictionaryLifted = lift([ "Felix": 1234567890 ], 0, "Unknown")
dictionaryLifted.transformedValue("Felix") // == 1234567890
dictionaryLifted.transformedValue("Hans") // == 0
dictionaryLifted.reverseTransformedValue(1234567890) // == "Felix"
dictionaryLifted.reverseTransformedValue(0) // == "Unknown"
let optionalLifted = lift(UppercaseValueTransformer, "")
optionalLifted.transformedValue("Felix") // == "FELIX"
optionalLifted.transformedValue(nil) // == ""
optionalLifted.reverseTransformedValue("FELIX") // == "felix"
optionalLifted.reverseTransformedValue("") // == nil
let arrayLifted = lift(UppercaseValueTransformer)
arrayLifted.transformedValue([ "Felix", "Robb" ]) // == [ "FELIX", "ROBB" ]

通过透镜和值转换器,您可以创建模型的适配器

struct Adapters {
  static let origin = DictionaryAdapter(specification: [
    "city_name": transform(OriginLenses.city, StringToAnyObjectValueTransformers)
  ], dictionaryTansformer: DictionaryToAnyObjectValueTransformers)

  static let person = DictionaryAdapter(specification: [
    "name": transform(PersonLenses.name, StringToAnyObjectValueTransformers),
    "origin": transform(PersonLenses.origin, lift(origin, Origin()))
  ], dictionaryTansformer: DictionaryToAnyObjectValueTransformers)
}

嗯,那是什么?对了,原本的适配器被提升为值转换器。

使用 fix 为递归模型创建适配器

let adapter: DictionaryAdapter<Model, Data, Error> = fix { adapter in
  // use `adapter` to reference the currently created adapter
}

适配器处理对数据的编码和解码

let adapter = Adapters.person

var person = Person(name: "Seb", origin: Origin(city: "Berlin"))
var data = adapter.encode(person)
// == .Success(Box([ "name": "Seb", "origin": [ "city_name": "Berlin" ] ]))

adapter.decode(Person(), from: data.value!)
// == .Success(Box(person))

both encodedecode 返回一个 LlamaKit.Result,它持有编码/解码值或错误。这使您能够优雅地处理编码错误。

帖子

关于

开心果是由 Felix JendruschRobert Böhnke 构建的。柏林问候 :wave: