Swift Alamofire SwiftyJSON Асинхронные / Синхронные Методы Класса

Итак, в настоящее время у меня есть следующее:

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.
}


}

По сути, я хотел бы иметь возможность вызвать println("Перед вызовом"), затем получить ответ от метода loginPassword() и затем println("После вызова"). Я считаю, что это синхронно, но я не могу найти способ заставить его работать, и вся эта нить сбила меня с толку.

Я в основном хочу иметь возможность сказать:

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

Любая помощь или указатели приветствуются.

1 ответ

Решение

Вам нужно установить функцию обратного вызова, которая будет вызываться всякий раз, когда вы хотите внутри loginPassword() функция.

Это может быть способом достижения этого:

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)
      }
    }
}

а потом...

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
        }

    }
}

ОБНОВИТЬ

Кроме того, ваша вызывающая функция может выглядеть так:

override func viewDidLoad() {
    super.viewDidLoad()

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

и вы можете добавить столько обработчиков обратного вызова, сколько вам нужно, не возиться с кучей вложенных замыканий...

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

ОБНОВЛЕНИЕ 2

Если вам нужно вызвать обратный вызов глубоко в иерархии вызовов, то вам нужно будет передать обратный вызов в качестве параметра каждого предыдущего замыкания.

ОБНОВЛЕНИЕ 3

Я хотел бы попробовать RxAlamofire и все о RxSwift

Другие вопросы по тегам