ios - Swift JSON可解码\u0000

标签 ios json swift unicode jsondecoder

问题
我目前正在从无法访问的服务器获取JSON。我有时会得到的JSON会将这个字符\u0000放在字符串的末尾。结果,我的解码失败,因为此字符使它失败。
我正在尝试在Playground中进行调试,但始终收到此错误。Expected hexadecimal code in braces after unicode escape这里是一些示例代码可以尝试。

import UIKit
import Foundation

struct GroceryProduct: Codable {
    var name: String
}

let json = """
{
    "name": "Durian \u0000"
}
""".data(using: .utf8)!

let decoder = JSONDecoder()
let product = try decoder.decode(GroceryProduct.self, from: json)

print(product.name)

您如何处理JSON中的\u0000?我一直在看Apple文档中的DataDecodingStrategy,但是我什至无法测试任何东西,因为Playground甚至无法运行。
任何方向或建议,将不胜感激。

更新资料
这是更多设置代码,可在您的Playground或真实应用中进行试用。
JSON test.json
{
    "name": "Durian \u0000"
}
extension Bundle {
    func decode<T: Decodable>(_ type: T.Type, from file: String, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys) -> T {
        
        guard let url = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to locate \(file) in bundle.")
        }

        guard let data = try? Data(contentsOf: url) else {
            fatalError("Failed to load \(file) from bundle.")
        }
                
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy    = .deferredToDate
        decoder.keyDecodingStrategy     = .useDefaultKeys

        do {
            return try decoder.decode(T.self, from: data)
        } catch DecodingError.keyNotFound(let key, let context) {
            fatalError("Failed to decode \(file) from bundle due to missing key '\(key.stringValue)' not found – \(context.debugDescription)")
        } catch DecodingError.typeMismatch(_, let context) {
            fatalError("Failed to decode \(file) from bundle due to type mismatch – \(context.debugDescription)")
        } catch DecodingError.valueNotFound(let type, let context) {
            fatalError("Failed to decode \(file) from bundle due to missing \(type) value – \(context.debugDescription)")
        } catch DecodingError.dataCorrupted(_) {
            fatalError("Failed to decode \(file) from bundle because it appears to be invalid JSON")
        } catch {
            fatalError("Failed to decode \(file) from bundle: \(error.localizedDescription)")
        }
    }
}


struct GroceryProduct: Codable {
    var name: String
}

// Try running this and it won't work
let results = Bundle.main.decode(GroceryProduct.self, from: "test.json")


print(results.name)

最佳答案

您需要先转义\u0000字符-这可以在解码之前完成:

guard let data = try? Data(contentsOf: url) else {
    fatalError("Failed to load \(file) from bundle.")
}

let escaped = Data(String(data: data, encoding: .utf8)!.replacingOccurrences(of: "\0", with: "").utf8)
...
return try decoder.decode(T.self, from: escaped)
注意:强制展开仅出于简化目的。

在Playground中,您可以使用其他\对其进行转义(以使其起作用):
let json = """
{
    "name": "Durian \\u0000"
}
""".data(using: .utf8)!
或将其替换为\0(以使其失败-在解码期间的行为类似):
let json = """
{
    "name": "Durian \0"
}
""".data(using: .utf8)!

关于ios - Swift JSON可解码\u0000,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63309869/

相关文章:

iOS - 钥匙串(keychain) - 可执行文件使用无效权利进行签名

ios - NSString 返回 null

ios - 添加导航栏但没有后退按钮

ios - Swift - 处理 UICollectionViewCell Tap

iOS 内存应用关闭

ios - iPhone 5 和 iPhone 6 @2x 图像问题

java - REST api和json解析

javascript - 在 d3.js 图表中回显 JSON

javascript - 无法确定如何在 Javascript 中使用 JSON.net

swift - Swift 中的通用类型作为返回值