1

Apple Watch 用のアプリを更新しています。このアプリは coredata を使用するため、Core Data スタックを管理するためのフレームワークを作成しました。デバイスまたはシミュレーターでアプリを実行すると、アプリは正常に動作しますが、Apple Watch シミュレーターで実行すると、このログでアプリがクラッシュします

*** キャッチされない例外 'NSInvalidArgumentException' が原因でアプリを終了します。理由: 'nil モデルで NSPersistentStoreCoordinator を作成できません'

問題は managedObjectModel にあるようで、ログに記録すると

NSLog(@"managedObjectModel %@", _managedObjectModel);

ログリターン

managedObjectModel (ヌル)

フレームワークのコードは正しいように見えますが、実際にはメインアプリは完全に機能します

とにかくこれはフレームワークの内容です

#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

問題はどこだ ?

ご協力ありがとうございました

4

1 に答える 1

4

現在のすべての WatchKit アプリを含む iOS アプリの拡張機能を作成する場合、独自のバンドルを使用して個別の実行可能ファイルを作成します。アプリ内のリソースが拡張機能で利用できるとは限りません。したがって、これを行うと:

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

WatchKit アプリで実行している場合と、含まれているアプリで実行している場合の URL は異なります。このエラーは、WatchKit アプリの URL が無効であること、つまり、WatchKit アプリのバンドルにモデル ファイルがないことを示しています。

簡単な修正は、モデルを WatchKit バンドルに含めることです。これを行うには:

  1. Xcode でのモデル ファイルの選択
  2. Xcode ウィンドウの右側にあるファイル インスペクター パネルを開く
  3. 「対象メンバーシップ」セクションを見てください。WatchKit ターゲットが選択されていることを確認します。

これは機能するはずですが、モデル ファイルのコピーが 2 つあることになります。より良いアプローチは、両方のターゲットが使用する共有フレームワークにモデル ファイルを配置することです。これはもう少し複雑ですが、少し検索すると詳細な手順が見つかります。

于 2015-01-05T17:54:50.720 に答える