防止iCloud同步数据(使用.nosync?)

时间:2011-10-14 20:48:16

标签: iphone objective-c cocoa-touch ios5

编辑:到目前为止,我能想到的最好的是一个弹出窗口,要求用户禁用iCloud同步,同时将所有数据移动到Documents目录,以便赢得'被擦除:In iOS5, is it possible to detect if a user has an app set to back up?

我为iPhone / iPad开发离线地图应用程序。

我们曾经在Caches目录中存储所有数据(可能有很多gigs)。

从iOS5开始,当用户的硬盘驱动器开满时,可以随机删除Caches目录中的文件。

如何在不将数据同步到iCloud,iTunes且没有随机删除的情况下存储本地数据?我的本地数据是一个包含许多小数据文件的大型目录树,存在于数千个子目录中。

我将目录树从库缓存目录移动到文档目录中的data.nosync目录,因为我们已经读过这可能是一个解决方案。但是,nosync文件夹中的数据仍然备份到iCloud。

现在我创建目录:

NSString* noSyncDirectory() {
  static NSString *directory = nil;
  if (!directory) {
    directory = [[NSString stringWithFormat:@"%@/%@",
                  documentsDirectory(), @"data.nosync"] retain];
    [Constants createDirectoryIfNeeded:directory];
  }
  return directory;
}

6 个答案:

答案 0 :(得分:13)

来自:https://developer.apple.com/library/ios/#qa/qa1719/_index.html

您可以使用以下方法设置“不备份”扩展属性。每当您创建不应备份的文件或文件夹时,请将数据写入文件,然后调用此方法,并将URL传递给该文件。

#include <sys/xattr.h>
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    const char* filePath = [[URL path] fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

可以找到更多信息:https://developer.apple.com/icloud/documentation/data-storage/

进一步说明:虽然开发人员文档错误地暗示(“这些文件不会被清除,也不会包含在用户的iCloud或iTunes备份中。”),请勿备份标志兼作“不做 - 不 - ”清除标志并非如此。只需将文件保留在缓存目录中并标记它们不进行备份就不会阻止它们擦除。

答案 1 :(得分:1)

此问题可能还没有解决方法......您可以尝试显式调用URLForUbiquityContainerIdentifier,因为它在第一次调用时进行了一些初始化。然后创建一个带有.nosync后缀的子目录(基于this example)。

  

第一次为给定容器目录调用此方法时,iOS会扩展应用程序沙箱以包含该容器目录。因此,在尝试搜索iCloud中的文件之前,至少调用一次此方法非常重要。如果您的应用程序访问多个容器目录,则应为每个目录调用该方法一次。

.nosync上的doc

  

确保iCloud不同步持久性存储本身:当您为NSPersistentStoreUbiquitousContentNameKey设置值时,UIManagedDocument将持久性存储放在文档包内的.nosync目录中。如果您使用其他内容(使用writeAdditionalContent:toURL:originalContentsURL:error:方法),则必须确保文档目录不是包。通常,您为文档目录指定一个未被识别为文档扩展名的扩展名。

您可能希望确保拥有com.apple.developer.ubiquity-container-identifiers权利。

  

iCloud容器字段标识应用可以在用户的​​iCloud存储中访问的容器目录列表。 (此字段对应于com.apple.developer.ubiquity-container-identifiers权利。)

答案 2 :(得分:1)

也许您可以禁用应用程序的备份并将数据文件存储在应用程序树中的其他位置。任何需要备份的东西都可以放在你应用程序之外的公共区域。

您可以在配置中执行此操作:invalid code signing app submission

settings

  

当您想要为用户提供完全为您的应用启用或禁用iCloud使用的选项。如果您的应用包含“设置”套件或内嵌首选项,则可以包含首选项以切换您的应用是否完全在iCloud中存储内容。例如,一个数据完全由私有托管文件组成的应用程序可以执行此操作,以便用户选择如何存储这些文件。

或删除使用Xcode的com.apple.developer.ubiquity-container-identifiers权利(可以自动添加):Configuring Your App's iCloud Entitlements

否则,您可能需要发出警告,其中包含有关通过用户界面禁用的说明:

http://www.pcmag.com/article2/0,2817,2394702,00.asp#fbid=bpIwPLZ1HeQ

另一种解决方法是将地图分组为作为单独应用程序安装的集合。这将是一种存储数据的方法,无需创建任何同步或备份的目录。数据将存储在.app目录中并受到保护。

根据缓存空间回收功能的工作方式,它可能不会删除最近访问或修改过的文件。您可以尝试定期触摸它们。您还可以添加一些旧文件作为诱饵,并检测它们何时被删除或空间不足以至少发出警告或重新下载已删除的对象...

答案 3 :(得分:0)

可能在项目的摘要窗格中取消选中“启用权利”或编辑配置文件以删除* ubiquity设置。 (Notes for ios 5 beta 7参考权利。)

还有setUbiquitous功能:

  

setUbiquitous:itemAtURL:DESTINATIONURL:错误:

     

设置指定网址的项目是否应存储在云中。

     

参数

     

标志

     

指定YES将项目移至iCloud,或指定NO将其从iCloud中移除(如果当前存在)。

http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html#//apple_ref/occ/instm/NSFileManager/setUbiquitous:itemAtURL:destinationURL:error

答案 4 :(得分:0)

有一种更新的方法可以阻止iCloud直接同步数据,而无需直接使用扩展属性:

- (BOOL)addSkipBackupAttributeToItemAtPath:(NSString *) filePathString
{
    NSURL* URL= [NSURL fileURLWithPath: filePathString];
    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;
}

有关详细信息,请参阅Apple的Technical Q&A QA1719

答案 5 :(得分:-6)

您是否尝试在没有前面数据的情况下命名目录“.nosync”?它可能是一般的。目录被忽略,或者可能是特定的。

但是,似乎行为就像用户想要的那样 - 可能是他们当前可能没有使用的应用程序使用的空间演出,可以自动回收空间。我不确定,但你会认为只有在没有选择的情况下,系统会很聪明地回收最近创建的文件,所以如果用户最近刚存储了地图,除非别无选择,否则不会删除它们。

出于提交错误的目的,我将要求在删除前为用户提示标记目录的方法 - 这样如果他们正在同步很多电影并且它会清除像地图这样的数据集你正在谈论的,将询问用户是否要从应用程序“MyCoolMapper”中删除数据“离线地图”以继续同步。