存储可解码到 Realm 但数组始终为空
Storage decodable to the Realm but the array always empty
现在我正在使用 Decodable 解析 JSON 并存储到 Realm,这里是 JSON 数据
{
"DefaultCompositionItem":[
{"Serial":1,"Category_Id":5,"Count":1,"Composition_Id":1},
{"Serial":2,"Category_Id":2,"Count":7,"Composition_Id":1},
{"Serial":3,"Category_Id":2,"Count":7,"Composition_Id":1},
{"Serial":4,"Category_Id":2,"Count":4,"Composition_Id":1},
{"Serial":5,"Category_Id":2,"Count":4,"Composition_Id":1},
{"Serial":6,"Category_Id":3,"Count":7,"Composition_Id":1},
{"Serial":7,"Category_Id":4,"Count":7,"Composition_Id":1}
],
"Serial":1,
"Case_Id":1,
"Name":"組合A",
"Price":760
}
问题是:
我无法从此 JSON 获取 DefaultCompositionItem 数组。
我正在使用名为 fetchComposition
的方法从服务器获取数据,获取 [Composition]
并使用 insertComposition
方法
插入到 Realm
func fetchComposition(from url: String, complete: @escaping (Bool, [Composition], APIError?) -> ()) {
Alamofire.request(url).responseData { (response) in
guard let data = response.result.value else {
return complete(false, [Composition](), APIError.unknownError(response.error?.localizedDescription ?? "Unknown"))
}
let decoder = JSONDecoder()
do {
let items = try decoder.decode([Composition].self, from: data)
complete(true, items, nil)
} catch {
complete(true, [Composition](), APIError.unknownError(error.localizedDescription))
}
}
}
func insertComposition(composition: Composition) {
try! realm.write {
print("Starting storing...")
// Composition
let compositionEntity = Composition()
compositionEntity.id = composition.id
compositionEntity.caseID = composition.caseID
compositionEntity.name = composition.name
compositionEntity.price = composition.price
// DefaultItem
let defaultItems = composition.items
defaultItems.forEach({ (i) in
print(i.categoryID) // print nothing
})
defaultItems.forEach({ item in
let newItem = DefaultCompositionItem()
newItem.itemID = item.itemID
newItem.categoryID = item.categoryID
newItem.compositionID = item.compositionID
newItem.count = item.count
compositionEntity.items.append(newItem)
})
realm.add(compositionEntity)
}
}
领域对象Composition
:
final class Composition:Object, Decodable {
@objc dynamic var id: Int = 0
@objc dynamic var name: String = ""
@objc dynamic var caseID: Int = 0
@objc dynamic var price: Double = 0.0
let items = List<DefaultCompositionItem>()
override static func primaryKey() -> String? {
return "id"
}
private enum RootKeys: String, CodingKey {
case DefaultCompositionItem
case Serial
case Name
case CaseId = "Case_Id"
case Price
}
convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: RootKeys.self)
id = try container.decode(Int.self, forKey: .Serial)
name = try container.decode(String.self, forKey: .Name)
caseID = try container.decode(Int.self, forKey: .CaseId)
price = try container.decode(Double.self, forKey: .Price)
if let itemArray = try container.decodeIfPresent(List<DefaultCompositionItem>.self, forKey: .DefaultCompositionItem) {
items.append(objectsIn: itemArray)
}
}
}
final class DefaultCompositionItem:Object, Decodable {
@objc dynamic var itemID: Int = 0
@objc dynamic var categoryID: Int = 0
@objc dynamic var compositionID: Int = 0
@objc dynamic var count: Int = 0
private enum ItemKeys: String, CodingKey {
case Serial
case CategoryId = "Category_Id"
case CompositionId = "Composition_Id"
case Count
}
override static func primaryKey() -> String? {
return "itemID"
}
convenience init(from decoder: Decoder) throws {
self.init()
let itemContainer = try decoder.container(keyedBy: ItemKeys.self)
itemID = try itemContainer.decode(Int.self, forKey: .Serial)
categoryID = try itemContainer.decode(Int.self, forKey: .CategoryId)
compositionID = try itemContainer.decode(Int.self, forKey: .CompositionId)
count = try itemContainer.decode(Int.self, forKey: .Count)
}
}
extension List: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
}
}
问题是您分配给 Composition
的 items
属性 而不是像需要的那样改变它。 Realm's documentation explicitly calls out List<T>
属性应该使用 let
而不是 var
来声明以避免这个问题。
将 items
更改为使用 let
声明,然后通过 修改 现有的 items
值而不是分配给它。
我还建议解码为 DefaultCompositionItem
的数组,而不是 List<DefaultCompositionItem>
,因为 List<T>
对 Swift 的 Decodable
一无所知.
现在我正在使用 Decodable 解析 JSON 并存储到 Realm,这里是 JSON 数据
{
"DefaultCompositionItem":[
{"Serial":1,"Category_Id":5,"Count":1,"Composition_Id":1},
{"Serial":2,"Category_Id":2,"Count":7,"Composition_Id":1},
{"Serial":3,"Category_Id":2,"Count":7,"Composition_Id":1},
{"Serial":4,"Category_Id":2,"Count":4,"Composition_Id":1},
{"Serial":5,"Category_Id":2,"Count":4,"Composition_Id":1},
{"Serial":6,"Category_Id":3,"Count":7,"Composition_Id":1},
{"Serial":7,"Category_Id":4,"Count":7,"Composition_Id":1}
],
"Serial":1,
"Case_Id":1,
"Name":"組合A",
"Price":760
}
问题是:
我无法从此 JSON 获取 DefaultCompositionItem 数组。
我正在使用名为 fetchComposition
的方法从服务器获取数据,获取 [Composition]
并使用 insertComposition
方法
Realm
func fetchComposition(from url: String, complete: @escaping (Bool, [Composition], APIError?) -> ()) {
Alamofire.request(url).responseData { (response) in
guard let data = response.result.value else {
return complete(false, [Composition](), APIError.unknownError(response.error?.localizedDescription ?? "Unknown"))
}
let decoder = JSONDecoder()
do {
let items = try decoder.decode([Composition].self, from: data)
complete(true, items, nil)
} catch {
complete(true, [Composition](), APIError.unknownError(error.localizedDescription))
}
}
}
func insertComposition(composition: Composition) {
try! realm.write {
print("Starting storing...")
// Composition
let compositionEntity = Composition()
compositionEntity.id = composition.id
compositionEntity.caseID = composition.caseID
compositionEntity.name = composition.name
compositionEntity.price = composition.price
// DefaultItem
let defaultItems = composition.items
defaultItems.forEach({ (i) in
print(i.categoryID) // print nothing
})
defaultItems.forEach({ item in
let newItem = DefaultCompositionItem()
newItem.itemID = item.itemID
newItem.categoryID = item.categoryID
newItem.compositionID = item.compositionID
newItem.count = item.count
compositionEntity.items.append(newItem)
})
realm.add(compositionEntity)
}
}
领域对象Composition
:
final class Composition:Object, Decodable {
@objc dynamic var id: Int = 0
@objc dynamic var name: String = ""
@objc dynamic var caseID: Int = 0
@objc dynamic var price: Double = 0.0
let items = List<DefaultCompositionItem>()
override static func primaryKey() -> String? {
return "id"
}
private enum RootKeys: String, CodingKey {
case DefaultCompositionItem
case Serial
case Name
case CaseId = "Case_Id"
case Price
}
convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: RootKeys.self)
id = try container.decode(Int.self, forKey: .Serial)
name = try container.decode(String.self, forKey: .Name)
caseID = try container.decode(Int.self, forKey: .CaseId)
price = try container.decode(Double.self, forKey: .Price)
if let itemArray = try container.decodeIfPresent(List<DefaultCompositionItem>.self, forKey: .DefaultCompositionItem) {
items.append(objectsIn: itemArray)
}
}
}
final class DefaultCompositionItem:Object, Decodable {
@objc dynamic var itemID: Int = 0
@objc dynamic var categoryID: Int = 0
@objc dynamic var compositionID: Int = 0
@objc dynamic var count: Int = 0
private enum ItemKeys: String, CodingKey {
case Serial
case CategoryId = "Category_Id"
case CompositionId = "Composition_Id"
case Count
}
override static func primaryKey() -> String? {
return "itemID"
}
convenience init(from decoder: Decoder) throws {
self.init()
let itemContainer = try decoder.container(keyedBy: ItemKeys.self)
itemID = try itemContainer.decode(Int.self, forKey: .Serial)
categoryID = try itemContainer.decode(Int.self, forKey: .CategoryId)
compositionID = try itemContainer.decode(Int.self, forKey: .CompositionId)
count = try itemContainer.decode(Int.self, forKey: .Count)
}
}
extension List: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
}
}
问题是您分配给 Composition
的 items
属性 而不是像需要的那样改变它。 Realm's documentation explicitly calls out List<T>
属性应该使用 let
而不是 var
来声明以避免这个问题。
将 items
更改为使用 let
声明,然后通过 修改 现有的 items
值而不是分配给它。
我还建议解码为 DefaultCompositionItem
的数组,而不是 List<DefaultCompositionItem>
,因为 List<T>
对 Swift 的 Decodable
一无所知.