Как получить utf8 декодированную строку из Decodable? - PullRequest
0 голосов
/ 06 июня 2018

Проблема в том, что у меня есть данные json, содержащие и закодированные строки, например:

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

Мне нужно получить декодированное значение строки "SGVsbG8gV29ybGQh".

На самом делеЯ мог бы получить желаемый результат, реализовав:

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!
}

Что мне нужно было сделать:

  • преобразовать закодированную строку, полученную из json (result.encoded) к объекту данных

  • Снова преобразовать объект данных в строку.

Однако, похоже, это больше, чем просто один шагЧтобы достичь этого, есть ли лучший подход (ы), который следует использовать для такого случая?

1 Ответ

0 голосов
/ 06 июня 2018

Когда дело доходит до обработки закодированной строки для Decodable, на самом деле вам даже не нужно объявлять свойство как String, просто просто объявите его как Data.

Так что для вашегоСлучай, который вы должны сделать, это отредактировать encoded как:

struct Result: Decodable {
    var encoded: Data
}

таким образом:

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

Имейте в виду, что это довольно похожий случай для обработки Даты для декодируемых данных. В качестве примера рассмотрим, что у нас есть следующие данные json:

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

Очевидно, что вы не получите timestamp как число и преобразуете его в объект Dateвместо этого вы бы объявили его как Date:

struct Result: Decodable {
    var timestamp: Date
}

таким образом:

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
...