Swift JSONDecoder 在转义字符后给出“意外字符”,可以使用原始字符串修复,但仅限于游乐场

问题描述 投票:0回答:1

从 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)!
),并且它成功解析到我的对象中。

swift decoding jsondecoder rawstring
1个回答
0
投票

以下是处理此问题的分步方法:

从API获取数据。 将数据转换为字符串。 替换无效的转义序列。 将清理后的字符串转换回数据。 解码 JSON。 以下是如何在 Swift 中实现此功能:

进口粉底

// 根据 JSON 结构定义您的模型 结构 AppDetails:可编码 { 让类型:字符串 让名称:字符串 // 根据 JSON 响应添加其他字段 }

func fetchAppDetails(appId: String, 完成: @escaping (Result) -> Void) { 让 urlString = "https://store.steampowered.com/api/appdetails?appids=(appId)" Guard let url = URL(string: urlString) else { return }

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()

}

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.