在 NSURLConnection 中从 Swift 中的completionHandler 中获取数据

2024-01-02

我正在尝试编写一个函数来执行异步 GET 请求,并返回响应(作为任何数据类型,但这里是 NSData)。

这个问题是基于:如何快速使用 NSURLConnectioncompletionHandler https://stackoverflow.com/questions/24016714/how-to-use-nsurlconnection-completionhandler-with-swift

func getAsynchData() -> NSData {
    var dataOutput : NSData
    let url:NSURL = NSURL(string:"some url")
    let request:NSURLRequest = NSURLRequest(URL:url)
    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
            /* this next line gives the below error */
            dataOutput = data
    })
    return dataOutput
}

但我收到错误:

error: variable 'dataOutput' captured by a closure before being initialized

我尝试从completionHandler返回值,但它需要一个void返回,这奇怪地让我想起我希望在没有帮助的情况下解决这个问题......:D

我看过:如何在 Swift 中使用带有 return 的completionHandler闭包? https://stackoverflow.com/questions/24647406/how-to-use-completionhandler-closure-with-return-in-swift但这并不能真正回答我的问题。我的目标是从块中获取异步请求的数据,以便在代码的其他地方使用。我是否应该在这个块中完成此请求的所有工作而不取出数据?

谢谢你!

EDIT

好吧,我有一个我认为可能可行的选择,但对我来说似乎并不合适。有人可以告诉我这是否是实现我的目标的最佳方式?

func doThingsWithData( data: NSData ) -> String {
    /* code to extract string from NSData */
    return somestring
}
func getAsynchData() {
    let url:NSURL = NSURL(string:"some url")
    let request:NSURLRequest = NSURLRequest(URL:url)
    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
            /* this next line gives the below error */
            doThingsWithData(data)
    })
}

编辑 2 -> 响应撤消

谢谢,撤消。你的回答对我来说很有意义。这里有更多的谜题。我有一个类是我的 API 处理程序。我希望能够实例化该类,并调用它的函数以从 API 获取数据。我宁愿通过一个 api 调用获取所有数据,而不是每次为我需要获取的每个值进行单独的调用,因为单个 API 调用包含我需要的所有数据,但这可能是一个完全不同的答案。这是代码:

class GetInfoFromAPI {

    func getSpecificValue(index : String) -> String {
        /* I assume I need to send the values from this function, yea? but how do I get them here? */
    }

    func doThingsWithData( data: NSData ) -> String {
        /* code to extract string from NSData */
        var error: NSError?
        let jsonDict = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as NSDictionary

        specificValue1 : String = jsonDict.valueForKey("value1") as String
        specificValue2 : String = jsonDict.valueForKey("value2") as String
        specificValue3 : String = jsonDict.valueForKey("value3") as String

        /* I want to get these ^^^ values into the ViewController below */
    }

    func getAsynchData() {
        let url:NSURL = NSURL(string:"some url")
        let request:NSURLRequest = NSURLRequest(URL:url)
        let queue:NSOperationQueue = NSOperationQueue()

        NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
            /* this next line gives the below error */
            doThingsWithData(data)
        })
    }
}


class ViewController: UIViewController {

    @IBOutlet var labelVariable1: UILabel
    @IBOutlet var labelVariable2: UILabel
    @IBOutlet var labelVariable3: UILabel

    let apiInstance = GetInfoFromAPI()

    @IBAction func buttonTapped(sender : AnyObject) {
        labelVariable1 = apiInstance.getSpecificValue(1)
        labelVariable2 = apiInstance.getSpecificValue(2)
        labelVariable3 = apiInstance.getSpecificValue(3)
    }

}

感谢您抽出时间回答我的问题。我是 Swift 新手,堆栈溢出非常有帮助!


让我尝试解释一下这一点 - 这是对线程的误解,我自己一开始也曾为此苦苦挣扎。我将尝试稍微简化一下事情。当您运行此代码时:

NSLog("Log 1")

NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        NSLog("Log in Completion Block")
})

NSLog("Log after request")

您将得到如下所示的输出:

Log 1
Log after request
Log in completion block

让我制作一个图表,有点像时间线:

                    "Log 1" (before request is sent)
                                       |
                                       |
                           Request sent over Internet
                                       |
                                     /   \  
                   "Log after request"   |
               This is logged *before*   | 
           the other one, because this   |
          one doesn't have to wait for   |
               the network to respond.   |
                                         |
The method finishes and returns a value. |
------------------------------------------------------------------------------
                                         | The network finally responds,
                                         | and the completion block is run.
                                         |

                                         "Log in completion block"

垂直线是该方法完成并返回的位置。在所有情况下,您的方法在运行完成块之前都已经向其调用者返回了一个值。你不能线性地思考这个问题。

我是否应该在这个块中完成此请求的所有工作而不取出数据?

是的,本质上是。如果您向我展示调用的代码,我可以提供更多帮助getAsynchData()首先。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 NSURLConnection 中从 Swift 中的completionHandler 中获取数据 的相关文章

随机推荐