现在我使用可解码解析JSON和存储到领域,下面是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()
}
}发布于 2018-01-10 02:12:40
问题在于,您是在分配给Composition的items属性,而不是像它那样对其进行修改。为了避免这个问题,领域的文档显式调用应该使用let而不是var来声明List<T>属性。
更改要使用items声明的let,然后通过改变items的现有值而不是分配给它来修复产生的编译错误。
我还建议对DefaultCompositionItem的数组进行解码,而不是List<DefaultCompositionItem>,因为List<T>对Swift的Decodable一无所知。
https://stackoverflow.com/questions/48179201
复制相似问题