2014-07-15 4 views
23

Ich habe eine NSManagedObject KlasseWie wird die CoreData-N-Beziehung in Swift zugewiesen?

class Disease: NSManagedObject { 
    @NSManaged var diseaseId: String 
    @NSManaged var diseaseName: String 
    @NSManaged var dogBreed: NSSet 
} 

Wie kann ich eine neue Beziehung zu dogbreed hinzufügen? Wenn ich den var-Typ in NSMutableSet ändere, werden die Änderungen nicht in der Datenbank gespeichert. Irgendwelche Ideen?

+0

weitere Informationen http://stackoverflow.com/questions/24146524/setting-an-nsmanagedobject-relationship-in-swift – DogCoffee

+0

Für andere, die diese Frage zu finden, weil sie lernen wollen, wie die Beziehungen zu verwenden, in Core Data , fand ich schließlich dieses Tutorial: [Core Data and Swift: Beziehungen und mehr Abrufen] (http://code.utsplus.com/tutorials/core-data-and-swift-relationships-and-more-fetching-cms-- 25070) – Wraithbone

Antwort

20

Ab Xcode 7 und Swift 2.0, die release note 17.583.057 Zustände:

Das NSManaged Attribut kann sowie Eigenschaften mit Methoden verwendet werden, für den Zugriff auf die Stammdaten automatisch generiert Key- Value-Coding-konform zu vielen Accessoren.

@NSManaged var employees: NSSet 

@NSManaged func addEmployeesObject(employee: Employee) 
@NSManaged func removeEmployeesObject(employee: Employee) 
@NSManaged func addEmployees(employees: NSSet) 
@NSManaged func removeEmployees(employees: NSSet) 

Diese können in Ihrem NSManagedObject Unterklasse deklariert werden.(17583057)

So einfach haben Sie die folgenden Methoden zu erklären und Coredata wird der Rest kümmern:

@NSManaged func addDogBreedsObject(dogBreed: DogBreed) 
@NSManaged func removeDogBreedsObject(dogBreed: DogBreed) 
@NSManaged func addDogBreeds(dogBreeds: NSSet) 
@NSManaged func removeDogBreeds(dogBreeds: NSSet) 
+1

Danke dafür! + 100 – DogCoffee

+1

Das mag seltsam und spät sein, aber wie weiß Swift, wie er sich um den Rest kümmert? Sie geben nicht an, welchen Satz die Funktionen hinzufügen müssen? – Emptyless

+2

@Emptyless Das hat wenig mit Swift zu tun. Diese Methoden werden von CoreData generiert, es ist die NSManaged-Klasse, die sich darum kümmert. Die obigen Antworten erklären nur den richtigen Weg, dies mit Swift zu tun. Es ist ziemlich ähnlich, IBOutlets in UIViewControllers zu deklarieren, und du fragst, wie Swift das mit dem Storyboard verbinden kann (es ist auch nicht Swift, es ist UIKit) – Nycen

18

Swift kann aufgrund des strikten Typsystems keine dynamischen Laufzeitaccessoren generieren. Sie können eine Erweiterung Disease Klasse erstellen und verpasste Methoden manuell hinzufügen, hier ist der Code:

extension Disease { 
    func addDogBreedObject(value:DogBreed) { 
     var items = self.mutableSetValueForKey("dogBreed"); 
     items.addObject(value) 
    } 

    func removeDogBreedObject(value:DogBreed) { 
     var items = self.mutableSetValueForKey("dogBreed"); 
     items.removeObject(value) 
    } 
} 

Bemerkungen:

ich Sie vorschlagen, für die Erweiterung Disease+CoreData.swift separate Datei zu erstellen, Dies sollte halten helfen Ihr Code wird überschrieben, wenn Sie das Modell CoreData neu generieren.

Es reicht aus, eine Beziehung in einem der verwalteten Objekte zu erstellen, die zweite wird mit der Rückreferenz aktualisiert. (Das gleiche wie war mit Objective-C)

Wichtig: Um es alle arbeiten Sie, dass Klassennamen von Entitäten in Ihnen überprüfen sollen Coredata-Modell Ihre Modulnamen enthalten. Z.B. MyProjectName.Disease

Antwort inspiriert von: Setting an NSManagedObject relationship in Swift

+1

Ich habe festgestellt, dass dieser Code für meine App nicht funktionieren würde, ohne den Setting-Prozess in den richtigen Schlüsselwert-Beobachtungscode einzubinden, mit self.willChangeValueForKey ("Schlüssel", mitSetMutation: , usingObjects: ) und die entsprechende didChangeValueForKey-Methode. Ohne dies wurden alle möglichen seltsamen und scheinbar unverwandten Fehler gemeldet. – Ash

+0

Guter Punkt. Ich werde deinen Vorschlag testen und zur Antwort hinzufügen, wenn ich wieder auf meinem Entwickler-Desktop bin. – Keenle

10

Wenn Sie schauen, dies nur für einen einfachen Ansatz.

import CoreData 
extension NSManagedObject { 
    func addObject(value: NSManagedObject, forKey: String) { 
     var items = self.mutableSetValueForKey(forKey); 
     items.addObject(value) 
    } 
} 

Die Umsetzung:

department.addObject(section, forKey: "employees") 

Statt die gleiche Methode auf jeder NSManageObject Klasse zu schreiben, die er braucht.

+0

Ah ha - Ich mag diese Lösung. Ordentlich. –

2

Als Erweiterung zu @Naz. Und in Kombination mit @ Ashs Kommentar. Ich habe die einzige funktionierende Lösung für xCode gefunden 6.3.1

import CoreData 

extension NSManagedObject { 
    func addObject(value: NSManagedObject, forKey: String) { 
     self.willChangeValueForKey(forKey, withSetMutation: NSKeyValueSetMutationKind.UnionSetMutation, usingObjects: NSSet(object: value) as Set<NSObject>) 
     var items = self.mutableSetValueForKey(forKey); 
     items.addObject(value) 
     self.didChangeValueForKey(forKey, withSetMutation: NSKeyValueSetMutationKind.UnionSetMutation, usingObjects: NSSet(object: value) as Set<NSObject>) 
    } 
} 

Sie haben die willchange und didChange Handler aufrufen, um richtig ein Objekt in eine n-Beziehung in Swift hinzuzufügen.

myManagedObject.addObject(value, forKey: "yourKey") 
4

Eigentlich kann man nur schreiben:

@NSManaged var dogBreed: Set<DogBreed> 

und verwenden Sie die insert und remove Methoden der Set direkt.

2

@Nycen hat die beste Lösung für Xcode 7 mit den nun automatisch implementierten Methoden, aber beachten Sie, dass die NSOrderedSet Ausgabe fast unglaublich noch existiert (siehe this question), so dass, wenn eine NSOrderedSet für Ihre Beziehung anstelle eines NSSet können Sie Zeit noch müssen einen Workaround verwenden.

+0

Ich kann nicht glauben, dass dies immer noch ein Fehler ist. Vielleicht werden sie es in einer Woche auf der WWDC reparieren. –

1

Wenn Sie ein NSOrderedSet statt NSSet, ich habe mit dem folgenden Code, die es leichter macht verwenden müssen (ich hätte statt der Entsendung eine neue Antwort, aber ich fehle in Punkten kommentiert) um die NSMutableOrderedSet Methoden zum Hinzufügen, Einfügen und Entfernen von Objekten zu erhalten.

@NSManaged private var myOrderedSet: NSOrderedSet 

var myMutableOrderedSet: NSMutableOrderedSet { 
    return self.mutableOrderedSetValueForKey("myOrderedSet") 
}