从 API 中,我得到一个带有一些转义字符反斜杠的 json。这是一个例子:
https://store.steampowered.com/api/appdetails?appids=294100
当我尝试使用
JSONDecoder()
进行解码时,我得到 NSCocoaErrorDomain Code=3840 "Unexpected character . . ."
指向第一个反斜杠之后的字符。
在操场上,我可以通过在多行文字字符串之前和之后填充“#”来解决这个问题,我相信这使其成为原始字符串,然后它会成功解析。
我的问题是:当我无法直接控制传入的 api 响应时,我不确定如何告诉 JSONDecoder 将数据视为原始字符串。
或者:我不确定如何成功地用“#”字符填充/包装传入的 api 响应,因此解码器会将其视为原始字符串。
在我
"#".data(using: .utf8)!
之前,我一直未能成功尝试填充(例如:.decode
在API响应周围连接)。
我不知道如何将数据转换为具有类似
.base64EncodedString()
之类的字符串,这目前没有意义,因为我无法验证,因为解码器不喜欢 #,现在给出了意外的字符性格。
这让我很困惑,因为在操场上,我只是用“#”包围模拟多行文字 json(上面的 API 响应作为多行文字字符串,附加
.data(using: .utf8)!
),并且它成功解析到我的对象中。
以下是处理此问题的分步方法:
从API获取数据。 将数据转换为字符串。 替换无效的转义序列。 将清理后的字符串转换回数据。 解码 JSON。 以下是如何在 Swift 中实现此功能:
进口粉底
// 根据 JSON 结构定义您的模型 结构 AppDetails:可编码 { 让类型:字符串 让名称:字符串 // 根据 JSON 响应添加其他字段 }
func fetchAppDetails(appId: String, 完成: @escaping (Result
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "No data received"])))
return
}
do {
// Convert data to string to preprocess
var jsonString = String(data: data, encoding: .utf8)!
// Replace invalid escape sequences
jsonString = jsonString.replacingOccurrences(of: "\\", with: "\\\\")
// Convert string back to data
guard let cleanedData = jsonString.data(using: .utf8) else {
completion(.failure(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to convert string to data"])))
return
}
// Decode JSON
let decoder = JSONDecoder()
let response = try decoder.decode([String: AppDetails].self, from: cleanedData)
// Extract the actual app details from the response
if let appDetails = response[appId] {
completion(.success(appDetails))
} else {
completion(.failure(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "App details not found"])))
}
} catch {
completion(.failure(error))
}
}
task.resume()
}