Swift - 函数不等待结果 [英] Swift - Function doesn't wait for results

查看:24
本文介绍了Swift - 函数不等待结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试从服务器调用中获取信息.这已经很好了,但是当我想使用这些信息使对话框出现时,它并没有真正起作用.到下一行的速度太快了.我可以让它工作的唯一方法是延迟代码中的下一位,但考虑到它是一个服务器调用,我无法确定它总是需要多长时间.我尝试使用 dispatch_sync 但它根本不起作用.

I've been trying to get information out of a server call. Which already works fine, but when I want to use the information to make a dialogue box appear it doesn't really work. It goes too fast to the next line. The only way I could make it work is by delaying the next bit in the code but considering it's a server call I can't determine how long it'll always take. I tried using dispatch_sync but it didn't work at all.

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 需要延迟一定量时,它确实可以工作,但这会使应用程序感觉有点笨拙.

I believe that whenever the code gets to the "getLogin" part it just immediately goes on to return whatever it has (which is always nothing). When I say that self.presentViewController needs to delay by an amount then it does work, but this would make the app feel a bit clunky.

 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:

And 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()
}

推荐答案

进入下一行的速度太快了.

It goes too fast to the next line.

您需要考虑异步操作.当您做一些需要时间的事情时,无论是向服务器发出网络请求还是要求用户提供一些信息,您都不能只是进行函数调用并期望立即显示结果.相反,您调用一个函数或方法来启动流程,然后您开始做其他事情,直到流程完成.对于网络请求,这通常意味着您提供一个委托对象或一个完成块,当连接有新信息时会调用该对象或完成块.在与用户打交道时,您可能会创建一个对话框并保持原样——当用户通过点击某个按钮或填写某个字段来触发某个操作时,流程会继续.

You need to think about asynchronous operations. When you do something that's going to take time, whether it's making a network request to a server or asking the user to provide some information, you don't just make a function call and expect the results to show up immediately. Instead, you call a function or method that starts the process, and then you go off and do other things until the process completes. For a network request, that usually means that you provide a delegate object or a completion block that gets called when the connection has new information. When dealing with the user, you might put up a dialog box and leave it at that -- the process continues when the user triggers an action by tapping some button or filling in some field.

这篇关于Swift - 函数不等待结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