簡體   English   中英

使用Codable序列化為JSON時Swift String轉義

[英]Swift String escaping when serializing to JSON using 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中的字符串嚴格未轉義。

我最終使用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)
}

我知道了。 事情是它沒有任何\\字符。 它只是swift的屬性,它總是會在控制台上返回這樣一個字符串。 解決方法是j-son解析它。

不過,您可以在下面使用“/”字符串替換'\\ /'的解決方案中使用

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

適用於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 ”,“用戶名”:“John”}


注:由於提馬丁- [R在評論\\/是一個有效的JSON轉義序列。

在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]))

希望對你有所幫助!!

實際上你不能這樣做,因為在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和你不需要修改服務器端!!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM