我有这个代码的控制器:
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需要一些时间从远程获取数据..
有没有解决方案?
答案 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
}
}
}
}