Экранирование json объекта

19.05.2020
1 мин

Думаю многие работали с экранированием URL. А можете с ходу ответить экранируется ли json при отправке в body? В своей работе я столкнулся с тем, что по умолчанию json body запроса экранируется при использовании стандартного JSONEncoder. Чем это плохо спросите вы?

bug Проблема

А вот представьте, что вы отправляете адрес: Трамвайный переулок 3/4. Что получим в body? Вот такую штуку: Трамвайный переулок 3\/4. И затем бедный менеджер будет декодировать этот адрес вручную (при тестировании ни один менеджер не пострадал).

idea Решение

Хорошая новость в том, что это можно легко исправить! У JSONEncoder есть свойство withoutEscapingSlashes.

Плохая в том, что только на iOS 13. Иначе вам придется делать это вручную. Вот пример, как это может выглядеть:

struct WithoutEscapingSlashesEncoder {
private enum EncoderError: InternalError {
case dataToUTF8
case utf8ToData
}
func encode<T: Encodable>(_ object: T) throws -> Data {
let jsonEncoder = JSONEncoder()
if #available(iOS 13, *) {
jsonEncoder.outputFormatting = .withoutEscapingSlashes
return try jsonEncoder.encode(object)
} else {
let data = try jsonEncoder.encode(object)
guard let string = String(data: data, encoding: .utf8)
else { throw EncoderError.dataToUTF8 }
let fixedString = string.replacingOccurrences(of: "\\/", with: "/")
guard let fixedData = fixedString.data(using: .utf8)
else { throw EncoderError.utf8ToData }
return fixedData
}
}
}

Вы можете оставить свой фидбек в этом твите edit.