Swift - 函数不会等待结果

时间:2015-02-26 15:20:15

标签: ios xcode swift

我一直试图从服务器调用中获取信息。哪个已经正常工作,但是当我想使用这些信息来显示对话框时,它确实不起作用。它太快到下一行了。我能使其工作的唯一方法是延迟代码中的下一位,但考虑到它是服务器调用,我无法确定它总是需要多长时间。我尝试使用dispatch_sync,但它根本没用。

func logIn(username: String, password: String) -> Void {
    var error: NSError?
    var call = "api/usersession/"
    var login = "username=" + username + "&password=" + password
    API().getLogin(login, api:call, { (data) -> Void in

        let json = JSON(data: data, error: &error)
        println(json.self)
        let status = json["status"].stringValue!
        if (status == "1") {
            alertController = UIAlertController(title: "Something went wrong", message: json["result"].stringValue, preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
        } else {
            alertController = UIAlertController(title: "Welcome!", message: "You're signed in", preferredStyle: UIAlertControllerStyle.Alert)
        }
    })
}

我相信每当代码进入" getLogin"部分它只是立即返回它所拥有的东西(这总是没有)。当我说self.presentViewController需要延迟一定数量然后它确实有效时,这会让应用感觉有点笨拙。

编辑:

 func getLogin(login: String, api: String, success: ((apiData: NSData!) -> Void)) {
    var request = NSMutableURLRequest(URL: NSURL(string: website + api)!)
    var learn = API()
    var postString = login
    request.HTTPMethod = "POST"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    learn.httpRequest(request, callback:{(data, error) -> Void in
        if let urlData = data {
            success(apiData: urlData)
        }
    })
}

和httpRequest:

func httpRequest(request: NSURLRequest!, callback: (NSData?,
    String?) -> Void) {
        var configuration =
        NSURLSessionConfiguration.defaultSessionConfiguration()
        var userPassWordString = apiusername + ":" + apipassword
        let userPasswordData = userPassWordString.dataUsingEncoding(NSUTF8StringEncoding)
        let base64EncodedCrendtial = userPasswordData!.base64EncodedStringWithOptions(nil)
        let authString = "Basic \(base64EncodedCrendtial)"
        configuration.HTTPAdditionalHeaders = ["Authorization": authString]
        var session = NSURLSession(configuration: configuration,
            delegate: self,
            delegateQueue:NSOperationQueue.mainQueue())
        var task = session.dataTaskWithRequest(request){
            (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
            if error != nil {
                callback(nil, error.localizedDescription)
            } else {
                var result = NSData(data: data)
                callback(result, nil)
            }
        }
        task.resume()
}

2 个答案:

答案 0 :(得分:3)

  

下一行太快了。

您需要考虑异步操作。当您执行需要花费时间的事情时,无论是向服务器发出网络请求还是要求用户提供某些信息,您不仅要进行函数调用并期望结果立即显示。相反,您调用一个启动该过程的函数或方法,然后在该过程完成之前继续执行其他操作。对于网络请求,这通常意味着您提供委托对象或在连接具有新信息时调用的完成块。在与用户打交道时,您可能会设置一个对话框并将其保留在该对话框中 - 当用户通过点击某个按钮或填写某个字段来触发操作时,该过程将继续。

答案 1 :(得分:1)

我设法通过使UIAlertController从函数本身出现来解决它:

if (status == "1") {
            alertController = UIAlertController(title: "Er ging iets fout", message: json["result"].stringValue, preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
            UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController,animated: true, completion:nil)
        } else {
            alertController = UIAlertController(title: "Welcome!", message: "You're signed in!", preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
            UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController,animated: true, completion:nil)
        }