swift не может декодировать строку с помощью escape-последовательности

#json #swift #decode

#json #swift #декодировать

Вопрос:

У меня есть строка в формате SO/ME/STR/ING . И я хочу иметь макет json для тестирования. И когда я создаю json с таким форматом, как:

 let json = """
{ "str": "SO/ME/STR/ING" } // Error: Invalid escape sequence in literal
"""
 

Для чего я это написал SO\/ME\/STR\/ING . Но он декодирует неверно:

 let json = """
{
    "str": "SO\/ME\/STR\/ING",
}
"""
let jsonData = Data(json.utf8)

let decoder = JSONDecoder()

do {
    let model = try decoder.decode(Model.self, from: jsonData)
    print(model) // Model(str: "SO/ME/STR/ING")
} catch {
    print(error.localizedDescription)
}
 

Как правильно декодировать?

Ответ №1:

Вам нужно 4 обратных косых черты в строке swift, чтобы представить фактическую обратную косую черту в model.str :

 let json = """
{
    "str": "\\",
}
"""
let jsonData = Data(json.utf8)

let decoder = JSONDecoder()

do {
    let model = try decoder.decode(Model.self, from: jsonData)
    print(model.str) // prints a single backslash
} catch {
    print(error.localizedDescription)
}
 

Обратная косая черта в строке JSON должна быть экранирована, поэтому вам нужно 2 обратных косых черты в строке JSON, но чтобы записать это в строковом литерале Swift, вам также нужно экранировать эти две обратные косые черты. Отсюда и 4 обратных косых черты.

Ответ №2:

Вы можете использовать необработанный строковый литерал ( #"..."# ), он же расширенные разделители строк, для представления этой экранированной строки как «то, что я вижу, это то, что я получаю»:

 let string = #"""
"SO/ME/STR/ING"
"""#
 

Внимание: ваша строка JSON должна быть действительным JSON и должна быть правильно экранирована, если это необходимо:
Последовательность из двух символов « / » экранирует «solidus» (в терминологии JSON). Приведенная выше строка будет напечатана как « SO/ME/STR/ING «.

Если вы хотите, чтобы она была напечатана как SO/ME/STR/ING , ваш строковый литерал JSON может быть определен как

 let json = #"""
{
    "str": "SO\/ME\/STR\/ING"
}
"""#
 

Приведенный выше строковый литерал является допустимой строкой JSON, соответственно, допустимым объектом JSON и может использоваться как есть. Однако это не значит, что это то, что вы ожидаете 😉

Вы должны преобразовать строковый литерал в значение данных, используя Unicode (UTF-8), прежде чем вы сможете использовать to в декодере JSON.

смотрите также: https://www.hackingwithswift.com/articles/162/how-to-use-raw-strings-in-swift