Problem
I'm currently getting JSON from a server that I don't have access to. The JSON I sometimes get will put this character \u0000
at the end of a String. As a result my decoding fails because this character just fails it.
I'm trying to debug this in Playground but I keep getting this error.
Expected hexadecimal code in braces after unicode escape
Here is some sample code to try out.
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)
Question
How do you deal with \u0000
from JSON? I have been looking at DataDecodingStrategy from the Apple documentation but I can't even test anything out because the Playground fails to even run.
Any direction or advice would be appreciated.
Update
Here is some more setup code to tryout in your Playground or a real app.
JSON test.json
{
"name": "Durian \u0000"
}
Code
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)