Model framework using Argo
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Pistachiargo.xcodeproj
Pistachiargo
PistachiargoTests
Cartfile
Cartfile.private
Cartfile.resolved
LICENSE
README.md

README.md

Pistachiargo

Pistachiargo is a model framework using Argo. It's based on Pistachio.

Installation

Carthage

Carthage is a simple, decentralized dependency manager for Cocoa.

  1. Add Pistachiargo to your Cartfile:
github "felixjendrusch/Pistachiargo" ~> 0.2
  1. Run carthage update to fetch and build Pistachiargo and its dependencies.

  2. Make sure your application's target links against Pistachiargo.framework and copies all relevant frameworks into its application bundle (iOS); or embeds the binaries of all relevant frameworks (Mac).

Usage

Like Pistachio, Pistachiargo leverages lenses and value transformers to create type safe adapters. Let's start by defining a very simple model:

struct Origin {
  var city: String

  init(city: String = "") {
    self.city = city
  }
}
struct Person {
  var name: String
  var age: Int
  var origin: Origin?
  var children: [Person]?

  init(name: String = "", age: Int = 0, origin: Origin? = nil, children: [Person]? = nil) {
    self.name = name
    self.age = age
    self.origin = origin
    self.children = children
  }
}

A lens is basically just a combination of a getter and a setter, providing a view on your model:

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 age = Lens(get: { $0.age }, set: { (inout person: Person, age) in
    person.age = age
  })

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

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

However, Pistachiargo ships with a lot of JSON value transformers, convenience functions and a JSON adapter:

struct JSONAdapters {
  static let origin = JSONAdapter(specification: [
    "city_name": JSONString(OriginLenses.city)
  ], value: Origin())

  static let person = fix { adapter in
    return JSONAdapter(specification: [
      "name": JSONString(PersonLenses.name),
      "age": JSONNumber(PersonLenses.age),
      "origin": JSONObject(PersonLenses.origin)(adapter: origin),
      "children": JSONArray(PersonLenses.children)(adapter: adapter)
    ], value: Person())
  }
}

JSON adapters handle transforming and reverse transforming your models:

let adapter = JSONAdapters.person

var person = Person(name: "Felix", origin: Origin(city: "Berlin"))
var data = adapter.transform(person)
// == .Success(Box(.JSONObject([
//   "name": .JSONString("Felix"),
//   "age": .JSONNumber(0),
//   "origin": .JSONObject([
//     "city_name": .JSONString("Berlin")
//   ]),
//   "children": .JSONNull
// ])))

adapter.reverseTransform(data.value!)
// == .Success(Box(person))

Both transform and reverseTransform return a Result, which either holds the (reverse) transformed value or an error. This enables you to gracefully handle transformation errors.

Posts