Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign CoreData many-to-many relationship in Swift?

Tags:

I have a NSManagedObject class

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

How do I add a new relationship to dogBreed? If i change var type to NSMutableSet, the changes are not saved to database. Any ideas?

like image 595
tadasz Avatar asked Jul 15 '14 10:07

tadasz


People also ask

Is it possible to have relationship in Core Data?

Inverse relationships enable Core Data to propagate change in both directions when an instance of either the source or destination type changes. Every relationship must have an inverse. When creating relationships in the Graph editor, you add inverse relationships between entities in a single step.

Is realm easier than Core Data?

Working with Realm is much easier than with CoreData. The fact is that in order to use CoreData, you need a deep understanding of the API. In the case of Realm, everything is rather simpler. CoreData manages objects explicitly in a ManagedObjectContext which you must save when making any changes.

Is Core Data a Threadsafe?

Core Data is designed to work in a multithreaded environment. However, not every object under the Core Data framework is thread safe. To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization.

How do I use Core Data?

Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.


2 Answers

As of Xcode 7 and Swift 2.0, the release note 17583057 states:

The NSManaged attribute can be used with methods as well as properties, for access to Core Data’s automatically generated Key-Value-Coding-compliant to-many accessors.

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

These can be declared in your NSManagedObject subclass. (17583057)

So you just have to declare the following methods and CoreData will take care of the rest:

@NSManaged func addDogBreedsObject(dogBreed: DogBreed) @NSManaged func removeDogBreedsObject(dogBreed: DogBreed) @NSManaged func addDogBreeds(dogBreeds: NSSet) @NSManaged func removeDogBreeds(dogBreeds: NSSet) 
like image 181
Arnaud Avatar answered Oct 12 '22 15:10

Arnaud


Swift cannot generate dynamic runtime accessors due to strict type system. You can create an extension to Disease class and add missed methods manually, here is the 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)     } } 

Remarks:

I suggest you to create separate file for extension Disease+CoreData.swift, This should help to keep your code from overrides when you re-generate the CoreData model.

It is sufficient to create relationship in one of managed objects, second one will be updated with back reference. (Same as was with Objective-C)

Important: To make it all work you should verify that class names of entities in you CoreData model includes your module name. E.g. MyProjectName.Disease

Answer inspired by: Setting an NSManagedObject relationship in Swift

like image 27
Keenle Avatar answered Oct 12 '22 14:10

Keenle