Kaidao
Kaidao

Reputation: 125

How to wait for variable in Swift before executing function?

I'm using Alamofire to connect with an API, getting a JSON object back, assigning that to a variable, and then trying to display it. The problem is that the variable is coming up as empty because it's trying to display before it's getting the value back from the server.

Here's my Networking.swift file:

class Networking {

class func postPurchase() {

    let parameters = [
        "login_user": "[email protected]",
        "login_password": "p0q3t4",
        "item_id": 5,
        "machine_token": "/HyZyq2FgU4RONnDlzPXWA==",
        "amount": 1
    ]

    Alamofire.request(.POST, "http://poqeta.herokuapp.com/api/v1/purchases/add_item", parameters: parameters, encoding: .JSON)
        .responseData { response in
            print(response.request)
            print(response.response)
            print(response.result)
    }
}

class func confirmPurchase() -> String {
    var token:String = " "

    Alamofire.request(.POST, "http://poqeta.herokuapp.com/api/v1/purchases/purchase", parameters: ["login_user": "[email protected]", "login_password": "p0q3t4"])
        .responseJSON { response in
            switch response.result {
            case .Success(let data):
                let json = JSON(data)
                let dispenseToken:String = json["token"].stringValue
                print(dispenseToken)
                token = dispenseToken
            case .Failure(let error):
                print("Request failed with error: \(error)")
                return
            }
    }
    return token
}

And here's the function trying to get the variable and display it (using PopUpViewControllerSwift):

    @IBAction func showPopUp(sender: AnyObject) {

    var purchase_token:String = " "

    Networking.postPurchase()
    purchase_token = Networking.confirmPurchase()

    let bundle = NSBundle(forClass: PopUpViewControllerSwift.self)
    if (UIDevice.currentDevice().userInterfaceIdiom == .Pad)
    {
        self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController_iPad", bundle: bundle)
        self.popViewController.title = "Purchase Complete"
        self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
    } else
    {
        if UIScreen.mainScreen().bounds.size.width > 320 {
            if UIScreen.mainScreen().scale == 3 {
                self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController_iPhone6Plus", bundle: bundle)
                self.popViewController.title = "Purchase Complete"
                self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
            } else {
                self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController_iPhone6", bundle: bundle)
                self.popViewController.title = "Purchase Complete"
                self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
            }
        } else {
            self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController", bundle: bundle)
            self.popViewController.title = "Purchase Complete"
            self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
        }
    }
}

Thanks in advance for any suggestions!

Upvotes: 0

Views: 1342

Answers (1)

Nguyen Hoan
Nguyen Hoan

Reputation: 1693

postPurchase & confirmPurchase is acsync function, don't use return. Try:

    class func postPurchase(handleComplete:((isOK:Bool)->())) {

    let parameters = [
        "login_user": "[email protected]",
        "login_password": "p0q3t4",
        "item_id": 5,
        "machine_token": "/HyZyq2FgU4RONnDlzPXWA==",
        "amount": 1
    ]



     Alamofire.request(.POST, "http://poqeta.herokuapp.com/api/v1/purchases/add_item", parameters: parameters, encoding: .JSON)
            .responseData { response in
                print(response.request)
                print(response.response)
                print(response.result)
                // check request success or failse
//                if  success
                handleComplete(isOK: true)
//                else
//                handleComplete(isOK: false)
        }
    }

class func confirmPurchase(handleComplete:((token:String?)->())){
    var token:String = " "

    Alamofire.request(.POST, "http://poqeta.herokuapp.com/api/v1/purchases/purchase", parameters: ["login_user": "[email protected]", "login_password": "p0q3t4"])
        .responseJSON { response in
            switch response.result {
            case .Success(let data):
                let json = JSON(data)
                let dispenseToken:String = json["token"].stringValue
                print(dispenseToken)
                token = dispenseToken
                handleComplete(token: token)
            case .Failure(let error):
                print("Request failed with error: \(error)")
                handleComplete(token: nil)
            }
    }
}

and use it:

 @IBAction func showPopUp(sender: AnyObject) {

    var purchase_token:String = " "

    Networking.postPurchase { (isOK) in
        if isOK{
            Networking.confirmPurchase({ (token) in
                if let tok = token{
                    purchase_token = tok

                    let bundle = NSBundle(forClass: PopUpViewControllerSwift.self)
                    if (UIDevice.currentDevice().userInterfaceIdiom == .Pad)
                    {
                        self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController_iPad", bundle: bundle)
                        self.popViewController.title = "Purchase Complete"
                        self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
                    } else
                    {
                        if UIScreen.mainScreen().bounds.size.width > 320 {
                            if UIScreen.mainScreen().scale == 3 {
                                self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController_iPhone6Plus", bundle: bundle)
                                self.popViewController.title = "Purchase Complete"
                                self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
                            } else {
                                self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController_iPhone6", bundle: bundle)
                                self.popViewController.title = "Purchase Complete"
                                self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
                            }
                        } else {
                            self.popViewController = PopUpViewControllerSwift(nibName: "PopUpViewController", bundle: bundle)
                            self.popViewController.title = "Purchase Complete"
                            self.popViewController.showInView(self.view, withImage: nil, withMessage: "Your purchase token is " + purchase_token, animated: true)
                        }
                    }

                }else{
                    // false --> do st
                }
            })
        } else{
            // do st
        }
    }

}

Upvotes: 2

Related Questions