简体   繁体   English

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

[英]Prevent iCloud sync of data (using .nosync?)

EDIT: So far, the best I've been able to come up with is a pop-up to ask the user to disable iCloud sync, along with moving all the data to the Documents directory so it won't get wiped: In iOS5, is it possible to detect if a user has an app set to back up? 编辑:到目前为止,我能够提出的最好的是一个弹出窗口,要求用户禁用iCloud同步,同时将所有数据移动到Documents目录,这样就不会被擦除: 在iOS5中,是否可以检测用户是否设置了备份应用程序?

I develop offline mapping application for iPhone/iPad. 我为iPhone / iPad开发了离线地图应用程序。

We used to store all of the data (many gigs potentially) in the Caches directory. 我们曾经在Caches目录中存储所有数据(可能有很多gigs)。

As of iOS5, the files in the Caches directory can be randomly deleted when the user's hard drive starts getting full. 从iOS5开始,当用户的硬盘驱动器开始变满时,可以随机删除Caches目录中的文件。

How can I store local data, without the data being synced to iCloud, iTunes, and without it being randomly deleted? 如何在不将数据同步到iCloud,iTunes且不随机删除的情况下存储本地数据? My local data is a large directory tree with many small data files, in thousands of subdirectories. 我的本地数据是一个包含许多小数据文件的大型目录树,存在于数千个子目录中。

I moved our directory tree from the library cache directory to a data.nosync directory in the documents directory, because we had read this might be a solution. 我将目录树从库缓存目录移动到文档目录中的data.nosync目录,因为我们已经读过这可能是一个解决方案。 However, the data in the nosync folder is still being backed up to iCloud. 但是,nosync文件夹中的数据仍将备份到iCloud。

Here is now I create the directory: 现在我创建目录:

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

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

You can use the following method to set the "do not back up" extended attribute. 您可以使用以下方法设置“不备份”扩展属性。 Whenever you create a file or folder that should not be backed up, write the data to the file and then call this method, passing in a URL to the file. 每当您创建不应备份的文件或文件夹时,请将数据写入文件,然后调用此方法,并将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;
}

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

Further note: While the developer documentation incorrectly implies ("These files will not be purged and will not be included in the user's iCloud or iTunes backup.") that the do-not-backup flag doubles as a do-not-purge flag that is not the case. 进一步说明:虽然开发人员文档错误地暗示(“这些文件不会被清除,也不会包含在用户的iCloud或iTunes备份中。”),do-not-backup标志会兼作do-not-purge标志,事实并非如此。 Simply leaving files in the Caches Directory and flagging them do-not-backup will not prevent their wipe. 只需将文件保留在缓存目录中并将其标记为“不备份”就不会阻止其擦除。

This issue might not have a workaround yet... You could possibly try calling URLForUbiquityContainerIdentifier explicitly, since it does some initialization on the first invocation. 此问题可能还没有解决方法...您可以尝试显式调用URLForUbiquityContainerIdentifier ,因为它在第一次调用时进行了一些初始化。 Then create a sub-directory with a .nosync suffix (based on this example ). 然后创建一个带有.nosync后缀的.nosync (基于此示例 )。

The first time you call this method for a given container directory, iOS extends your application sandbox to include that container directory. 第一次为给定容器目录调用此方法时,iOS会扩展应用程序沙箱以包含该容器目录。 Thus, it is important that you call this method at least once before trying to search for files in iCloud. 因此,在尝试搜索iCloud中的文件之前,至少调用一次此方法非常重要。 And if your application accesses multiple container directories, you should call the method once for each directory. 如果您的应用程序访问多个容器目录,则应为每个目录调用该方法一次。

The doc on .nosync : .nosync上的文档

To ensure that the persistent store itself is not synced by iCloud: when you set a value for the NSPersistentStoreUbiquitousContentNameKey, UIManagedDocument puts the persistent store in a .nosync directory inside the document package. 确保iCloud不同步持久性存储本身:当您为NSPersistentStoreUbiquitousContentNameKey设置值时,UIManagedDocument将持久性存储放在文档包内的.nosync目录中。 If you make use of additional content (using the writeAdditionalContent:toURL:originalContentsURL:error: method), you must make sure that the document directory is not a package. 如果您使用其他内容(使用writeAdditionalContent:toURL:originalContentsURL:error:方法),则必须确保文档目录不是包。 Typically you give the document directory an extension that is not recognized as a document extension. 通常,您为文档目录指定一个未被识别为文档扩展名的扩展名。

You may want to ensure you have the com.apple.developer.ubiquity-container-identifiers entitlement. 您可能希望确保拥有com.apple.developer.ubiquity-container-identifiers权利。

The iCloud Containers field identifies the list of container directories that your app can access in the user's iCloud storage. iCloud容器字段标识应用程序可以在用户的​​iCloud存储中访问的容器目录列表。 (This field corresponds to the com.apple.developer.ubiquity-container-identifiers entitlement.) (此字段对应于com.apple.developer.ubiquity-container-identifiers权利。)

