从远程加载后在segue上传递数据

时间:2015-02-24 00:42:28

标签: ios swift segue viewcontroller

我有这个代码的控制器:

var adItem: JSON!
var item: JSON? {
    didSet {
        self.loadAdData()
    }
}

func loadAdData() {
    let url = "\(Config.apiAdsUrl)\(item!)/"
    Alamofire.request(.GET, url).responseJSON { (request, response, json, error) in
        if (json != nil) {
            var jsonObj = JSON(json!)
            self.adItem = jsonObj
        }
    }
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "imagesSegue" {
        let infoIC = segue.destinationViewController as AdImagesViewController
        infoIC.adItem = self.adItem // this line pass nil value to controller, but i need to pass that JSON data
    }
}

我想获取数据并将其传递给segue视图控制器。

我无法在AdImagesViewController中获取该adItem,当我打印它时,我总是会得到nil,因为prepareForSegue会在启动时触发,所以loadAdData需要一些时间从远程获取数据..

有没有解决方案?

2 个答案:

答案 0 :(得分:1)

如果你有数据,你想要segue,你可以有一个单独的单例对象来处理fetch。此控制器和您调用的控制器都可以访问该对象。每当JSON更改时,对象都可以通知控制器刷新新数据。

您也可以等到获取数据以调用performSegue,但是如果用户服务质量低或根本没有服务怎么办?但如果这是你想要的,你可以创建一个shouldSegue布尔变量并将其设置为YES。在回调中,检查标志是否设置为YES,如果是,则执行segue。你也可以使用队列。 segue与UI相关并发生在主队列上,而fetch通常放在后台队列上,然后更新UI。也许将获取放在主队列上? : - /

答案 1 :(得分:0)

我正在构建一个登录页面,我遇到了类似的问题,但我找到了一个包含下一个代码的解决方案: 我用performatch_async包装performSegueWithIdentifier来获取主队列,我配置prepareForSegue将数据传递给我在EventsVC文件中创建的变量。

import UIKit
import Alamofire

class ViewController: UIViewController {

    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!

    var login: Int = 0
    var clientId: String = ""
    var email: String = ""
    // I'll send the data in this variable
    var userData = [String : AnyObject]()

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

    }

    @IBAction func loginButton(sender: AnyObject) {

        if emailTextField.text != "" && passwordTextField.text != "" {

            userLogin(emailTextField.text!, userPassword: passwordTextField.text!)

        } else {
            let alert = UIAlertController(title: "Error", message: "Fields are required!", preferredStyle: .Alert)
            let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
            alert.addAction(action)
            self.presentViewController(alert, animated: true){}
        }
    }

    func userLogin(email: String, userPassword: String) {

        let userUrl = "\(URL_BASE)\(URL_KEY)User/login"
        let url = NSURL(string: userUrl)!

        let parameters = [
            "email" : email,
            "password" : userPassword
        ]

        Alamofire.request(.POST, url, parameters: parameters).responseJSON { response in

            if let data = response.result.value as? [String : AnyObject] {
                print("Response JSON: \(data)")

                self.userData = data

                if let isLogin = data["check"] as? Int {
                    self.login = isLogin
                }

                if let client = data["client_id"] as? String {
                    self.clientId = client
                }

                print(self.userData)

                if self.login == 1 {
                    // You need to wrap methods that call UI updates with dispatch_asynch to get the main queue
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        self.performSegueWithIdentifier("segueEventsVC", sender: self.userData)
                    })

                } else {
                    let alert = UIAlertController(title: "Error", message: "Your credentials are invalid!", preferredStyle: .Alert)
                    let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
                    alert.addAction(action)
                    self.presentViewController(alert, animated: true){}
                }
            }
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "segueEventsVC" {
            if let eventsVC = segue.destinationViewController as? EventsVC {
                    eventsVC.userData = self.userData
            }
        }
    }
}