Swish 1.0, our Swift networking library, is out! Swish came to life through working on many client projects and writing more or less the same networking stack over and over. Our goals with Swish are:

Be able to test our networking layer.

Keep the networking layer self contained.

By default, decode JSON into domain objects via Argo.

If we want to do something different than decoding JSON, it should be as painless as possible.

And so Swish was born!

Our 90% use case is that we get JSON from an endpoint, and we want to decode it into a struct via Argo. Swish makes that easy. Let’s say you have an endpoint, GET https://www.example.com/comments/1 , that returns the following JSON:

{ "id" : 1 , "commentText" : "Pretty good. Pret-ty pre-ty pre-ty good." , "username" : "LarryDavid" }

We’ll model this with the following struct, and implement Argo’s Decodable protocol to tell it how to deal with JSON:

import Argo import Curry struct Comment : Decodable { let id : Int let text : String let username : String static func decode ( json : JSON ) -> Decoded < Comment > { return curry ( Comment . init ) <^> j <| "id" <*> j <| "commentText" <*> j <| "username" } }

(n.b. if you’re not familiar with the Curry library, check this blog post out)

We can model the request by defining a struct that implements Swish’s Request protocol:

struct CommentRequest : Request { typealias ResponseObject = Comment let id : Int func build () -> NSURLRequest { let url = NSURL ( string : "https://www.example.com/comments/ \( id ) " ) ! return NSURLRequest ( URL : url ) } }

We can then use Swish’s default APIClient to make the request:

let request = CommentRequest ( id : 1 ) let dataTask = APIClient () . performRequest ( request ) { ( response : Result < Comment , SwishError > ) in switch response { case let . Success ( value ): print ( "Here's the comment: \( value ) " ) case let . Failure ( error ): print ( "Oh no, an error: \( error ) " ) } }

And that’s it!

Swish’s defaults make decoding via Argo seamless, but if you want to customize, provide a different implementation for any of the following protocols:

RequestPerformer allows you to define how the NSURLRequest should be carried out

allows you to define how the should be carried out Deserializer allows you to process the NSData from the response however you wish

allows you to process the from the response however you wish Parser allows to you convert the result of your deserialization into a Representation (e.g. JSON , by default)

allows to you convert the result of your deserialization into a (e.g. , by default) Client allows you to define how the objects implementing the above protocols are linked together.

Checkout the Swish repository for more!