Skip to content
Ryan Bush edited this page Apr 24, 2017 · 1 revision

A Service is a modularized object that typically connects to a web interface to get data. This allows the connection to a web endpoint to be completely abstracted and easily changeable. The Interactor will call the Services and handle the responses, whether it is a success or failure.

Continuing with the Login flow example, lets say the Interactor has been told to login with a username and password.

//Interactor.swift
lazy var loginService: LoginService = LoginService()
func login(withUserName username: String, andPassword password: String) {
    loginService.login(withUsername: username, andPassword: password,
        success: { (user: User) in
             self.loggedIn(withUser: user)
        },
        failure: { (error: Error) in
             self.failedLogin(withError: error)
        })
}

//LoginService.swift
func login(withUsername username: String,
           andPassword password: String,
           success completion: (user: User),
           failure: ((error: Error) -> Void)) {
    let parameters: Parameters = [
        "username": username,
        "password": password,
    ]
    let request = Alamofire.request("http://www.myserver.com/login,
                      method: Method.get,
                      parameters: parameters,
                      encoding: JSONEncoding.default)
    request.responseJSON { (response: Response) in
         switch response.result {
             case .Success(let value):
                 let user = User(fromJson: value)
                 completion(user: user)
             case .Failure(let error):
                 failure(error: error)
         }
    }
}

Here, we use Alamofire to handle the HTTP request to our server and login the user with username and password provided. The response is JSON, that is then parsed into a User object by the User entities init from JSON method. It is then returned to the completion handler block.

Similarly, if there was an error (maybe the username or password was incorrect), the failure block is called with the Error that was received.

So, with this implementation, notice that we can easily swap out Alamofire for any other networking API. The Interactor will still call the login service the same way, and receive the User or Error object through the same handler blocks, allowing this implementation to change on the fly without affecting any other part of our application!