2014-07-15 15 views
23

Ho una classe NSManagedObjectCome assegnare la relazione molti-a-molti CoreData in Swift?

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

Come si aggiunge un nuovo rapporto di dogBreed? Se cambio il tipo var in NSMutableSet, le modifiche non vengono salvate nel database. Qualche idea?

+0

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

+0

Per gli altri che trovano questa domanda perché vogliono imparare ad utilizzare le relazioni in Core Data , ho finalmente trovato questo tutorial: [Core Data and Swift: Relationships and More Fetching] (http://code.tutsplus.com/tutorials/core-data-and-swift-relationships-and-more-fetching--cms- 25070) – Wraithbone

risposta

20

Come di Xcode 7 e Swift 2.0, i release note 17583057 afferma:

L'attributo NSManaged può essere utilizzato con i metodi così come proprietà, per l'accesso al di Core Data generato automaticamente Key- Accessorio compatibile con la codifica del valore per molti.

@NSManaged var employees: NSSet 

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

Questi possono essere dichiarati nella sottoclasse NSManagedObject.(17583057)

quindi basta per dichiarare i seguenti metodi e CoreData si prenderà cura di tutto il resto:

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

Grazie per questo! + 100 – DogCoffee

+1

Questo potrebbe essere strano e in ritardo, ma come fa Swift a sapere come occuparsi di tutto il resto? Non si specifica a quale set devono essere aggiunte le funzioni? – Emptyless

+2

@Emptyless Questo ha poco a che fare con Swift. Questi metodi sono generati da CoreData, è la classe NSManaged che effettivamente si prende cura di esso. Le risposte sopra spiegano solo il modo corretto di farlo con Swift. È molto simile alla dichiarazione di IBOutlet in UIViewControllers e tu chiedi come Swift sa come collegarlo allo Storyboard (non è neanche Swift, è UIKit) – Nycen

18

Swift non può generare accessori di runtime dinamici a causa di un sistema di tipo rigoroso. È possibile creare una proroga per Disease classe e aggiungere metodi perse manualmente, ecco il codice:

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

Osservazioni:

vi consiglio di creare file separato per l'estensione Disease+CoreData.swift, Questo dovrebbe aiutare a mantenere il codice da sovrascrivere quando si ricrea il modello CoreData.

È sufficiente creare una relazione in uno degli oggetti gestiti, la seconda verrà aggiornata con riferimento all'indietro. (Come è stato con Objective-C)

Importante: Per far funzionare il tutto è necessario verificare che i nomi delle classi di entità in te modello CoreData include il nome del modulo. Per esempio. MyProjectName.Disease

Risposta ispirato: Setting an NSManagedObject relationship in Swift

+1

Ho trovato che questo codice non funzionava per la mia app senza avvolgere il processo di impostazione nel codice di osservazione del valore chiave appropriato, con self.willChangeValueForKey ("chiave", con SetMutation: , usingObjects: ) e il metodo didChangeValueForKey corrispondente. Senza questo sono stati riportati tutti i tipi di errori strani e apparentemente non correlati. – Ash

+0

Buon punto. Metterò alla prova il tuo suggerimento e aggiungerò alla risposta quando tornerò sul desktop di sviluppo. – Keenle

10

Se siete alla ricerca di un approccio semplice basta usare questo.

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

L'implementazione:

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

Invece di scrivere lo stesso metodo su ogni classe NSManageObject che ne ha bisogno.

+0

Ah ah - Mi piace questa soluzione. Neat. –

2

Come estensione a @Naz. E in combinazione con il commento di @ Ash. Ho trovato l'unica soluzione di lavoro per 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>) 
    } 
} 

si deve chiamare il willChange e gestori didChange al fine di aggiungere correttamente un oggetto ad un rapporto a-molti in Swift.

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

In realtà si può solo scrivere:

@NSManaged var dogBreed: Set<DogBreed> 

e utilizzare il insert e remove metodi dello Set direttamente.

2

@Nycen ha la soluzione migliore per Xcode 7 con i metodi oggi implementati automaticamente, tuttavia notare che la questione NSOrderedSet quasi incredibilmente esiste ancora (vedi this question), quindi se si utilizza un NSOrderedSet per il vostro rapporto invece di un NSSet sarà comunque è necessario utilizzare una soluzione alternativa.

(avrei commentato invece di inviare una nuova risposta, però mi manca in punti)

+0

Non posso credere che questo sia ancora un bug. Forse tra una settimana o due lo sistemeranno al WWDC. –

1

Se è necessario utilizzare un NSOrderedSet invece di NSSet, ho usato il seguente codice che rende più facile per ottenere i metodi NSMutableOrderedSet per aggiungere, inserire e rimuovere oggetti.

@NSManaged private var myOrderedSet: NSOrderedSet 

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