如何在 Realm 对象上建模 Swift 字典 属性?
How to model a Swift dictionary property on a Realm object?
我应该如何在 Realm 对象上为字典 属性 建模,以便在编码为 JSON 时我可以得到:
{
"firstName": "John",
"lastName": "Doe",
"favoriteThings": {
"car": "Audi R8",
"fruit": "strawberries",
"tree": "Oak"
}
}
我尝试使用我在其他地方看到的 'key' 和 'value' 属性创建一个新对象 FavoriteThings...
public class Person: Object {
@objc dynamic var firstName = ""
@objc dynamic var lastName = ""
var favoriteThings = List<FavoriteThings>()
}
但是当我将它编码为 JSON 时,List 自然而然地给了我一个数组。我不想要一个数组。我正在使用 Swift Codable。
{
"firstName": "John",
"lastName": "Doe",
"favoriteThings": [
{
"key": "fruit",
"value": "strawberries"
},
{
"key": "tree",
"value": "Oak"
}
],
}
感谢任何指点!
贡萨洛
如您所知,列表默认编码为 json 数组。因此,要将列表编码为字典,您必须实现自定义编码方法才能做到这一点。
public class FavoriteThings: Object {
@objc dynamic var key = ""
@objc dynamic var value = ""
convenience init(key: String, value: String) {
self.init()
self.key = key
self.value = value
}
}
public class Person: Object, Encodable {
enum CodingKeys: String, CodingKey {
case firstName
case lastName
case favoriteThings
}
@objc dynamic var firstName = ""
@objc dynamic var lastName = ""
let favoriteThings = List<FavoriteThings>()
convenience init(firstName: String, lastName: String, favoriteThings: [FavoriteThings]) {
self.init()
self.firstName = firstName
self.lastName = lastName
self.favoriteThings.append(objectsIn: favoriteThings)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(firstName, forKey: .firstName)
try container.encode(lastName, forKey: .lastName)
var favThings: [String: String] = [:]
for thing in favoriteThings {
favThings[thing.key] = thing.value
}
try container.encode(favThings, forKey: .favoriteThings)
}
}
用法是这样的:
func testEncode() {
let john = Person(
firstName: "John",
lastName: "Doe",
favoriteThings: [
.init(key: "car", value: "Audi R8"),
.init(key: "fruit", value: "strawberries"),
.init(key: "tree", value: "Oak"),
])
let encoder = JSONEncoder()
let data = try! encoder.encode(john)
if let string = String(data: data, encoding: .utf8) {
print(string)
}
}
打印:
{"firstName":"John","favoriteThings":{"car":"Audi R8","fruit":"strawberries","tree":"Oak"},"lastName":"Doe"}
我应该如何在 Realm 对象上为字典 属性 建模,以便在编码为 JSON 时我可以得到:
{
"firstName": "John",
"lastName": "Doe",
"favoriteThings": {
"car": "Audi R8",
"fruit": "strawberries",
"tree": "Oak"
}
}
我尝试使用我在其他地方看到的 'key' 和 'value' 属性创建一个新对象 FavoriteThings...
public class Person: Object {
@objc dynamic var firstName = ""
@objc dynamic var lastName = ""
var favoriteThings = List<FavoriteThings>()
}
但是当我将它编码为 JSON 时,List 自然而然地给了我一个数组。我不想要一个数组。我正在使用 Swift Codable。
{
"firstName": "John",
"lastName": "Doe",
"favoriteThings": [
{
"key": "fruit",
"value": "strawberries"
},
{
"key": "tree",
"value": "Oak"
}
],
}
感谢任何指点!
贡萨洛
如您所知,列表默认编码为 json 数组。因此,要将列表编码为字典,您必须实现自定义编码方法才能做到这一点。
public class FavoriteThings: Object {
@objc dynamic var key = ""
@objc dynamic var value = ""
convenience init(key: String, value: String) {
self.init()
self.key = key
self.value = value
}
}
public class Person: Object, Encodable {
enum CodingKeys: String, CodingKey {
case firstName
case lastName
case favoriteThings
}
@objc dynamic var firstName = ""
@objc dynamic var lastName = ""
let favoriteThings = List<FavoriteThings>()
convenience init(firstName: String, lastName: String, favoriteThings: [FavoriteThings]) {
self.init()
self.firstName = firstName
self.lastName = lastName
self.favoriteThings.append(objectsIn: favoriteThings)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(firstName, forKey: .firstName)
try container.encode(lastName, forKey: .lastName)
var favThings: [String: String] = [:]
for thing in favoriteThings {
favThings[thing.key] = thing.value
}
try container.encode(favThings, forKey: .favoriteThings)
}
}
用法是这样的:
func testEncode() {
let john = Person(
firstName: "John",
lastName: "Doe",
favoriteThings: [
.init(key: "car", value: "Audi R8"),
.init(key: "fruit", value: "strawberries"),
.init(key: "tree", value: "Oak"),
])
let encoder = JSONEncoder()
let data = try! encoder.encode(john)
if let string = String(data: data, encoding: .utf8) {
print(string)
}
}
打印:
{"firstName":"John","favoriteThings":{"car":"Audi R8","fruit":"strawberries","tree":"Oak"},"lastName":"Doe"}