Быстрая стирание строк при сериализации в JSON с использованием Codable
Я пытаюсь сериализовать свой объект следующим образом:
import Foundation
struct User: Codable {
let username: String
let profileURL: String
}
let user = User(username: "John", profileURL: "http://google.com")
let json = try? JSONEncoder().encode(user)
if let data = json, let str = String(data: data, encoding: .utf8) {
print(str)
}
Однако в macOS я получаю следующее:
{"profileURL":"http:\/\/google.com","username":"John"}
(примечание экранировано символом '/').
В то время как на машинах Linux я получаю:
{"username":"John","profileURL":"http://google.com"}
Как я могу заставить JSONEncoder возвращать неэкранированный?
Мне нужно, чтобы строка в JSON была строго неэкранированной.
Ответы
Ответ 1
В итоге я использовал replacingOccurrences(of:with:)
, что может быть не лучшим решением, но оно устраняет проблему:
import Foundation
struct User: Codable {
let username: String
let profileURL: String
}
let user = User(username: "John", profileURL: "http://google.com")
let json = try? JSONEncoder().encode(user)
if let data = json, let str = String(data: data, encoding: .utf8)?.replacingOccurrences(of: "\\/", with: "/") {
print(str)
dump(str)
}
Ответ 2
Я понял. Дело в том, что он не содержал никакого символа. Это просто свойство быстрого, чтобы он всегда возвращал такую строку на консоли. Обходной путь заключается в том, чтобы j-son проанализировал его.
Тем не менее, вы можете использовать ниже решение для замены '\/' на строку "/"
let newString = str.replacingOccurrences(of: "\\/", with: "/")
print(newString)
Ответ 3
Для iOS 13+/macOS 10. 15+
Вы можете использовать опцию .withoutEscapingSlashes
для декодера json, чтобы избежать слеша
let user = User(username: "John", profileURL: "http://google.com")
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .withoutEscapingSlashes
let json = try? jsonEncoder.encode(user)
if let data = json, let str = String(data: data, encoding: .utf8) {
print(str)
}
Консоль O/P
{"profileURL":"http://google.com","username":"John"}
ПРИМЕЧАНИЕ: Как упомянуто Мартином R в комментариях \/
, это допустимая escape-последовательность JSON.
Ответ 4
Во время воспроизведения JSONEncoder/JSONDecoder,
Я обнаружил, что тип URL
имеет потерю при кодировании → декодирование.
Инициализирует строку по отношению к другому URL.
init?(string: String, relativeTo: URL?)
Возможно, вам поможет этот документ яблока: https://developer.apple.com/documentation/foundation/url
используя версию PropertyList
, однако:
let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))!
let url2 = PropertyListDecoder().decode([URL].self, from: PropertyListEncoder().encode([User]))
Другой способ
let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))!
let url2 = JSONDecoder().decode([URL].self, from: JSONEncoder().encode([User]))
Надеюсь, вам будет полезно!
Ответ 5
На самом деле вы не можете этого сделать, поскольку в macOS и Linux немного разные экранирующие системы. В linux//разрешен, macOS - нет (он использует NSSerialization). Таким образом, вы можете просто добавить процентную кодировку в свою строку, что гарантирует вам равные строки на macOS и linux, правильную проводку строки на сервер и правильную проверку. При добавлении процента сбрасывания установите CharacterSet.urlHostAllowed
. Это можно сделать следующим образом:
init(name: String, profile: String){
username = name
if let percentedString = profile.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed){
profileURL = percentedString
}else{
profileURL = ""
}
}
Таким же образом вы можете удалитьPercentEncoding
И ВАМ НЕОБХОДИМО ИЗМЕНИТЬ СТОРОНУ СЕРВЕР!!!