web-dev-qa-db-fra.com

Swift Chaîne s'échappant lors de la sérialisation en JSON à l'aide de Codable

J'essaie de sérialiser mon objet comme suit:

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

Cependant sur macOS, j'obtiens ce qui suit:

{"profileURL":"http:\/\/google.com","username":"John"}

(notez le caractère '/' échappé).

Sur les machines Linux, je reçois:

{"username":"John","profileURL":"http://google.com"}

Comment puis-je faire en sorte que JSONEncoder retourne le sans échappement?

J'ai besoin que la chaîne en JSON soit strictement non échappée.

24
tofiffe

J'ai fini par utiliser replacingOccurrences(of:with:), ce qui n'est peut-être pas la meilleure solution, mais cela résout le problème:

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)
}
10
tofiffe

J? ai compris. Le fait était qu'il ne contenait aucun caractère \. C'est juste la propriété de Swift qu'il retournera toujours une telle chaîne sur une console. La solution de contournement consiste à l'analyser par j-son.

Néanmoins, vous pouvez utiliser la solution ci-dessous pour remplacer '\ /' par la chaîne "/"

 let newString = str.replacingOccurrences(of: "\\/", with: "/") 
 print(newString)
4
Ashish

Pour iOS 13+/macOS 10.15 +

Vous pouvez utiliser .withoutEscapingSlashes option pour le décodeur json pour éviter d'échapper aux barres obliques

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

Console O/P

{"profileURL": " http://google.com ", "nom d'utilisateur": "John"}


REMARQUE: Comme mentionné par Martin R dans les commentaires \/ est une séquence d'échappement JSON valide.

3
Inder Kumar Rathore

En jouant autour de JSONEncoder/JSONDecoder, j'ai trouvé que le type URL est avec perte lors de l'encodage -> décodage.

Initialise avec une chaîne, par rapport à une autre URL.

init?(string: String, relativeTo: URL?)

Cela pourrait être utile Apple document: https://developer.Apple.com/documentation/foundation/url

en utilisant la version PropertyList, cependant:

let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))! 
let url2 = PropertyListDecoder().decode([URL].self, from: PropertyListEncoder().encode([User]))

Autre voie

let url = URL(string: "../", relativeTo: URL(string: "http://google.com"))! 
let url2 = JSONDecoder().decode([URL].self, from: JSONEncoder().encode([User]))

L'espoir vous sera utile !!

1
BuLB JoBs