2015-05-12 2 views
6

Так что я в настоящее время следующие: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 } 

Любая помощь или указатели оценили.

ответ

8

Вам необходимо установить функцию обратного вызова, которая будет вызываться всякий раз, когда вы захотите в своей функции 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 
     } 

    } 
} 

UPDATE

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

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

UPDATE 2

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

UPDATE 3

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

+0

Brilliant спасибо! Есть ли способ связать это вместе, используя обещания, чтобы он не выглядел столь же противным с гнездом? Это может потенциально занять 4-5 уровней в течение второй половины приложения? –

+0

Я обновлю свой ответ, чтобы показать вам другой способ ... –

+0

Знаете ли вы, как оригинальный ответ выглядит в Swift 2? Он работал для меня в swift 1.2, но теперь параметр ошибки кажется удаленным. [Здесь] (http://stackoverflow.com/questions/32277680/alamofire-post-request-with-swift-2) мой вопрос об этом – mattgabor

Смежные вопросы