Создание Swift-моделей из объектов Core Data

Обновление для Xcode 8:

В Xcode 8 нужно перейти к редактору модели основных данных и отобразить "Инспектор файлов". Рядом с дном есть опция для генерации кода. Выберите Swift.

Изменить. Я нашел решение для создания модели Swift из объекта Core Data:

В Xcode:

Редактоp > Создать NSManagedOjbect > Нажмите кнопку "Далее" > Нажмите кнопку "Далее" > Выберите "Swift" Langage > Нажмите кнопку "Создать"


Я попробовал Swift langage, создав новый проект Swift на бета-версию Xcode 6 с использованием Core Data.

Когда я создаю свои модели из объектов Core Data, Xcode создает модели Objective-C.

Есть ли способ генерировать модель Swift, а не модель Obejctive-C с основными данными?

Спасибо!

Ответ 1

Давайте посмотрим на способ Objective-C:

Person.h (заголовочный файл)

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface Person : NSManagedObject
@property (nonatomic, retain) NSString *name;
@end

Person.m (файл реализации)

#import "Person.h"

@implementation Person
@dynamic name;
@end

Swift

В документации, уже включенной в Xcode6-Beta, говорится:

Core Data предоставляет базовое хранилище и реализацию свойств в подклассах класса NSManagedObject. Добавьте атрибут @NSManaged перед каждым определением свойства в подклассе управляемого объекта, который соответствует атрибуту или отношениям в вашей модели данных ядра. Как и атрибут @dynamic в Objective-C, атрибут @NSManaged информирует компилятор Swift о том, что хранение и реализация свойства будут предоставлены во время выполнения. Однако, в отличие от @dynamic, атрибут @NSManaged доступен только для поддержки Core Data.

Таким образом, я бы переписал приведенный выше пример для Swift (не тестировался):

Person.swift

import CoreData

class Person: NSManagedObject {

    @NSManaged var name : NSString

}

И по вашему вопросу, я думаю, что функция подкласса-генерации еще не включена в Xcode6. Вы убедились, что вы выбрали "Swift" в качестве языка программирования, когда вы создавали Cocoa -Project в Xcode?

Ответ 2

Вы можете вернуть модель Swift с помощью NSEntityDescription.insertNewObjectForEntityForName, но вы должны отредактировать файл модели основных данных и не использовать Person как объект класса, но <ProjectName>.Person else он возвращает NSManagedObject...

Используя println(), вы не увидите экземпляр Person, но что-то вроде <_TtC5ProjectName4Person: 0xc9ad5f0>, но вызовы методов на нем будут служить примером Person для реального. Я думаю, это просто способ для Swift генерировать уникальные имена классов, а не конфликты, а методы CoreData показывают этот внутренний механизм.

Документация Apple:

Классы Swift - это namespaced-theyre, привязанные к модулю (обычно, проект), в котором они скомпилированы. Чтобы использовать подкласс Swift класса NSManagedObject с моделью Core Data, префикс имени класса в поле Class в модели инспектор объектов с именем вашего модуля.

Ответ 3

В соответствии с видео Apple о том, что нового в кадре CoreData: 38 минут (сеанс WWDC2014), в модели данных инспектора префикс имени класса с именем проекта. Как projectName.Doctor

Я пробовал это, но произойдет то, что созданный класс управляемых объектов станет: projectName.swift вместо Doctor.swift. Даже объявление класса становится class projectName: ManagedObject

Решение:

В инспекторе модели данных просто укажите имя и класс вашего объекта, какое имя вы хотите, example: Doctor

После создания объектной модели и выбора Swift это создаст файл (Doctor.swift).

Теперь, при вставке новых записей в Core Data, вы можете столкнуться с ошибкой опыта "Класс не найден, используя по умолчанию NSManagedObject", даже если вы добавили вновь вставленный объект к правильному имени объекта.

Чтобы решить эту проблему, просто добавьте @objc (имя класса) над объявлением класса. См. Пример ниже.

import Foundation
import CoreData

@objc(Doctor)
class Doctor: NSManagedObject {
    @NSManaged var name: String
}

Тогда:

let doctorManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Doctor", inManagedObjectContext: context) as Doctor
doctorManagedObject.name = "John" // you can now use dot syntax instead of setValue

Сохранить контекст для фиксации вставки.

Ответ 4

Я тестировал @NSManaged, это не сработало.:(. Но файлы смешанных моделей (.h), сгенерированные xcdatamodel, преуспевают. пожалуйста, прочитайте документ и код в https://github.com/iascchen/SwiftCoreDataSimpleDemo

Ответ 5

В качестве альтернативы вы можете просто добавить #import "Person.h" в заголовок моста, Project-Bridging-Header.h, который генерирует Xcode для вас (если вы приняли его предложение для генерации). Затем вы можете использовать все автогенерированные Obj-C, как если бы они были родными Swift.

Ответ 6

Редактор → Создать подкласс NSManagedObject отлично работает для Swift

Просто пройдите все обычные шаги, но когда вы приступите к созданию файлов, выберите "Swift", если он в первый раз, когда вы использовали Create NSManagedObject Subclass с проектом Swift, по умолчанию будет Objective C