managedObjectModel в nil (только в WatchApp)
Я обновляю приложение для Apple Watch. Это приложение использует coredata, поэтому я создал среду для управления стеком Core Data! Когда я запускаю приложение на устройстве или симуляторе, приложение работает нормально, но когда я запускаю его на симуляторе Apple Watch, происходит сбой приложения с этим журналом.
*** Завершение работы приложения из-за необработанного исключения "NSInvalidArgumentException", причина: "Невозможно создать NSPersistentStoreCoordinator с нулевой моделью"
Казалось бы, проблема заключается в managedObjectModel, и если я войду в него
NSLog(@"managedObjectModel %@", _managedObjectModel);
возврат журнала
managedObjectModel (null)
код в рамках кажется правильным на самом деле основное приложение работает отлично
в любом случае это содержание рамок
#import "DataAccess.h"
@implementation DataAccess
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
+ (instancetype)sharedInstance
{
static DataAccess *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[DataAccess alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
#pragma mark - Core Data stack
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
NSLog(@"managedObjectModel %@", _managedObjectModel);
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSLog(@"managedObjectModel %@", _managedObjectModel);
return _managedObjectModel;
}
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
//NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TMM.sqlite"];
//NSURL *storeURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSAllDomainsMask] lastObject];
// storeURL = [storeURL URLByAppendingPathComponent:@"db.sqlite"];
NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.ragazzetto.MyApp.Documents"];
storeURL = [storeURL URLByAppendingPathComponent:@"MyApp.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
@end
В чем проблема?
Спасибо за помощь
1 ответ
Когда вы пишете расширение приложения для iOS, включая все текущие приложения WatchKit, вы создаете отдельный исполняемый файл со своим собственным пакетом. Ресурсы в приложении не обязательно доступны в расширении, и наоборот. Итак, когда вы делаете это:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
При запуске в приложении WatchKit URL-адрес отличается от используемого в нем приложения. Ошибка говорит о том, что URL-адрес приложения WatchKit является недействительным, то есть, что в комплекте приложения WatchKit нет файла модели.
Простое решение состоит в том, чтобы просто включить модель в комплект WatchKit. Сделайте это путем:
- Выбор файла модели в Xcode
- Открытие панели инспектора файлов в правой части окна Xcode
- Посмотрите в разделе "Целевое членство". Убедитесь, что ваша цель WatchKit выбрана.
Это должно работать, но будет означать, что у вас есть две копии файла модели. Лучшим подходом было бы поместить файл модели в общую структуру, которую используют обе цели. Это немного сложнее, но небольшой поиск найдет подробные шаги.