Perhaps you can disable backup for your app and store data files somewhere else in the app tree. 也许您可以禁用应用程序的备份并将数据文件存储在应用程序树中的其他位置。 Any stuff that needs to be backed can be put in a common area outside your app. 任何需要备份的东西都可以放在应用程序外的公共区域。

You might be able to do it in provisioning: invalid code signing app submission 您可以在配置中执行此操作: 无效的代码签名应用程序提交

or settings : 设置

When you want to give the user the option to enable or disable iCloud usage entirely for your app. 当您想要为用户提供完全为您的应用启用或禁用iCloud使用的选项。 If your app includes a Settings bundle or inline preferences, you could include a preference to toggle whether your app stores content in iCloud at all. 如果您的应用包含“设置”套件或内嵌首选项,则可以包含首选项以切换您的应用是否完全在iCloud中存储内容。 For example, an app whose data consists entirely of privately managed files might do this to give the user the choice of how those files are stored. 例如,其数据完全由私有托管文件组成的应用程序可以执行此操作,以便用户选择如何存储这些文件。

or by removing the com.apple.developer.ubiquity-container-identifiers entitlement (which could get auto-added) with Xcode: Configuring Your App's iCloud Entitlements 或者使用Xcode删除com.apple.developer.ubiquity-container-identifiers权利(可以自动添加): 配置应用程序的iCloud权利

Otherwise you might need to issue a warning with instructions on disabling through the UI: 否则,您可能需要发出警告,其中包含有关通过UI禁用的说明:

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

Another workaround is to group the maps into collections that are installed as separate applications. 另一种解决方法是将映射分组为作为单独的应用程序安装的集合。 That would be a way to store the data without creating any directories that sync or get backed-up. 这将是一种存储数据的方法,无需创建任何同步或备份的目录。 The data will be stored in the the .app directory and will be protected. 数据将存储在.app目录中并受到保护。

Depending on how the cache space reclamation function works, it might not delete recently accessed or modified files. 根据缓存空间回收功能的工作方式,它可能不会删除最近访问或修改过的文件。 You could try periodically touching them on a timer. 您可以尝试定期触摸它们。 You could also add some old files as decoys and detect when they've been deleted or when space is low to at least issue a warning or re-download the deleted objects... 您还可以添加一些旧文件作为诱饵,并检测它们何时被删除或空间不足以至少发出警告或重新下载已删除的对象...

There is a newer way to prevent iCloud syncing of data without using extended attributes directly: 有一种更新的方法可以防止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;
}

See Apple's Technical Q&A QA1719 for more details. 有关详细信息,请参阅Apple的技术问答QA1719

Maybe uncheck "Enable Entitlements" in the summary pane of the project or edit the profile to remove the *ubiquity settings. 也许在项目的摘要窗格中取消选中“启用权利”或编辑配置文件以删除* ubiquity设置。 ( Notes for ios 5 beta 7 reference entitlements.) ios 5 beta 7参考权利的注释 。)

There is also the setUbiquitous function: 还有setUbiquitous函数:

setUbiquitous:itemAtURL:destinationURL:error: setUbiquitous:itemAtURL:DESTINATIONURL:错误:

Sets whether the item at the specified URL should be stored in the cloud. 设置指定URL处的项目是否应存储在云中。

Parameters 参数

flag

Specify YES to move the item to iCloud or NO to remove it from iCloud (if it is there currently). 指定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 : 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

Did you try just naming the directory ".nosync" without the data in front? 您是否尝试仅在没有前面数据的情况下命名目录“.nosync”? It could be generally . 它可能是一般的。 directories are ignored, or perhaps that specifically. 目录被忽略,或者可能是具体的。

But, it seems like the behavior is just as a user would want it - potentially gigs of space used by an application they may not be using currently, where the space could be reclaimed automatically. 但是,似乎行为就像用户想要的那样 - 可能是当前可能没有使用的应用程序所使用的空间演出,其中空间可以自动回收。 I am not sure but you would think the system would be smart about reclaiming files created recently only after there was no choice, so if the user had just stored maps recently they would not be deleted unless there was no other choice. 我不确定,但你会认为系统只有在没有选择之后才能回收最近创建的文件,所以如果用户最近刚刚存储了地图,除非没有其他选择,否则它们不会被删除。

For the purposes of filing a bug I am going to ask for a way to mark a directory for user prompting before deletion - so that if they are syncing a lot of movies and it would clear out a data set like the maps you are talking about, the user would be asked if they want to remove the data "offline maps" from application "MyCoolMapper" to proceed with the sync. 出于提交错误的目的,我将要求在删除之前为用户提示标记目录的方法 - 这样如果他们正在同步很多电影并且它会清除像你正在谈论的地图一样的数据集,将询问用户是否要从应用程序“MyCoolMapper”中删除数据“离线地图”以继续同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM