我正在获取一组URL,并在“集合视图”中对其进行解码。我之前已经成功完成了此操作,但是这次却收到错误消息。
我收到错误:
Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的JSON。”,underlyingError:可选(错误域= NSCocoaErrorDomain代码= 3840,JSON文本未开始带有数组或对象以及允许未设置片段的选项。“ UserInfo = {NSDebugDescription = JSON文本不是以数组或对象开头并且允许不允许设置片段的选项。})))
我要注意的是,如果可能的话,它似乎正在尝试在完成另一个解码之前对其进行解码。我相信这是因为在我运行该应用程序的某些时候,它将在抛出错误之前很好地打印一两个解码数据实例。
这是我的代码:
struct Details: Codable {
let name: String
let location: Location
}
struct Location: Codable {
let address: Address
let geoCode: Geo
}
struct Geo: Codable {
let latitude: String
let longitude: String
}
struct Address: Codable {
let street: String
let state: String
let city: String
let postalCode: String
let country: String
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = showtimesCollection.dequeueReusableCell(withReuseIdentifier: "timeCell", for: indexPath) as! TimeCell
let theaters = self.theaterIds[indexPath.row]
let id = theaters
let apiKey = ""
let url = URL(string: "http://data.tmsapi.com/v1.1/theatres/\(id)?api_key=\(apiKey)")
print(url!)
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )
let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
if let data = data {
do { let theater = try JSONDecoder().decode(Details.self, from: data) //error: Swift.DecodingError.dataCorrupted
print(theater)
} catch let err {
print("JSON Error")
}
})
task.resume()
return cell }
数组看起来像这样:
["12345", "23456", "34567", "45678"]
该数组正在正确打印到控制台,因此正在解码的URL。它们与成功运行的控制器的显示方式相同。
JSON如下:
{
"theatreId": "2469",
"name": "Paramount Theatre",
"location": {
"telephone": "512-472-5470",
"geoCode": {
"latitude": "30.2694",
"longitude": "-97.7419"
},
"address": {
"street": "713 Congress Ave",
"state": "TX",
"city": "Austin",
"country": "USA",
"postalCode": "78701"
}
}
}
为什么我会收到此错误?如果我的理论认为它试图太快地加载它们,那么我如何才能等到第一个完成时呢?
编辑:我在JSONDecoder中添加了一个catch块,并且每次调用都随机获得成功的一个错误。每次我运行该应用时,它看起来都与此类似。
JSON Error
JSON Error
JSON Error
JSON Error
Details(name: "Paramount Theatre", location: Film_Bee.ShowtimesView.Location(address: Film_Bee.ShowtimesView.Address(street: "1245 Station Place", state: "TX", city: "Austin", postalCode: "12345", country: "USA"), geoCode: Film_Bee.ShowtimesView.Geo(latitude: "43.12345", longitude: "-44.12345")))
JSON Error
每次获得成功和失败的次数都不同,总是顺序不同。
编辑:我已经解决了问题,并将解决方案作为答案发布了。
另一种解决方案是在每个呼叫之间设置延迟。我该如何实现?
答案 0 :(得分:0)
您收到此错误,因为您没有收到JSON数据。 不要忘记像下面的代码一样检查HTTP状态
let url = URL(string: "http://data.tmsapi.com/v1.1/theatres/\(2469)?api_key=\(apiKey)")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error == nil, data != nil, let rep = response as? HTTPURLResponse {
switch rep.statusCode {
case 200:
if let theater = try? JSONDecoder().decode(Details.self, from: data!) {
print(theater)
}
default:
print("Receive HTTP status: \(rep.statusCode)")
print(String(data: data!, encoding: .utf8))
print(rep.statusCode)
}
} else {
print(error)
}
}.resume()
由于该端点,API响应为:
<h1>Not Authorized</h1>
,状态码为 403
答案 1 :(得分:0)
所以我尝试了以下代码:
let data = """
{
"theatreId": "7719",
"name": "Navy Pier IMAX Theatre",
"location": {
"telephone": "312-595-5629",
"geoCode": {
"latitude": "41.8921",
"longitude": "-87.6088"
},
"address": {
"street": "600 E. Grand Ave. Ste 115",
"state": "IL",
"city": "Chicago",
"country": "USA",
"postalCode": "60611"
}
}
}
""".data(using: .utf8)!
do {
let theater = try JSONDecoder().decode(Details.self, from: data)
print("Name: \(theater.name)")
} catch {
print(error)
}
并且您的代码有效,它给了我以下输出:
名称:海军码头IMAX剧院
答案 2 :(得分:0)
问题在于该API每秒仅允许2个调用,而我试图进行更多操作。
要解决此问题,我将不得不使用tmsapi升级我的帐户。