许多关系如何运作。

时间:2017-04-15 01:08:59

标签: ios core-data swift3

好的,我读过苹果Core Data Guide。我也在网上看,但大约2年前才找到帖子。所以我不知道有多少关系工作。我正在使用核心数据构建应用。该应用有3个实体 宠物小精灵 类型 能力 。口袋妖怪可以有1种或更多类型,所以我将关系设置为to-many。一个类型可以有多个与之关联的Pokemon,所以我也应该将关系设置为to-many但我不理解多对多关系。能力也是如此。这就是我的数据模型的样子。还有另外两个实体,但我现在并不关心这些实体。

enter image description here

这是我用来解析以下API的函数。它抓住前20个口袋妖怪保存名称并使用url获取有关该口袋妖怪的更多信息。所以我添加了另一项任务,为该口袋妖怪增加了类型和能力。

private func loadPokemon(url: String) {
    let context = coreData.persistentContainer.viewContext
    let request = URLRequest(url: URL(string: url)!)
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        if error != nil {
            print(error!)
        }

        do {
           let jsonResults = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
            let pokemonArray = jsonResults.value(forKey: "results") as! [[String: Any]]

            for pokemonData in pokemonArray {

                guard let name = pokemonData["name"] as? String else {
                    return
                }

                guard let pokemonInfoURL = pokemonData["url"] as? String else {
                    return
                }

                let pokemon = Pokemon(context: context)
                pokemon.name = name
                print(1)

                self.pokemonMoreInfo(for: pokemon, url: pokemonInfoURL, context: context)

            }
        }
        catch let err {
            print(err.localizedDescription)
        }
    }
    task.resume()
}

private func pokemonMoreInfo(for pokemon: Pokemon, url: String, context: NSManagedObjectContext) {
    let request = URLRequest(url: URL(string: url)!)
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        if error != nil {
            print(error!)
        }

        do {
            let jsonResults = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary


            //MARK: Pokemon Abilities
            if let abilityArray = jsonResults.value(forKey: "abilities") as? [[String: Any]] {
                let abilities = pokemon.ability?.mutableCopy() as! NSMutableSet

                for abilityData in abilityArray {

                    guard let abilityDic = abilityData["ability"] as? NSDictionary else {
                        return
                    }
                    let name = abilityDic.value(forKey: "name") as! String

                    guard let isHidden = abilityData["is_hidden"] as? Bool else {
                        return
                    }

                    guard let slot = abilityData["slot"] as? Int16 else {
                        return
                    }

                    let ability = Ability(context: context)
                    ability.name = name
                    ability.isHidden = isHidden
                    ability.slot = slot

                    abilities.add(ability)
                    pokemon.addToAbility(abilities)
                }
            }

            //MARK: Pokemon Type
            if let typeArray = jsonResults.value(forKey: "types") as? [[String: Any]] {
                let types = pokemon.type?.mutableCopy() as! NSMutableSet

                for typeData in typeArray {

                    guard let typeDic = typeData["type"] as? NSDictionary else {
                        return
                    }
                    let name = typeDic.value(forKey: "name") as! String

                    guard let slot = typeData["slot"] as? Int16 else {
                        return
                    }

                    let type = Type(context: context)
                    type.name = name
                    type.slot = slot

                    types.add(type)
                    pokemon.addToType(types)
                }
            }
        }
        catch let err {
            print(err.localizedDescription)
        }
        self.coreData.saveContext()
    }
    task.resume()
}

我正在使用这个名为SQLight Read-Only的应用程序。能力和类型与正确的口袋妖怪相匹配。这些是关于我的SQLight外观的截图。

enter image description here

我不确定你们是否知道口袋妖怪,但是charizard类型是 fire 飞行 并具有 太阳能 blaze 的能力。所以我知道我正确地保存了数据。但是我的SQLight有类似的重复类型,如 fire grass 毒药 相同的功能,但与正确的口袋妖怪相关联。这就是我完整的SQLight的样子。

enter image description here

不确定它是否会继续与多对多关系重复。所以我的问题是我如何使用 宠物小精灵 类型 能力 即可。那么我如何添加具有相同类型或相同能力的口袋妖怪。所以后来,我可以执行一次抓取,抓住所有具有火力或相同能力的口袋妖怪。我不确定我是否正确解释了我的问题可能会有点混乱。

非常感谢任何帮助。 :)

1 个答案:

答案 0 :(得分:0)

修改 实际上我在下面写的内容对于Core Data来说并不正确。 (感谢你在评论Paulw11中指出这一点。)来自Core Data Guide

  

多对多关系

     

使用两对多关系定义多对多关系。第一个到多个关系从第一个实体(源实体)到第二个实体(目标)。第二对多关系从第二实体(原始目标实体)到第一实体(原始源实体)。然后将每个设置为另一个的倒数。 (如果您有数据库管理的背景,这引起您的关注,请不要担心:如果您使用SQLite存储,Core Data会自动为您创建中间连接表。)

旧答案(核心数据不正确): 要在关系数据库中创建多对多关系,您必须添加一个帮助程序表。在你的情况下,你可以称之为PokemonWithType。它有两列,一列用于Pokemon id,另一列用于Type id。如果你想找到一个特定口袋妖怪的所有类型,你只需要查询PokemonWithType中具有特定口袋妖怪id的所有条目。如果你想找到所有具有特定类型的口袋妖怪,你只需要使用类型ID。