次のようにオブジェクトをシリアル化しようとしています:
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 "、 "username": "John"}
注:Martin R のコメント\/
は有効なJSONエスケープシーケンスです。
JSONEncoder/JSONDecoderで遊んでいると、エンコード->デコードでURL
タイプが非可逆であることがわかりました。
別のURLに関連する文字列で初期化します。
init?(string: String, relativeTo: URL?)
これが役立つかもしれませんApple document: 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]))
あなたに役立つことを願っています!!