2015-05-12 23 views
6

więc obecnie mam następujące:Swift Alamofire SwiftyJSON Asynchronous/Synchroniczne klasę

class ViewController: UIViewController { 

class Identity{ 
    let baseUrl = "superSecretURL" 
    var _username: String = "" 
    var _password: String = "" 
    var _apiKey: String = "" 

    init(){ 

    } 

    init(username: String, apiKey: String){ 
     _username = username 
     _apiKey = apiKey 
    } 

    init(username: String, password: String){ 
     _username = username 
     _password = password 
    } 

    func loginPassword() -> String{ 
     var loginJSON = ["auth": ["passwordCredentials": ["username": _username, "password": _password]]]; 
     var returnJSON: String 

     request(.POST, baseUrl, parameters: loginJSON, encoding: .JSON) 
      .responseJSON { (request, response, data, error) in 
       if let anError = error 
       { 
        // got an error in getting the data, need to handle it 
        println("error calling POST on /posts") 
        println(error) 
       } 
       else if let data: AnyObject = data 
       { 
        // handle the results as JSON, without a bunch of nested if loops 
        let post = JSON(data) 
        // to make sure it posted, print the results 
        println("JSON Returned") 
       } 
     } 
    } 
} 

var i = Identity(username: "secretName", password: "complicatedPassword") 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    println("Before Call") 



    println("After Call") 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 


} 

Zasadniczo chciałbym być w stanie wywołać println („Przed Call”), a następnie otrzymać odpowiedź od loginPassword (), a następnie println ("After Call"). Uważam, że jest to synchroniczne, ale nie potrafię znaleźć sposobu, żeby to zadziałało, a cała sprawa z wątkami zbiła mnie z tropu.

Zasadniczo chcę móc powiedzieć:

if i.loginPassword(){ // do some login stuff }else{ // do some error stuff } 

Każda pomoc lub wskazówki mile widziane.

Odpowiedz

8

Należy ustawić funkcję wywołania zwrotnego, która będzie wywoływana w dowolnym momencie wewnątrz funkcji loginPassword().

To może być sposobem osiągnięcia go:

func loginPassword(callback: ((isOk: Bool)->Void)?) -> String{ 
var loginJSON = ["auth": ["passwordCredentials": ["username": _username, "password": _password]]]; 
var returnJSON: String 

request(.POST, baseUrl, parameters: loginJSON, encoding: .JSON) 
    .responseJSON { (request, response, data, error) in 
     if let anError = error{ 
     // got an error in getting the data, need to handle it 
     println("error calling POST on /posts") 
     println(error) 

     callback?(isOk: false) 
     } 
     else if let data: AnyObject = data{ 
     // handle the results as JSON, without a bunch of nested if loops 
     let post = JSON(data) 
     // to make sure it posted, print the results 
     println("JSON Returned") 

     callback?(isOk: true) 
     } 
    } 
} 

a potem ...

override func viewDidLoad() { 
    super.viewDidLoad() 

    var identity = Identity(username: "John Apleseed", apiKey: "213123123") 

    identity.loginPassword { (isOK) -> Void in 
     if (isOK) { 
      //do good stuff here 
     }else{ 
      // do error handling here 
     } 

    } 
} 

UPDATE

Również czynność wywołująca może wyglądać następująco:

override func viewDidLoad() { 
    super.viewDidLoad() 

    var identity = Identity(username: "John Apleseed", apiKey: "213123123") 
    identity.loginPassword(handlePasswordRequest) 
} 

i można dodać dowolną liczbę procedur obsługi wywołań zwrotnych, ponieważ może trzeba bez aprowizacji z bandą zagnieżdżonych zamknięć ...

private func handlePasswordRequest(isOK: Bool){ 
    if (isOK) { 
     //do good stuff here 
    }else{ 
     // do error handling here 
    } 
} 

UPDATE 2

Jeśli jesteś w potrzebie, aby nazwać zwrotnego w głąb hierarchii połączeń, wtedy będziesz musiał przekazać wywołanie zwrotne jako parametr każdego poprzedniego zamknięcia.

UPDATE 3

dałbym spróbować RxAlamofire i wszystko o RxSwift

+0

Brilliant dzięki! Czy istnieje sposób na połączenie tego łańcucha za pomocą obietnic, aby nie wyglądało to tak nieprzyjemnie z zagnieżdżaniem? To może potencjalnie uzyskać 4-5 poziomów głębokości w drugiej połowie aplikacji? –

+0

Zaktualizuję moją odpowiedź, aby pokazać Wam inny sposób ... –

+0

Czy wiesz, jak oryginalna odpowiedź wygląda w Swift 2? Udało mi się to w wersji 1.2, ale teraz wydaje się, że parametr błędu został usunięty. [Tutaj] (http://stackoverflow.com/questions/32277680/alamofire-post-request-with-swift-2) to moje pytanie na temat tego – mattgabor