在iOS 8扩展中访问核心数据SQL数据库(在App和Widget扩展之间共享数据)

时间:2014-07-08 21:17:25

标签: ios iphone sqlite core-data ios-app-extension

问题:

无法从Today View中的Widget扩展中访问应用程序的Core Data数据库。

应用程序本身能够在iOS 8下按照正常情况读取和写入数据库,但扩展将无法创建存储,从而导致错误,无法写入文件。

日志如下:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)"

reason = "Failed to create file; code = 2

3 个答案:

答案 0 :(得分:69)

小部件无法访问NSDocuments目录,这是人们通常存储数据库的位置。

解决方案是首先创建一个App Group

转到: 项目 - 目标 - 应用程序组 - 添加新容器

为容器命名,即'group.mycontainer'

使用容器的相同名称重复Widget's Target的过程。

然后将数据库写入您的组容器。

所以:

NSURL *storeURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory  inDomains:NSAllDomainsMask] lastObject];
storeURL = [storeURL URLByAppendingPathComponent:@"db.sqlite"];

变为:

NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.mycontainer"];
storeURL = [storeURL URLByAppendingPathComponent:@"db.sqlite"];

初始化商店应该是这样的:

NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.mycontainer"];
storeURL = [storeURL URLByAppendingPathComponent:@"db.sqlite"];

NSPersistentStore *store = nil;
store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                  configuration:nil
                                            URL:storeURL
                                        options:nil
                                          error:&error]

答案 1 :(得分:7)

只是想通过使用标准的iOS备份程序来备份应用程序组文件。

请注意,如果您将持久存储保留在应用组容器中,则用户可能会在恢复iOS后丢失所有应用数据。

<强>更新

rdar:// 18750178

<强>更新

似乎已经在iOS 8.1中修复了,Apple的人给我发了消息并要求检查iOS 8.1中的问题是否已修复(非常不礼貌的是不是吗?)。我还没有测试过,所以请记住。无论如何,如果你支持有缺陷的iOS 8.0

,保持AppGroups中的存储是一个死的想法

答案 2 :(得分:5)

更改

[MagicalRecord setupCoreDataStackWithStoreNamed:@"Database"];

 - (void)setupCoreDataStack
{
     if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil)
     {
        return;
    }

    NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel];
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

    NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.yourgroup"];
    storeURL = [storeURL URLByAppendingPathComponent:@"Database.sqlite"];

    [psc MR_addSqliteStoreNamed:storeURL withOptions:nil];
    [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:psc];
    [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:psc];
}