Codementor Events

Swift — Write Concise Networking Code with WS☁️

Published Oct 30, 2017Last updated Apr 28, 2018

In this article, we are going to go through step by step, what is required to get User objects from a JSON Api in Swift3, using the ☁️ws library.

What is ws ?

ws is a swift library for writing concise networking code.

ws leverages the power of other libraries to make networking a breeze. Under the hood, it uses the great Alamofire for HTTP Requests, 🎬then for the popular Promise Concept and 🏹Arrow for the simple JSON Parsing.

This architechture is modular on purpose so that every “brick” doe_s_ one thing and does it well.

If you wish to go deeper into the inner-workings of ws , you can checkout :

Let’s get some JSON back, shall we?

Installation

If you want to follow this tutrial on Xcode, make sure to create a new iOS project and install ws as explained here, both Carthage and Cocoapods are supported 😃

Disabling App Transport Security (ATS)

Here we will use the great JSONPlaceholder service to get some JSON users https://jsonplaceholder.typicode.com/users

In order to be able to process requests to this domain, we need to bypass App Transport Security settings in our .plist file like so :

⚠️ B_are in mind that this ATS setting is for testing purpose and not meant to be in a production App 😃_

Crafting our Api

Start by creating a new Swift file named Api.swift, this will encapsulate all of our api specific code:

import ws
import then   // Needed to import Promise Type
import Arrow  // Needed to import JSON Type
let api = Api() // Define global api
struct Api {
    
    // Connect to the base URL
    private let ws = WS("http://jsonplaceholder.typicode.com")
    
    // Declare your route and what you want back, here some JSON
    func getUsers() -> Promise<JSON> {
        return ws.get("/users")
    }
}

And now you can call your api from a view controller like this:

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
      
        api.getUsers().then { json in
            print(json)
        }   
    }
}

Wow that was easy wasn’t it?

Yeah but most of the time, in your apps, you’ll want to use custom Swift models. Alright so now we’re going to see next how we translate the JSON into our nice User.swift model.

Set up Model Parsing

Create a User.swift file and add a username property.

struct User {
    var username = ""
}

Create a User+JSON.swift file and map the JSON key to your model property:

import Arrow

extension User: ArrowParsable {

    mutating func deserialize(_ json: JSON) {
        username <-- json["username"]
    }
}

That’s all that’s needed to describe how to parse a User object for now.

Now modify the previous Api.swift file and make the getUsers() function returns Promise<[User]> instead of JSON.

import ws
import then

let api = Api()

struct Api {
    
    private let ws = WS("http://jsonplaceholder.typicode.com")
    
    func getUsers() -> Promise<[User]> { // We want [User] back!
        return ws.get("/users")
    }
}

Yes! That’s the only thing to change! Now ws will automatically try to parse the response into an array of User objects 🎉!

Let’s use it in our controller then!

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        api.getUsers().then { users in
            for u in users {
                print(u.username)
            }
        }   
    }
}

Bonus — Handle errors

As you know, things don’t always work as we intend and we need to prepare ourselves for the worst. So what if the request fails for instance?

That’s where the power of promises comes in :


api.getUsers().then { users in
  // strongly typed [User] !
}.onError { e in
    print(e) // Handle any networking error that might happen
}.finally {
    print("Whatever happens I'll be executed ")
}

Just chain an .onError block in there and it will be called with the corresponding reason whenever something wrong happens!

Conclusion

With roughly 20 lines of code you have :

  • Connected to a distant JSON Api
  • Got JSON back
  • Parsed JSON into your models
  • A way to handle failures when the worst happens

It’s as concise as it gets I guess 😃

Of course there is much more ws can do : handle params, nested models, POST, PUT, DELETE request, multipart uploads, progress, Loadmore requests… But this is out of the scope of this article.

More goodness ❤️

☁️ws is part of a series of lightweight libraries aiming to make developing iOS Apps a breeze. At freshOS we thrive for simple apis, so go checkout our repos and happy coding 😃


Special thanks to maxkonovalov and Yanickdot for proofreading 😃

If you liked this article press the heart ❤ below that means a lot to us ! 😃

Originally published here

Discover and read more posts from Sacha Durand Saint Omer
get started