首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储可以解码到领域,但数组总是空的。

存储可以解码到领域,但数组总是空的。
EN

Stack Overflow用户
提问于 2018-01-10 01:50:22
回答 1查看 186关注 0票数 0

现在我使用可解码解析JSON和存储到领域,下面是JSON数据

代码语言:javascript
复制
{
    "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

代码语言:javascript
复制
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

代码语言:javascript
复制
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()
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-10 02:12:40

问题在于,您是在分配给Compositionitems属性,而不是像它那样对其进行修改。为了避免这个问题,领域的文档显式调用应该使用let而不是var来声明List<T>属性。

更改要使用items声明的let,然后通过改变items的现有值而不是分配给它来修复产生的编译错误。

我还建议对DefaultCompositionItem的数组进行解码,而不是List<DefaultCompositionItem>,因为List<T>对Swift的Decodable一无所知。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48179201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档