2015-09-03 10 views
6

mam tych dwóch metod w mojej klasie API, aby uzyskać dane z API:Zrozumienie Swift Alamofire completionHandler

func authenticateUser(completionHandler: (responseObject: String?, error: NSError?) ->()) { 
     makeAuthenticateUserCall(completionHandler) 
    } 

    func makeAuthenticateUserCall(completionHandler: (responseObject: String?, error: NSError?) ->()) { 
     Alamofire.request(.GET, loginUrlString) 
      .authenticate(user: "a", password: "b") 
      .responseString { request, response, responseString, responseError in 
       completionHandler(responseObject: responseString as String!, error: responseError) 
     } 
    } 

Następnie w innej klasy używam następujący kod dostępu do danych:

API().authenticateUser{ (responseObject, error) in 
    println(responseObject) 
} 

Kod działa, ale nie rozumiem go całkowicie.

  1. func authenticateUser ma completionHandler parametrów: (responseObject: String ?, błędzie: NSError?) ->(), jest to odniesienie do sposobu completionHandler? czy to jest obiekt? jaki jest cel ->()?
  2. Kiedy wywołuję funkcję authenticateUser, jak faktycznie uzyskać dostęp do odpowiedzi? W żadnym z moich funków api nie ma powrotu, funcname {(parametr, parametr) w ..} wydaje się naprawdę dziwna.
+0

Twoja zmiana sprawia, że ​​kwestia całkowicie niezrozumiałe. –

Odpowiedz

9

completionHandler to parametr zamknięcia. Jako dokumentacja Swift mówi:

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.

Tak, to zamknięcie służy do celu jest dodanie niektórych funkcji własnych, który chcesz dodać do wykonywania swojej funkcji.

W twoim przypadku zadzwonisz pod numer authenticateUser i przekazujesz zamknięcie, które odbiera (responseObject, error) i wykonuje println(responseObject). authenticateUser() odbiera twoje zamknięcie pod parametrem completionHandler, a następnie wywołuje makeAuthenticateUserCall(), przekazując mu zamknięcie completionHandler.

Potem znowu, patrząc na definicji widać func makeAuthenticateUserCall(completionHandler: (responseObject: String?, error: NSError?) ->()) Oznacza to, że jak authenticateUser()makeAuthenticateUserCall() jest funkcją, która odbiera zamknięcie jako parametr, pod nazwą completionHandler. makeAuthenticateUserCall() tworzy żądanie sieciowe za pomocą AlamoFire i ponownie rejestrujesz odpowiedź pod zamknięciem, którą przekazujesz jako parametr metody responseString(). Więc trzeba:

//here you call authenticateUser with a closure that prints responseObject 
API().authenticateUser{ (responseObject, error) in 
    println(responseObject) 
} 

Następnie:

//authenticateUser receives your closure as a parameter 
func authenticateUser(completionHandler: (responseObject: String?, error: NSError?) ->()) { 
    //it passes your closure to makeAuthenticateUserCall 
    makeAuthenticateUserCall(completionHandler) 
} 

//makeAuthenticateUserCall receives your closure 
func makeAuthenticateUserCall(completionHandler: (responseObject: String?, 
error: NSError?) ->()) { 
    Alamofire.request(.GET, loginUrlString) 
     .authenticate(user: "a", password: "b") 
     //here you pass a new closure to the responseString method 
     .responseString { request, response, responseString, responseError in 
      //in this closure body you call your completionHandler closure with the 
      //parameters passed by responseString and your code gets executed 
      //(that in your case just prints the responseObject) 
      completionHandler(responseObject: responseString as String!, error: responseError) 
    } 
} 

Aby uzyskać więcej informacji, zapoznać się z dokumentacją: Swift Closures

+0

Świetna odpowiedź, wielkie dzięki! –

Powiązane problemy