How to get utf8 decoded string from Decodable?

2019-08-30 07:53发布

问题:

The issue is that I have a json data contains and encoded string, example:

let jsonData = "{ \"encoded\": \"SGVsbG8gV29ybGQh\" }".data(using: .utf8)

What I need is to get the decoded value of "SGVsbG8gV29ybGQh" string.

Actually I could get the desired output by implementing:

let decoder = JSONDecoder()
let result = try! decoder.decode(Result.self, from: jsonData!)

if let data = Data(base64Encoded: result.encoded), let decodedString = String(data: data, encoding: .utf8) {
    print(decodedString) // Hello World!
}

What I had to do is:

  • convert the encoded string That I got from the json (result.encoded) to Data object

  • Reconvert the data object to a string again.

However, it seems to be more than just a one step to achieve it, is there better approach(es) to be followed for such a case?

回答1:

When it comes to handle encoded string for a Decodable, actually you don't even have to declare the property as String, just directly declare it as Data.

So for your case, what you should do is to edit encoded to as:

struct Result: Decodable {
    var encoded: Data
}

thus:

let decoder = JSONDecoder()
let result = try! decoder.decode(Result.self, from: jsonData!)

let decodedString = String(data: result.encoded, encoding: String.Encoding.utf8)
print(decodedString ?? "") // decodedString

Keep in mind that it is a pretty similar case to handling Dates for decodables, as an example consider that we have the following json data:

let jsonData = "{ \"timestamp\": 1527765459 }".data(using: .utf8)

Obviously, you won't receive timestamp as number and convert it to a Date object, instead you would declare it as Date:

struct Result: Decodable {
    var timestamp: Date
}

thus:

let decoder = JSONDecoder()
// usually, you should edit decoding strategy for the date to get the expected result:
decoder.dateDecodingStrategy = .secondsSince1970

let result = try! decoder.decode(Result.self, from: jsonData!)
print(result.timestamp) // 2018-05-31 11:17:39 +0000