我从API中提取了JSON数据,并使用JSON解码器进行了解码,然后尝试用分派队列中的JSON数据填充数组数据结构,以便在其他方法中使用它,但当我尝试在其他方法或函数中访问数据时,它会显示数组为空
这就是我解码JSON数据并尝试填充分派队列中的数组的方法
if let url = URL(string:"https://parseapi.back4app.com/classes/restaurants"){
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("app id", forHTTPHeaderField: "X-Parse-Application-Id")
request.setValue("REST API key", forHTTPHeaderField: "X-Parse-REST-API-Key")
let session = URLSession.shared
session.dataTask(with: request) { [self] (data, response, err) in
guard let jsonData = data else {
return
}
do {
let decoder = JSONDecoder()
let restaurantList = try decoder.decode(restaurants.self, from: jsonData)
self.restaurantStruct = restaurantList
DispatchQueue.main.async {
self.fillArray()
}
}
catch let jsonErr {
print("Error decoding JSON", jsonErr)
}
}
.resume()
}
这是我编写的fillArray方法
x一个一个一个一个x一个一个二个x
1条答案
按热度按时间v8wbuo2f1#
我(还)没有解决方案,但在评论中讨论之后,我认为提供一些代码可能有助于调试过程,而评论对此太有限了。
首先你需要确定你的集合视图是否如你所期望的那样工作。为了确定我们需要一些本地数据,将这些数据添加到你的
ViewController
源文件中。它们可以是全局的然后我们将
dataTask
完成处理程序的大部分内容提取到它自己的方法中,以便我们可以将其用于调试数据:请注意,我从对
fillArray()
的调用中删除了DispatchQueue.main.async
,因此如果您更改了fillArray
以进行UI调用(例如我在注解中建议调用setNeedsDisplay()
的那个),请删除这些调用。让我们也将
dataTask
调用封装在一个方法中:我添加了
err
不是nil
的情况下的检查,以处理网络/HTTP错误,并且它期望URL作为String
参数。它还使用我们前面创建的setRestuarantData(from:)
方法。除此之外,它与您的代码相同。我们不再直接调用代码中最初调用
dataTask
的地方的requestRestaurantData(from:)
,而是提供一个更高级别的间接调用:现在,在最初调用
dataTask
的代码中,将其替换为这应该会给予与您已经拥有的完全相同的行为。只是要确保在进行这些更改时没有破坏任何东西。换句话说,您的
UICollectionView
仍然不包含餐馆数据。这是意料之中的,但是之前工作的其他所有东西应该仍然工作。然后从
.normal
更改为.debugSync
。这将在requestRestaurantData(_:)
返回之前同步填充数组。如果唯一的问题是从异步任务设置视图的数据,则视图现在应该显示调试数据。如果没有,则根本上没有正确设置视图或其数据,必须在继续之前修复。假设视图显示了调试数据,现在从
.debugSync
更改为.debugAsync
,这将在异步任务中填充数组,因此它的行为更像dataTask
,但没有网络访问,延迟也更短。因为它不需要等待网络响应,它只会在主运行循环的下几次迭代中执行,如果没有其他任务排队的话,可能会在下一次迭代中执行。如果你的视图没有使用
.debugAsync
更新,我想应该是这样,你知道你没有通知视图,它的委托,或者因为它是UICollectionView
,它的dataSource
有新的数据,所以它需要更新/重绘。我目前的想法是你需要为你的UICollectionView
调用reloadData
方法:如果这不起作用,那么将有更多的调试要做。评论让我知道。
最后,当你让它工作时,从
.debugAsync
更改为.normal
。假设网络连接和服务器正在运行,你的视图应该工作。如果没有,有一些完全不同的问题,我想。但我很肯定,如果它工作与.debugAsync
它将工作与.normal
。一旦你让它工作了,你就可以删除调试代码了。不过我会把非调试的提取方法留在原处。