假設我有一個物件,Game,它包含三個屬性,score,firstName,lastName。
class Game: Encodable {
var firstName: String
var lastName: String
var score: Int
enum CodingKeys: String, CodingKey {
case firstName
case lastName
case score
}
func encode(to encoder: Encoder) throws {
var encoder = encoder.container(keyedBy: CodingKeys.self)
try? encoder.encode(self.firstName, forKey: .firstName)
try? encoder.encode(self.lastName, forKey: .lastName)
try? encoder.encode(self.score, forKey: .score)
}
}
說我想把它持久化到磁盤,我可以使用 JSONEncoder
let game = Game(firstName: "John", lastName: "Smith", score: 42)
let data = try JSONEncoder().encode(game)
{
firstName: "John",
lastName: "Smith",
score: 42
}
現在我希望用戶能夠自己生成 JSON 并將其共享給任何應用程式,但出于隱私原因我想省略姓氏,我如何encode(to encoder: Encoder)為一種型別創建兩個實作?
示例輸出:
{
firstName: "John",
score: 42
}
uj5u.com熱心網友回復:
您可以向類中添加一個附加變數(確保不要將此附加變數添加到 CodingKeys enum)并在您的encode(to encoder:函式中使用它,如圖所示
class Game: Encodable { // assuming you have assigned initial values to all your properties or you have a init which initializes all these properties, I would have used struct but am not sure of your usecase so leaving it as is
var firstName: String
var lastName: String
var score: Int
var isLastNameEnabled: Bool
enum CodingKeys: String, CodingKey {
case firstName
case lastName
case score
}
func encode(to encoder: Encoder) throws {
var encoder = encoder.container(keyedBy: CodingKeys.self)
try? encoder.encode(self.firstName, forKey: .firstName)
if isLastNameEnabled {
try? encoder.encode(self.lastName, forKey: .lastName)
}
try? encoder.encode(self.score, forKey: .score)
}
}
最后,如果您想將姓氏添加為 JSON 的一部分,請使用
let game = Game(firstName: "John", lastName: "Smith", score: 42, isLastNameEnabled: true)
do {
let data = try JSONEncoder().encode(game)
let json = String(bytes: data, encoding: .utf8)
print(json)
}
catch {
print(error) //handle error here
}
開/關:
{ "firstName": "John", "score": 42, "lastName": "Smith" }
如果你想避免使用姓氏
let game = Game(firstName: "John", lastName: "Smith", score: 42, isLastNameEnabled: false)
do {
let data = try JSONEncoder().encode(game)
let json = String(bytes: data, encoding: .utf8)
print(json)
}
catch {
print(error) // handle error here
}
開/關:
{ "firstName":"John", "score":42 }
uj5u.com熱心網友回復:
有一些選擇。除了 Sandeep 帶有 Bool 標志的解決方案之外,多型性可能是另一種:
final class ShareableGame: Game {
init(_ game: Game) {
super.init(firstName: game.firstName,
lastName: game.lastName,
score: game.score)
}
override func encode(to encoder: Encoder) throws {
var encoder = encoder.container(keyedBy: CodingKeys.self)
try? encoder.encode(self.firstName, forKey: .firstName)
try? encoder.encode(self.score, forKey: .score)
}
}
let game = Game(firstName: "John", lastName: "Smith", score: 42)
let shareableGame = ShareableGame(game)
let shareableGameData = try JSONEncoder().encode(shareableGame)
print(String(bytes: shareableGameData, encoding: .utf8)!)
// {"firstName":"John","score":42}
(假設 Game 類的定義與此類似:)
class Game: Encodable {
let firstName: String
let lastName: String
let score: Int
init(firstName: String, lastName: String, score: Int) {
self.firstName = firstName
self.lastName = lastName
self.score = score
}
/*
encode(to:) throws can be omitted, since the default
implementation is exactly as expected.
*/
enum CodingKeys: String, CodingKey {
// Cannot be omitted, since it's used in subclasses.
case firstName
case lastName
case score
}
}
uj5u.com熱心網友回復:
您可以使用userInfo字典中的字典JSONEncoder來設定一個標志,無論這是否是私有編碼。這樣您就不需要向您的型別添加屬性或創建另一個屬性。
首先我們需要一個字典的鍵,我在這里做了一個更通用的
let isPrivateInfoKey = CodingUserInfoKey(rawValue: "isPrivate")!
然后我們需要在 encode 函式中檢查它
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
let isPrivate = encoder.userInfo[isPrivateInfoKey] as? Bool ?? true
try container.encode(self.firstName, forKey: .firstName)
if isPrivate {
try container.encode(self.lastName, forKey: .lastName)
}
try container.encode(self.score, forKey: .score)
}
如果鍵/值尚未添加到字典中,則默認為 true,因此僅當不應包含姓氏時才需要設定它
let encoder = JSONEncoder()
encoder.userInfo[isPrivateInfoKey] = false
do {
let game = Game(firstName: "John", lastName: "Smith", score: 42)
let data = try encoder.encode(game)
if let s = String(data: data, encoding: .utf8) { print(s) }
} catch {
print(error)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/347599.html
