2014-07-15 13 views
23

Mam klasy NSManagedObjectJak przypisać w Swift relację wiele-do-wielu CoreData?

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

Jak mogę dodać nową relację dogBreed? Jeśli zmienię typ var na NSMutableSet, zmiany nie zostaną zapisane w bazie danych. Jakieś pomysły?

+0

więcej informacji http://stackoverflow.com/questions/24146524/setting-an-nsmanagedobject-relationship-in-swift – DogCoffee

+0

Dla innych, które znajdują na to pytanie, ponieważ chcą nauczyć się wykorzystywać relacje w danych Core , w końcu znalazłem ten samouczek: [Core Data and Swift: Relationships and More Fetching] (http://code.tutsplus.com/tutorials/core-data-and-swift-relationships-and-more-fetching--cms- 25070) – Wraithbone

Odpowiedz

20

Od Xcode 7 i Swift 2.0, release note 17583057 stany:

Atrybut NSManaged można stosować metod, jak również właściwości, za dostęp do Rdzeń danych automatycznie generowane kluczykowy Zgodny z kodami wartości do wielu akcesorów.

@NSManaged var employees: NSSet 

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

Te mogą być zadeklarowane w swojej podklasy NSManagedObject.(17583057)

Więc po prostu trzeba zadeklarować następujące metody i CoreData zajmie się resztą:

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

Dzięki za to! + 100 – DogCoffee

+1

Może to być dziwne i spóźnione, ale jak Swift wie, jak zająć się resztą? Nie określasz, do którego zestawu należy dodać funkcje? – Emptyless

+2

@ Emptyless Ma to niewiele wspólnego z Swift. Te metody są generowane przez CoreData, jest to klasa NSManaged, która faktycznie się nią zajmuje. Powyższe odpowiedzi wyjaśniają tylko właściwy sposób, aby to zrobić za pomocą Swift. To dość podobne do deklarowania IBOutletów w UIViewControllerach, a ty pytasz, jak Swift wie, jak połączyć to ze Storyboard (to nie jest Swift, to UIKit). – Nycen

18

Swift nie może generować dynamicznych programów wykonawczych ze względu na ścisły system typów. Można utworzyć rozszerzenie Disease klasy i dodać nieodebranych metod ręcznie, oto kod:

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

Uwagi:

Proponuję, aby utworzyć osobny plik dla rozszerzenia Disease+CoreData.swift, powinno to pomóc w utrzymaniu Twój kod został nadpisany, gdy ponownie wygenerujesz model CoreData.

Wystarczy utworzyć relację w jednym z obiektów zarządzanych, a drugi zostanie zaktualizowany z powrotem. (Tak samo jak w Objective-C). Na przykład. MyProjectName.Disease

Odpowiedź zainspirowany: Setting an NSManagedObject relationship in Swift

+1

Zauważyłem, że ten kod nie zadziała dla mojej aplikacji bez zawijania procesu ustawiania we właściwym kodzie obserwacji wartości klucza, do odrobiny self.willChangeValueForKey ("key", withSetMutation: , usingObjects: ) i odpowiednią metodę didChangeValueForKey. Bez tego zgłaszano wszelkiego rodzaju dziwne i pozornie niepowiązane błędy. – Ash

+0

Dobra uwaga. Przetestuję twoją sugestię i dodaję odpowiedź po powrocie do mojego pulpitu programisty. – Keenle

10

Jeśli szukasz prostego podejścia po prostu używać.

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

Realizacja:

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

Zamiast pisać tę samą metodę w każdej klasie NSManageObject że potrzebuje.

+0

Ah ha - Podoba mi się to rozwiązanie. Schludny. –

2

Jako rozszerzenie @Naz. I w połączeniu z komentarzem @ Ash. Znalazłem tylko roztwór roboczy dla Xcode 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>) 
    } 
} 

Trzeba wezwać willChange i koparki didChange aby poprawnie dodać obiekt do relacji do wielu w Swift.

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

Właściwie można po prostu napisać:

@NSManaged var dogBreed: Set<DogBreed> 

i użyj insert i remove metody bezpośrednio od .

2

@Nycen ma najlepsze rozwiązanie dla Xcode 7 z automatycznie realizowanych metodami jednak pamiętać, że niemal niewiarygodnie NSOrderedSet problem nadal istnieje (patrz this question), więc jeśli przy użyciu NSOrderedSet dla relacji zamiast NSSet będzie jeszcze trzeba użyć obejścia.

(bym skomentował zamiast pisać nową odpowiedź, jednak brakuje mi w punktach)

+0

Nie mogę uwierzyć, że to nadal jest błąd. Może za jakiś tydzień naprawią to na WWDC. –

1

Jeśli trzeba użyć NSOrderedSet zamiast NSSet, Używam następujący kod, który sprawia, że ​​łatwiej aby uzyskać metody dodawania, wstawiania i usuwania obiektów.

@NSManaged private var myOrderedSet: NSOrderedSet 

var myMutableOrderedSet: NSMutableOrderedSet { 
    return self.mutableOrderedSetValueForKey("myOrderedSet") 
} 
Powiązane problemy