ios - jsondecoder - Cadena Swift que se escapa al serializar a JSON utilizando Codable
string to json swift 4 (4)
En realidad no puedes hacer eso ya que en macOS y Linux hay sistemas de escape un poco diferentes. En linux // está permitido, macOS - no (utiliza NSSerialization). Por lo tanto, solo puede agregar el porcentaje de codificación en su cadena, lo que le garantiza cadenas iguales en macOS y linux, la publicación correcta de cadenas en un servidor y la validación correcta. Al agregar el porcentaje de escape, establezca CharacterSet.urlHostAllowed
. Podría hacerse así:
init(name: String, profile: String){
username = name
if let percentedString = profile.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed){
profileURL = percentedString
}else{
profileURL = ""
}
}
De la misma manera, puedes eliminarPercentEncoding ¡Y NO NECESITAS MODIFICAR EL LADO DEL SERVIDOR!
Estoy tratando de serializar mi objeto de la siguiente manera:
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)
}
Sin embargo en macOS me sale lo siguiente:
{"profileURL":"http:////google.com","username":"John"}
(nota escapada carácter ''/'').
Mientras que en las máquinas Linux estoy recibiendo:
{"username":"John","profileURL":"http://google.com"}
¿Cómo puedo hacer que JSONEncoder devuelva el formulario sin escapar en macOS?
Necesito que la cadena en JSON esté estrictamente sin escapar.
Entiendo. La cosa era que no contenía ningún carácter. Es la propiedad de swift que siempre devolverá tal cadena en una consola. La solución es j-son analizarlo.
Aún así, puede ser usado debajo de la solución de reemplazar ''/ /'' con la cadena "/"
let newString = str.replacingOccurrences(of: "///", with: "/")
print(newString)
Mientras jugaba con JSONEncoder / JSONDecoder, encontré que el tipo de URL
tiene pérdidas en codificar -> decodificar.
Inicializa con una cadena, relativa a otra URL.
init?(string: String, relativeTo: URL?)
Podría ser de ayuda este documento de Apple: https://developer.apple.com/documentation/foundation/url
utilizando la versión PropertyList
, sin embargo:
let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))!
let url2 = PropertyListDecoder().decode([URL].self, from: PropertyListEncoder().encode([User]))
Otra manera
let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))!
let url2 = JSONDecoder().decode([URL].self, from: JSONEncoder().encode([User]))
Espero te ayude !!
Terminé usando replacingOccurrences(of:with:)
, que puede no ser la mejor solución, pero resuelve el problema:
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)
}