等到快速获得PHP的响应

时间:2017-10-24 14:02:22

标签: swift

我有这段代码:

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.title = "Tavolo n° " + UserDefaults.standard.string(forKey: "number")!
    self.navigationController?.isNavigationBarHidden = false
    navigationController?.navigationBar.barTintColor =  UIColor(red: 0.30, green: 0.69, blue: 0.31 , alpha: 1.0)
    navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white]
    navigationController?.navigationBar.tintColor = UIColor.white;
    pickerView.delegate = self
    pickerView.dataSource = self
    name.delegate = self

    let myUrl = NSURL(string: "http://192.168.1.116/myorder/data/fetch_name.php");
    let request = NSMutableURLRequest(url: myUrl! as URL);
    request.httpMethod = "POST";
    let postString = "number=\(UserDefaults.standard.integer(forKey: "number"))";
    request.httpBody = postString.data(using: String.Encoding.utf8);
    let task = URLSession.shared.dataTask(with: request as URLRequest){
        data, response, error in
        if error != nil{
            print("error=\(String(describing: error))")
            return
        }

        var _: NSError?

        do{

            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray

            if let parseJSON: NSArray = json {

                for index in 0...parseJSON.count-1 {
                    if (parseJSON[index] is NSNull){
                            let myAlert = UIAlertController(title: "Attenzione\n", message: "Nessun nominativo per questo tavolo", preferredStyle: UIAlertControllerStyle.alert);

                            let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ action in }

                            myAlert.addAction(okAction);
                            self.present(myAlert, animated: true, completion: nil);
                    }else{
                        let nomi = parseJSON[index] as! [String:Any]
                        ViewController.listNames.append(nomi["name"] as! String)
                    }
                }

            }
        }catch{
            print("error=\(error)")
            return
        }
    }
    task.resume();
    print(ViewController.listNames)
    selectedName = ViewController.listNames[0]

    NotificationCenter.default.addObserver(self, selector: #selector(NamesVC.keyboardWillShow(sender:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(NamesVC.keyboardWillHide(sender:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

有时候,在打印ViewController.listNames的第一个元素之前,响应会返回,但有时候并不会打印任何内容。 我怎么能等到响应返回?我在stackOverflow上尝试过其他答案,但我不能这样做

1 个答案:

答案 0 :(得分:1)

发生这种情况是因为当您resume任务时,它会通过互联网上传并获取数据,这可能需要一些时间。因此,resume立即完成,而不是等到网络连接完成。您的print位于下一行。有时网络连接会很快,并且会在到达print之前完成。其他时候它不会那么快,print首先发生。这是一个竞争条件的典型例子 - 两件事彼此分开,并且不可预测哪一件将首先完成。

所有这一切都是为什么任务有一个完成块 - 这是以if error != nil{开头的闭包。在任务完成之前,该闭包内的代码不会发生。

您应该将print语句放在该闭包中,以便在发生之前确保网络连接已完成。