【问题标题】:restrict sqlite-wal and sqlite-shm from icloud backup从 icloud 备份中限制 sqlite-wal 和 sqlite-shm
【发布时间】:2015-08-20 08:40:08
【问题描述】:

我是第一次使用 coredata,我必须从文档目录中的 iCloud 备份中限制 sqlite db 文件,我使用以下代码完成了它

-(id)init
{
    if((self = [super init]))
    {
        NSURL* documentsDirectoryURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        NSURL* modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
        NSURL* giveForwardSqliteURL = [documentsDirectoryURL URLByAppendingPathComponent:@"InfoCollection.sqlite"];
        NSError* error;

        m_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
        m_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:m_managedObjectModel];

        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];


        if ([m_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:giveForwardSqliteURL options:options error:&error])
        {
            m_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
            [m_managedObjectContext setPersistentStoreCoordinator:m_persistentStoreCoordinator];

            [self addSkipBackupAttributeToItemAtPath:giveForwardSqliteURL];
        }
        else
        {
            NSLog(@"Failed to create or open database: %@", [error userInfo]);
            return nil;
        }
    }

    return self;
}

//防止iCloud备份文档目录文件夹

- (BOOL)addSkipBackupAttributeToItemAtPath:(NSURL *) URL
{
    assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);

    NSError *error = nil;
    BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
                              forKey: NSURLIsExcludedFromBackupKey error: &error];
    if(!success){
        NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
    }
    return success;
}

现在我不明白的是,我们是否还需要限制来自 icloud 备份的 sqlite-wal 和 sqlite-shm 文件,如果是,那么 如何限制来自 icloud 备份的 sqlite-wal 和 sqlite-shm 文件

我想要一个解决方案,而不需要从文档目录文件夹中更改 sqlite db 位置......我们该怎么做

以上代码如有错误请指正

提前致谢

【问题讨论】:

  • 如果我们需要跳过它们,为 walshm 文件创建 URL 并将它们传递给添加跳过属性方法应该非常简单。问题是我们是否需要这样做,如果是,何时因为这些文件可能不会在创建持久存储时创建。此外,WAL 日志会定期合并到主数据库中并重新创建等。我们如何跟踪这些更改?
  • @lukya 我不知道该做什么以及如果我这样离开会发生什么......所以我添加了这些行'if ([[NSFileManager defaultManager] fileExistsAtPath:[sqliteShmURL path ]]) { [self addSkipBackupAttributeToItemAtPath:sqliteShmURL]; } if ([[NSFileManager defaultManager] fileExistsAtPath:[sqliteWalURL path]]) { [self addSkipBackupAttributeToItemAtPath:sqliteWalURL]; }'
  • hmm.. 很奇怪.. 我想我会得到很多参考资料... 但令人惊讶的是,没有任何地方对此进行讨论... 我已经开始对这个问题进行赏金。让我们看看是否有任何有效的答案出现......
  • 即使在开始赏金之后也没有活动。我想这个问题没有真正的答案。
  • 我添加了question on apple developer forums。如果出现任何有用的信息,将更新此帖子。

标签: ios sqlite core-data icloud


【解决方案1】:

我想要一个解决方案,而无需更改 sqlite db 位置 文件目录文件夹...我们该怎么做

首先,确保您已阅读 this 以确定放置文件的正确目录。

其次,不要拘泥于将它们直接放入文档目录。通常,将每个文件直接填充到 Documents 目录中并不是一个好主意。相反,您应该使用目录层次结构对数据进行逻辑分区。

接下来,请注意,如果您从备份中排除某个目录,该目录中的所有文件也将被排除。

因此,如果您愿意灵活一些并遵循上述建议,您可以简单地将文档目录的子目录用于您的核心数据数据库。

NSURL* giveForwardDirURL = [documentsDirectoryURL URLByAppendingPathComponent:@"InfoCollection.dir"];
[[NSFileManager defaultManager] createDirectoryAtURL:giveForwardDirURL
                         withIntermediateDirectories:YES
                                          attributes:nil
                                               error:NULL];
[self addSkipBackupAttributeToItemAtPath:giveForwardDirURL];

NSURL* giveForwardSqliteURL = [giveForwardDirURL URLByAppendingPathComponent:@"InfoCollection.sqlite"];

但是,如果您坚持让文件驻留在目录中,则必须在初始化时搜索它们,然后您必须在应用运行时监控目录,以便您可以设置标志 if/when相关文件出现。

此线程包含与此相关的信息:Notification of changes to the iPhone's /Documents directory

【讨论】:

  • 将 sqlite 和相关文件放在子目录中是我采用的最后一种方法(大约一个月前)。所以你的解决方案是对的。但是,我正在寻找一些有关 -wal 和 -shm 文件创建和跟踪的官方文档。如果没有其他结果,我可能会奖励你。
  • kqueue 实现来跟踪文档目录更改,如您共享的链接中所述,排除 -wal 和 -shm 文件似乎有点过头了。子目录方法肯定要好得多。但是,因为我还没有找到跟踪这些文件的正确方法,所以我觉得我逃避了一个问题,因为我找不到正确的解决方案。
  • 如果这是您采用的解决方案,那么您并没有逃避问题,而是解决了问题。将 Core Data 数据库放在其自己的子目录中是正确的解决方案,而且 IMO 应该始终这样做,除非有很好的理由不这样做(这也使得核对整个数据库和所有临时文件非常容易)。如果您想要的只是临时文件的文档,那么它就在这里:sqlite.org/tempfiles.html。但是,请注意,即使 SQLite 的作者也声明这些信息是信息性的,并且不保证将来会继续以这种方式工作。
  • 是的.. 这是一个非常好的解决方案,但如果我能找到一种方法来正确跟踪和标记临时文件并决定不去,我会感觉更舒服(关闭)使用它,因为子目录方法更容易/更好......我已经阅读了临时文件文档,但就像你说的那样非正式,并且没有给我一个很好的跟踪这些文件的命令。
【解决方案2】:

您可以强制 Core Data 使用回滚日志模式,阻止 -shl 和 -wal 文件,方法是在 -[NSPersistentStoreCoordinator addPersistentStore…] 调用中添加选项字典,就像在这个答案中一样:

https://stackoverflow.com/a/24261845/453082

【讨论】:

  • 我现在,但它是一种变通方法,首先防止创建 -shl 和 -wal 文件。最终结果是相同的 - 不会备份此类文件。
  • 我不同意。预期的最终结果是应该创建 -wal 和 -shm 文件但不备份到 iCloud。不允许创建文件与不备份它们有很大不同。 WAL 日志模式有一些优势。
猜你喜欢
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 2011-12-08
  • 2018-02-11
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多