2

friends!, I am new to Swift. I need to make multiple API requests in one of my view controllers. If I put all the code in ViewController it will be messy. So I am trying to develop this simple architecture to separate the concepts but I'm not sure whether it's the best approach to handle this situation.

/*-----------------------------------------------------*/
/* RestClient.swift */
/*-----------------------------------------------------*/
protocol RestClientDelegate {
    func dataDidLoad(json:String)
}
class RestClient {

    var delegate:RestClientDelegate

    //Handles all the network codes and exceptions
    func makeGetRequest(url){
        //send a get request to the server  
        //on error - handle erros 
        //on success - pass Json response to HttpUser class
        delegate.dataDidLoad(jsonOutput)
    }

}

/*-----------------------------------------------------*/
/* HttpUser.swift */
/*-----------------------------------------------------*/
protocol UserDelegate(){
    func usersDidLoad(usersArray:[User])//User object array
}
class HttpUser, RestClientDelegate {

    var delegate:UserDelegate

    func getUsers(){
        //Use rest client to make an api call
        var client = RestClient()
        client.delegate = self
        client.makeGetRequest("www.example.com/users")
    }

    //Once RestClient get the json string output, it will pass to
    //this function
    func dataDidLoad(json:String){
        //parse json - Handles json exceptions
        //populate user objects in an array
        //pass user array to the ViewController
        delegate.usersDidLoad(usersArray:[User])
    }

}

/*-----------------------------------------------------*/
/* UserViewController.swift */
/*-----------------------------------------------------*/
class UserViewController:UIViewController, UserDelegate {

    override viewDidLoad(){
        super.viewDidLoad()

        //Ask http user class to retrieve users
        var httpUser = HttpUser()
        httpUser.delegate = self
        httpUser.getUsers()
    }

    //Callback function to get users array
    func usersDidLoad(usersArray:[User]) {
        //now you have users object array
        //populate a table view
    }

}
  1. RestClient.swift - Make the API request and pass a json output. This class contains all the code related to network GET/POST requests. I can modify this class in the future without affecting other classes.
  2. HttpUser.swift - Get json output make an Users Array and pass it. This class does not care about network requests. It will just handle the JSON response and parse it into an object array. I will be having multiple of these. (ex: HttpBlogs, HttpComments)
  3. UserViewController.swift - Get Users Array and populate a table view. This will handle only sections related to the UI.

Can you tell me is this approach is good to follow? Is there a much better way to achieve this?

Thanks a lot everyone!

-Please note: I don't want to use 3rd party libraries like Alamofire in this case.

stackflow
  • 2,112
  • 6
  • 32
  • 45
  • 1
    I'm quite new to iOS development but to my opinion your approach is very good. Actually I came up with the same approach when developing my first project and since then rather satisfied using it everywhere. A bit of advice - declare your delegate variables as weak variables. – Elena Jul 21 '16 at 09:53
  • Thanks! I tried this code in my App today. it seems pretty clean. :P – stackflow Jul 21 '16 at 13:50
  • I usually follow this kind of architecture. https://stackoverflow.com/a/50868373/3656515 – vinodonkar Jun 20 '18 at 00:22

1 Answers1

1

In general, this is a good approach. You may want to think about displaying errors (ex: no internet connection) on the user interface for better user experience. In your example, you are handling your errors in RestClient class, but in case of any error, it is not upstreamed to UserViewController class to handle on the user interface.

R. Mohan
  • 2,182
  • 17
  • 30