Pistachiargo
Pistachiargo copied to clipboard
Pistachiargo and Value Transformers
Dear felixjendrusch, thank you very much for Pistachiargo! It would be create to provide a short example in your README how to combine the adapters with transformers. Right now I struggle to find a correct way of doing it.
For example: The server responds a URL as a String but I want to convert it to a NSURL. Below you see a short example. The resource
adapter contains a url
. The server responds the url
as String. I want to save it as NSURL
. Other useful examples would be the conversion of a ISO 8601 Date String to a NSDate object.
Would be great! Thanks and best regards from Munich.
Excerpt of JSONAdapters.swift
static let location = JSONAdapter(specification: [
"id": JSONNumber(LocationLenses.id),
"logos": JSONArray(LocationLenses.logos)(adapter: resource, model: Resource()),
])
static let resource = JSONAdapter(specification: [
"url": JSONString(ResourceLenses.URL),
"width": JSONNumber(ResourceLenses.width),
"height": JSONNumber(ResourceLenses.height)
])
Excerpt of Resource.swift
@objc public class Resource: NSObject {
// TODO: Change URL type to NSURL and implement adapter in JSONAdapters.swift
public var URL: String
public var width: Int
public var height: Int
public init(URL: String = "", width: Int = 0, height: Int = 0) {
self.URL = URL
self.width = width
self.height = height
}
}
struct ResourceLenses {
static let URL = Lens(get: { $0.URL }, set: { (inout resource: Resource, URL) in
resource.URL = URL
})
static let width = Lens(get: { $0.width }, set: { (inout resource: Resource, width) in
resource.width = width
})
static let height = Lens(get: { $0.height }, set: { (inout resource: Resource, height) in
resource.height = height
})
}
Hey @rweindl, I'm really sorry for the late reply! I was actually traveling at the time you opened this issue and must have accidentally marked the notification as read 😶
Regarding your issue, the JSONString
lens transformer function is defined as follows:
public func JSONString<A>(lens: Lens<A, String>) -> Lens<Result<A, NSError>, Result<JSONValue, NSError>> {
return transform(lens, JSONValueTransformers.string)
}
It uses the pre-defined JSONValueTransformers.string
transformer, which is of type:
ValueTransformer<String, JSONValue, NSError>
So, when you call JSONString(ResourceLenses.URL)
, your lens of type Lens<Resource, String>
is:
- transformed into a lens of type
Lens<Result<Resource, NSError>, Result<String, NSError>>
- transformed into a lens of type
Lens<Result<Resource, NSError>, Result<JSONValue, NSError>>
Both transformations are applied by transform
. The second transformation uses the given value transformer (JSONValueTransformers.string
), going from String
to JSONValue
. What's still missing is a value transformer going from NSURL
to String
, which should be something like this (untested, without error handling):
let NSURLValueTransformer = ValueTransformer(transformClosure: { value in
return success(value.absoluteString)
}, reverseTransformClosure: { transformedValue in
return success(NSURL(string: transformedValue)!)
})
Fortunately, value transformers can be composed very easily, so your adapter could be created like this:
let adapter = JSONAdapter(specification: [
"url": transform(ResourceLenses.URL, NSURLValueTransformer >>> JSONValueTransformers.string),
"width": JSONNumber(ResourceLenses.width),
"height": JSONNumber(ResourceLenses.height)
])
I'm close to finally updating everything to Swift 1.2, including value transformers, the generic model framework itself and this particular instance. Thank you very much for your feedback, I will take that into account when updating the readme.
Please let me know if you have any other questions!
Hey felixjendrusch, half a year later I realized your replied on that issue! Thank you very much for your very detailed explanation. I got it running with custom transformers. :+1:
Are you planning to continue working on Pistachiargo? (i.e. Swift 2 Branch) If not I would fork the project and start converting it to Swift 2.
Best regards Robert
Yes, I would really like to continue working on Pistachio and related projects but my time for this is currently very limited 😐 I might start working on Swift 2 updates soon but cannot guarantee that.