问题:
无法从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
答案 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];
}