Подтвердить что ты не робот

Как использовать Core Data ManagedObjectModel внутри рамки?

Я пытаюсь перенести определенную часть одного из моих приложений в фреймворк, чтобы я мог использовать его в самом приложении и в одном из этих новых виджетов iOS 8. Эта часть является той, которая обрабатывает все мои данные в Core Data. Это довольно прямо вперед, чтобы переместить все и получить к нему доступ. У меня просто возникают проблемы с доступом к моему файлу momd.

При создании NSManagedObjectModel я по-прежнему пытаюсь загрузить momd, как показано в шаблонах кода Apple:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

К сожалению, modelURL остается nil и, таким образом, MyApp сбой при доступе к стеку Core Data с этой ошибкой:

2014-08-01 22:39:56.885 MyApp[81375:7417914] Cannot create an NSPersistentStoreCoordinator with a nil model
2014-08-01 22:39:56.903 MyApp[81375:7417914] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'

Итак, какой правильный способ сделать это при работе внутри фреймворка с Core Data?

4b9b3361

Ответ 1

Вам нужно перетащить файл xcdatamodeld и отбросить его на этапе сборки. Скомпилируйте источники для целей, которые используют структуру. Затем, когда цель запускает свой [NSBundle mainBundle], будет содержать модель (файл momd).

Ответ 2

Я немного опаздываю на проблему с пламя, но, надеюсь, это помогает любому другому, кто блуждает. Это можно заставить работать без необходимости выполнять script -fu для копирования ресурсов вокруг!

По умолчанию шаблон Apple Core Data дает вам примерно следующее:

lazy var managedObjectModel: NSManagedObjectModel = {
  let modelURL = NSBundle.mainBundle().URLForResource("MyCuteCoreDataModel", withExtension: "momd")!
  return NSManagedObjectModel(contentsOfURL: modelURL)!
}()

Это загрузит ваши ресурсы Core Data из основного пакета. Главное здесь: если модель Core Data загружена в структуру, файл .momd находится в этом пакете структуры. Поэтому вместо этого мы просто делаем это:

lazy var managedObjectModel: NSManagedObjectModel = {
    let sexyFrameworkBundleIdentifier = "com.heybaby.xxx"
    let customKitBundle = NSBundle(identifier: sexyFrameworkBundleIdentifier)!
    let modelURL = customKitBundle.URLForResource("MyCuteCoreDataModel", withExtension: "momd")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
}()

Это должно заставить вас работать и работать.

Кредит: https://www.andrewcbancroft.com/2015/08/25/sharing-a-core-data-model-with-a-swift-framework/

Ответ 3

@Рич Сантос был почти там. Я думаю, вам просто нужно сделать это скорее "мамой", чем "мамдом", и тогда она будет работать.

lazy var managedObjectModel: NSManagedObjectModel = {
    let modelURL = NSBundle(forClass: self.dynamicType.self).URLForResource(self.dataModelName, withExtension: "mom")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
}()

Ответ 4

Возможно, я немного опоздаю с ответом на это, но вот что решило мою проблему:

С моей картой я поставляю также пакет с ресурсами, такими как изображения и другие вещи. Ввод файла xcdatamodeld там не дал ничего, поскольку этот файл создается с проектом, и в результате вы получаете папку momd в своем комплекте приложений (чего фактически не хватает в наш случай).. Я создал другую цель, а не фреймворк, но приложение, построил ее и скопировал momd из своего пакета приложений в свой отдельный пакет в проекте (тот, который идет с фреймворком). После этого вам просто нужно изменить URL-адрес ресурса из основного пакета в новый:

// ...
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"separate_bundle" ofType:@"bundle"];
NSURL *modelURL = [[NSBundle bundleWithPath:bundlePath] URLForResource:@"your_model" withExtension:@"momd"];
// ...

Работал хорошо для меня. Единственное, что я знаю, это App Store Review, которого я еще не понял. Поэтому, если вы нашли лучшее решение, поделитесь им.

ИЗМЕНИТЬ

Нашел лучшее решение. Вы можете самостоятельно построить модель. Из Руководство по программированию основных данных:

Модель данных - это ресурс развертывания. В дополнение к деталям объекты и свойства в модели, модель, которую вы создаете в Xcode содержит информацию о диаграмме - ее расположение, цвета элементов, и так далее. Эта последняя информация не требуется во время выполнения. Модель файл скомпилирован с использованием компилятора модели momc для удаления постороннюю информацию и загрузку ресурса во время выполнения насколько это возможно. Исходный каталог xcdatamodeld скомпилирован в директорию развертывания momd, а файл источника xcdatamodel скомпилирован в файл развертывания мамы.

momc находится в /Developer/usr/bin/. Если вы хотите использовать его в своем собственные скрипты сборки, его использование - источник источника momc, где источник - путь к модели Core Data для компиляции, а назначение - путь выхода.

В разделе "/Developer/usr/bin/" они означают "/Applications/Xcode.app/Developer/usr/bin/"

Вы можете добавить script в свою целевую схему и скомпилировать это автоматически перед каждой сборкой (или после, не думайте, что это важно). Это в случае, если вы измените модель во время разработки.

Что-то вроде этого:

mkdir -p "${BUILT_PRODUCTS_DIR}/your_model_name.momd"
momc "${SRCROOT}/your_model_path/your_model_name.xcdatamodeld" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/your_bundle_name.bundle/your_model_name.momd"

Ответ 5

Ресурс модели больше не доступен через mainBundle, вам нужно использовать bundleForClass: следующим образом:

NSURL *modelURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"MyApp" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

Ответ 6

Я предполагаю, что вам нужна только модель данных.

Если это так, я считаю, что следующий метод является наиболее успешным методом копирования в файле модели данных из одного проекта в другой...

  • Удалите все текущие копии файла .xcdatamodeld, которые находятся в целевом проекте.
  • Закройте Xcode.

    Использование Finder (или строки cmd);

  • Выберите папку проекта Xcode, которая содержит исходный файл .xcdatamodeld.
  • Сделайте копию исходного файла .xcdatamodeld.
  • Переместите копию исходного файла .xcdatamodeld в целевой проект.

    Тогда...

  • Открыть Xcode.
  • Используя команду меню "Добавить файлы в > ваш проект <", найдите и добавьте копию исходного файла .xcdatamodeld в ваш проект.
  • Переименуйте исходный файл .xcdatamodeld (если необходимо) с помощью Навигатора проектов.
  • "Создайте и запустите" ваш целевой проект.

Помогает ли это?

Ответ 7

Если вы попытаетесь получить основные данные в своей структуре, сделайте это.

в YourFramework  - добавить новые файлы/данные ядра/модель данных...  - создать все объекты....

При создании нового проекта, который будет использовать YourFramework, убедитесь, что данные ядра находятся на Использовать основные данные: На

Это создаст всю плиту котла внутри AppDelegate.

в тестовом проекте  - добавить Framework  - добавить Framework как встроенную инфраструктуру  - УДАЛИТЬ файл .xcdatamodeld  - в AppDelegate:

изменить - (NSManagedObjectModel *)managedObjectModel метод на:

NSBundle * testBundle = [NSBundle bundleWithIdentifier:@"YourFramework bundle id "];

NSURL *modelURL = [testBundle URLForResource:@"Model" withExtension:@"momd"];

где YourFramework bundle id - идентификатор Bundle YourFramework (в общем/идентификатор пакета)

и Model - это имя вашего файла .xcdatamodeld в YourFramework

Это работает.

Надеюсь, что это поможет.