Как назначить отношения CoreData "многие ко многим" в Swift?
У меня есть класс NSManagedObject
class Disease: NSManagedObject {
@NSManaged var diseaseId: String
@NSManaged var diseaseName: String
@NSManaged var dogBreed: NSSet
}
Как добавить новое отношение к dogBreed? Если я изменяю тип var на NSMutableSet, изменения не сохраняются в базе данных. Любые идеи?
Ответы
Ответ 1
Как и в Xcode 7 и Swift 2.0, в примечании к выпуску 17583057 говорится:
Атрибут NSManaged может использоваться как с методами, так и с свойства, для автоматического доступа к базовым Datas Ключ-кодирование, совместимый со многими аксессуарами.
@NSManaged var employees: NSSet
@NSManaged func addEmployeesObject(employee: Employee)
@NSManaged func removeEmployeesObject(employee: Employee)
@NSManaged func addEmployees(employees: NSSet)
@NSManaged func removeEmployees(employees: NSSet)
Они могут быть объявлены в вашем подклассе NSManagedObject. (17583057)
Итак, вам просто нужно объявить следующие методы, и CoreData позаботится об остальном:
@NSManaged func addDogBreedsObject(dogBreed: DogBreed)
@NSManaged func removeDogBreedsObject(dogBreed: DogBreed)
@NSManaged func addDogBreeds(dogBreeds: NSSet)
@NSManaged func removeDogBreeds(dogBreeds: NSSet)
Ответ 2
Swift не может генерировать динамические аксессоры времени выполнения из-за строгой системы типов. Вы можете создать расширение класса Disease
и вручную добавить пропущенные методы, вот код:
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)
}
}
Примечания:
Я предлагаю вам создать отдельный файл для расширения Disease+CoreData.swift
. Это должно помочь сохранить код от переопределения при повторной генерации модели CoreData
.
Достаточно создать отношения в одном из управляемых объектов, второй - с обратной ссылкой. (То же, что было с Objective-C)
Важно: Чтобы все это работало, вы должны убедиться, что имена классов объектов в вашей модели CoreData содержат имя вашего модуля. Например. MyProjectName.Disease
Ответ, вдохновленный: Настройка отношения NSManagedObject в Swift
Ответ 3
Если вы ищете простой подход, просто используйте это.
import CoreData
extension NSManagedObject {
func addObject(value: NSManagedObject, forKey: String) {
var items = self.mutableSetValueForKey(forKey);
items.addObject(value)
}
}
Реализация:
department.addObject(section, forKey: "employees")
Вместо того, чтобы писать один и тот же метод для каждого класса NSManageObject, который ему нужен.
Ответ 4
На самом деле вы можете просто написать:
@NSManaged var dogBreed: Set<DogBreed>
И используйте методы insert
и remove
Set
напрямую.
Ответ 5
Как расширение для @Naz. И в сочетании с комментарием @Ash. Я нашел единственное рабочее решение для 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>)
}
}
Вам нужно вызвать обработчики willChange и didChange, чтобы правильно добавить объект в отношение ко многим во Swift.
myManagedObject.addObject(value, forKey: "yourKey")
Ответ 6
@Nycen имеет лучшее решение для Xcode 7 с теперь автоматически реализованными методами, однако обратите внимание, что проблема NSOrderedSet
почти невероятно все еще существует (см. этот вопрос), поэтому, если вы используете NSOrderedSet
для своих отношений вместо NSSet
, вам все равно придется использовать обходной путь.
(Я бы прокомментировал вместо публикации нового ответа, однако мне не хватает точек)
Ответ 7
Если вам нужно использовать NSOrderedSet
вместо NSSet
, я использовал следующий код, который упрощает доступ к методам NSMutableOrderedSet
для добавления, вставки и удаления объектов.
@NSManaged private var myOrderedSet: NSOrderedSet
var myMutableOrderedSet: NSMutableOrderedSet {
return self.mutableOrderedSetValueForKey("myOrderedSet")
}