无法获取从 dataTask() 返回的数据

Posted

技术标签:

【中文标题】无法获取从 dataTask() 返回的数据【英文标题】:Can't get data returned from dataTask() 【发布时间】:2018-06-09 15:19:42 【问题描述】:

一周以来,我一直试图从 dataTask() 返回一个字符串。

我已经在 *** 上阅读了很多内容,也从他们处理这个主题的一些网站上阅读了很多内容。例如,this one。所以我已经明白这是 dataTask 不直接返回值,因为它发生在不同的线程上等等。我还阅读了有关闭包和完成处理程序的信息。我真的有一种感觉,我实际上已经知道这是关于什么的了。但我无法让它工作。

这是我的代码。我只是发布了整个代码,所以没有人需要担心问题会出现在我没有显示的部分。一切正常,直到我尝试返回一个值并将其保存在变量中:

func requestOGD(code gtin: String, completion: @escaping (_ result: String) -> String) 
    // MARK: Properties
    var answerList: [String.SubSequence] = []
    var answerDic: [String:String] = [:]
    var product_name = String()
    var producer = String()

    // Set up the URL request
    let ogdAPI = String("http://opengtindb.org/?ean=\(gtin)&cmd=query&queryid=400000000")

    guard let url = URL(string: ogdAPI) else 
        print("Error: cannot create URL")
        return
    

    let urlRequest = URLRequest(url: url)
    // set up the session
    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    // make the request
    let task = session.dataTask(with: urlRequest) 
        (data, response, error) in
        // check for any errors
        guard error == nil else 
            print("error calling GET on /todos/1")
            print(error!)
            return
        
        // make sure we got data
        guard let responseData = data else 
            print("Error: did not receive data")
            return
        

        // parse the result, which is String. It willbecome split and placed in a dictionary
        do 
            let answer = (String(decoding: responseData, as: UTF8.self))

            answerList = answer.split(separator: "\n")

            for entry in answerList 
                let entry1 = entry.split(separator: "=")
                if entry1.count > 1 
                    let foo = String(entry1[0])
                    let bar = String(entry1[1])
                    answerDic[foo] = "\(bar)"
                
            

            if answerDic["error"] == "0" 
                product_name = answerDic["detailname"]!
                producer = answerDic["vendor"]!

                completion(product_name)
             else 
                print("Error-Code der Seite lautet: \(String(describing: answerDic["error"]))")
                return
            
        
    
    task.resume()

这里调用了我的函数,不用担心,我也试过直接把它返回给var foo,也不行 值只存在于闭包内:

    // Configure the cell...
    var foo:String = ""

    requestOGD(code: listOfCodes[indexPath.row])  (result: String) in
        print(result)
        foo = result
        return result
    

    print("Foo:", foo)

    cell.textLabel?.text = self.listOfCodes[indexPath.row] + ""

    return cell

所以我的问题是,我有一种感觉,我无法从 http-request 中获得价值。

【问题讨论】:

嘿@matt 谢谢你的回答。是的,这也是我所理解的,但我认为解决方案是使用完成处理程序?不是吗?我的意思是,这是一个简单的场景:我通过 http-request 请求数据库 API。 API 以字符串响应。不,我想保存字符串。我该怎么做? 您不应尝试使用单独获取的远程数据填充每个单元格。执行一次远程访问以获取整个表视图的所有数据(假设它是合理数量的数据)。将获取的数据打包成适合table view的数据模型,然后重新加载table view。现在每个单元格都填充了仅加载一次的本地数据模型。 @maddy 谢谢 4 你的回答。这就是我想做的。只需发出请求,将字符串保存在我的应用程序中的某个位置,使用它执行我的逻辑并使用它来将单个数据传递到 TableView 中。但是,你能告诉我,怎么做吗?我的完成处理程序错了吗?我需要对我的整个应用程序结构进行调整吗?我真的为此发疯了,因为今天它应该是一个正常的任务。我会很高兴,如果我可以打一个简单的电话。有什么图书馆或教程可以推荐吗? 【参考方案1】:

您在对requestOGD 的调用中使用了完成处理程序:

requestOGD(code: listOfCodes[indexPath.row]) 
    (result: String) in
    // result comes back here

但随后您尝试捕获并返回该结果

    foo = result
    return result

所以你在这里犯了同样的错误,你试图通过首先使用完成处理程序来避免犯这种错误。对该完成处理程序的调用本身是异步的。因此,您再次面临同样的问题。如果此时要提取result,则需要另一个完成处理程序。

简单来说,就是这样的操作顺序:

requestOGD(code: listOfCodes[indexPath.row]) 
    (result: String) in
    foo = result // 2

print("Foo:", foo) // 1

您在异步代码运行之前打印foo,并有机会首先设置foo

在更大的范围内:您不能cellForRowAt 中使用任何异步收集的材料。在收集信息之前返回单元格。这就是异步的意思。你不能通过增加更多的异步级别来解决这个问题。你必须改变你的整个策略。

【讨论】:

感谢您的回答!这真的很有帮助!好的!所以我的整个结构和计划都行不通。

以上是关于无法获取从 dataTask() 返回的数据的主要内容,如果未能解决你的问题,请参考以下文章

从 URLRequest dataTask 返回泛型类型

按顺序附加异步响应 swit 3

无法使用类型的参数列表调用“dataTask”(使用:NSMutableRequest,...)

无法从 Fortran 90 中返回的 C 浮点指针获取数据

无法从 api 获取数据,Future 总是返回 null - 颤振

无法从 JSON 获取某些数据,返回未定义的 Angular 6