问题
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 objectReconvert 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
来源:https://stackoverflow.com/questions/50710795/how-to-get-utf8-decoded-string-from-decodable