无法获取从 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() 返回的数据的主要内容,如果未能解决你的问题,请参考以下文章
无法使用类型的参数列表调用“dataTask”(使用:NSMutableRequest,...)
无法从 Fortran 90 中返回的 C 浮点指针获取数据