2017-04-15 6 views
0

Okay, ich habe gelesen Apple Core Data Guide. Ich schaue auch im Internet nach, finde aber vor etwa 2 Jahren nur Posts. Also ich weiß nicht, wie viele zu viele Beziehungsarbeit. Ich baue eine App mit Kerndaten. Die App verfügt über 3 Einheiten Pokemon, Typ, Fähigkeit. Ein Pokémon kann einen oder mehrere Typen haben, also setze ich die Beziehung auf to-many. Einem Typ können mehrere Pokémon zugeordnet sein, daher sollte ich die Beziehung auch auf "Viele" setzen, aber ich verstehe keine Viele-zu-Viele-Beziehung. Gleiches gilt für die Fähigkeiten. So sieht mein Datenmodell aus. Es gibt noch zwei weitere Entitäten, aber im Moment interessieren mich diese nicht wirklich.Wie funktionieren viele zu viele Beziehungen?

enter image description here

Dies ist die Funktion, die ich die folgenden API analysieren bin mit. Es ergreift die ersten 20 Pokemon speichert den Namen und verwendet die URL, um weitere Informationen über dieses Pokemon zu holen. Also habe ich eine weitere Aufgabe hinzugefügt, die dem Pokémon den Typ und die Fähigkeit hinzufügt.

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() 
} 

Ich benutze diese App namens SQLight Read-Only. Die Fähigkeit und der Typ stimmen mit dem richtigen Pokémon überein. Dies sind Screenshots, wie meine SQLight aussieht.

enter image description here

Ich bin nicht sicher, ob ihr über Pokemon wissen, aber charizard Typ ist Feuer und und haben die Fähigkeiten von Solarstrom fliegen und blaze. Ich weiß also, dass ich die Daten richtig speichere. Allerdings hat mein SQLight die gleiche Art wie Feuer Wiederholung, Gras, Gift gleiche gilt für die Fähigkeiten geht aber mit dem richtigen Pokemon mit ihnen verbunden ist. So sieht mein komplettes SQLight aus.

enter image description here

Nicht sicher, ob es mit einer many-to-many-Beziehung zu wiederholen halten. Also meine Frage ist, wie würde ich eine many-to-many verwenden Beziehung mit Pokemon zu Typ und Fähigkeit. Also, wie würde ich ein Pokemon mit dem gleichen Typ oder den gleichen Fähigkeiten hinzufügen? So später kann ich einen Hol durchführen, der alle Pokémon schnappt, die eine Art Feuer oder die gleiche Fähigkeit haben. Ich bin mir nicht sicher, ob ich meine Frage richtig erklärt habe, könnte ein wenig verwirrend sein.

Würde mich über jede Hilfe freuen. :)

+0

Core Data ist ein Objektpersistenzsystem, keine SQL-Datenbank. Ich würde vorschlagen, dass Sie nicht versuchen, den zugrunde liegenden SQL-Datenspeicher zu analysieren. Setzen Sie die Objektreferenzen einfach in das Attribut "type" Ihres Pokemon und lassen Sie CoreData die Referenzen aktualisieren. – Paulw11

Antwort

0

EDIT: Eigentlich was ich unten schrieb ist nicht korrekt für Core Data.(Danke für den Hinweis aus den Kommentaren Paulw11.) Aus den Core Data Guide:

Many-to-Many Beziehungen

Sie definieren eine many-to-many-Beziehung mit zwei zu-viele-Beziehungen. Die erste zu-viele-Beziehung geht von der ersten Entität (der Quellenentität) zu der zweiten Entität (dem Ziel). Die zweite to-now-Beziehung geht von der zweiten Entität (der ursprünglichen Zieleinheit) zur ersten Entität (der ursprünglichen Quellenentität). Sie stellen dann jeweils die Umkehrung der anderen ein. (Wenn Sie einen Hintergrund in der Datenbank-Management haben und dies bewirkt, dass Sie Sorge, keine Sorge. Wenn Sie einen SQLite-Speicher zu verwenden, Core Data erstellt automatisch die Zwischentabelle für Sie beitreten)


Alt Antwort (falsch für Core Data): Um eine Viele-zu-Viele-Beziehung in einer relationalen Datenbank zu erstellen, müssen Sie eine Hilfstabelle hinzufügen. In Ihrem Fall könnten Sie es PokemonWithType nennen. Es hat zwei Spalten, eine für die Pokemon-ID und eine weitere für die Type-ID. Wenn Sie alle Typen für ein bestimmtes Pokémon finden möchten, fragen Sie einfach alle Einträge in PokemonWithType mit der spezifischen Pokémon-ID ab. Wenn du alle Pokémon finden möchtest, die einen bestimmten Typ haben, machst du das Gleiche mit der Typ-ID.

+0

Hey Benjamin, Können Sie einen Screenshot oder Beispielcode bereitstellen? Würde es schätzen, wenn Sie können. :) –

+0

CoreData unterstützt viele-zu-viele Beziehungen direkt. Obwohl es von SQLite unterstützt werden kann, ist es ein Objekt-Persistenz-System, keine Datenbank. – Paulw11

+0

Wahr. Ich habe meine Antwort korrigiert. @Luis - Du musst die Zu-Viele-Beziehungen von Fähigkeit zu Pokémon und von Typ zu Pokémon hinzufügen. Dann sollten die benötigten Beziehungen angezeigt werden. Entschuldigung, momentan kann ich keine Screenshots bereitstellen. –

Verwandte Themen