iosswifthttpdesign-patternsapi-design

Design Pattern HTTP API


I'm building an app that is based on data provided by an REST API. I use the Alamofire framework to request the data from the API. At the moment everything works but it's kind a messed up in a lot of ways, so I want to structure it and use some design patterns to have more control over my code.

I created some entity classes that are basically my data layer. The data layer should be up to date every time I use these objects. Data updates / API connections could be triggered by time intervals or by user action (if he edits some data and saves it or something like this).

After that my UI should always update if data has changed and if that viewcontroller is active.

The problem is that the request and the receiving of data is asynchronous and I don't know a good way to structure everything.

At the moment the request to the api is always triggered by the viewcontroller. After data is received I call some methods in the viewcontroller itself via delegation and update the UI. It's kind a messy with all the different requests and different data that is send to API. I need to generalise everything and clean it up. And one of the problems at the moment is, that one viewcontroller can only handle one kind of request. For example, the viewcontroller can only save an edited post, but can not receive a post, because the same method would be called after receiving data.

So, does anyone know how it is done correctly and in a very structured way? Maybe some ideas or designpatterns or how one of the big players handle such problems.


Solution

  • Delegation is certainly a design pattern you can use, but I agree it gets messy when your API is growing and you start introducing new delegate methods for every single API call.

    Closures

    I guess the preferred way to implement asynchronous callbacks is using closures. In your ViewController you simply pass a closure to the request method:

    requestHandler.sendSomeRequest(param1, parameter2: param2, completion: { (response) -> Void in
    
        // This is executed asynchronously, but you can still access all properties of your ViewController
        // Just make sure you're on the main thread when you need to update your UI
    }
    

    The definition of the RequestHandler's method would be something like this:

    func sendSomeRequest( parameter1: String, parameter2: String, completion: ( response: String)->Void ) {
    
        // Send the request, and pass/store the "completion" closure until you get the response back.
        // Then, just call:
        completion( response )
    
    }
    

    See also The Swift Programming Language: Closures.

    Notifications

    This applies more to OS X than to iOS, but especially in situations where more than one ViewController is interested in the response you could also start sending NSNotifications around. However, doing so will have a similar "bad smell" like the delegate method, because you'll start inventing new notifications for every API response, so I wouldn't recommend that approach.