大文件下载到Documents并备份到iCloud

时间:2016-03-29 19:20:57

标签: ios

我在应用程序商店中有一个iOS应用程序,可以下载需要留在设备上以供离线使用的相对较大的文件。这些文件当前存储在应用程序的Documents文件夹中,但我刚刚读到Documents文件夹已备份,并且实际上只应用于用户生成的内容。 This Apple technical Q&A声明NSURLIsExcludedFromBackupKey应设置为阻止备份。 This声明应用的/Library/Caches是放置这些类型文件的正确位置,但进一步阅读表明,当设备存储空间不足时,该文件夹可能会被清除,这对于此应用来说是不可接受的。我相信/Library/Application Support/是他们最好的位置 - 这听起来不错吗?

不幸的是,这个错误通过了应用审核流程。现在人们正在使用该应用程序并且已经将一些文件保留到Documents文件夹及其备份中,有哪些最佳实践可以解决这个问题?我似乎需要移动所有现有文件并在应用更新上设置NSURLIsExcludedFromBackupKey。我如何保证这一次完成并且不会中断?是将文件移出Documents文件夹重要还是我可以将它们留在那里?更改文件的备份状态是否会将其从现有备份中删除?

我正在使用Swift 2.1.1并定位到iOS 8.0 +。

2 个答案:

答案 0 :(得分:2)

如技术问答A中所述,最好的办法是在文档中创建一个子目录,并将该子目录排除一次。

答案 1 :(得分:2)

我不相信你可以写一次,并确保它已经完成了#39;例程,因为您无法保证您的应用在运行时不会崩溃。当你确定它已经完成时,你当然可以设置一个完成标志,这样一旦完成,你就不必再次运行了它。

从备份中排除目录,而不是单个文件。 来自Xcode:

  

您可以使用此属性排除备份中不需要的缓存和其他应用程序支持文件。通常对用户文档进行的一些操作会导致此属性重置为false;因此,请勿在用户文档中使用此属性。

这是我使用的策略,效果很好 (对不起,它的目标 - 我 - 我不是一个快速的人。希望它会给你这个想法):

    - (BOOL)moveAllFiles{

    // Searches through the documents directory for all files ending in .data
    BOOL success = true;
    NSString *myNewLocation = @"/store/my/files/here/now";

    // Get the documents directory
    NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory = [documentDirectories objectAtIndex:0];

    // Get all files ending in .data (whatever your file type is)
    NSArray *dataFilesArray = [NSArray arrayWithArray:[NSBundle pathsForResourcesOfType:@"data" inDirectory:documentDirectory]];
    // If you have multiple resource types, use this line once each for each resource type, then append the arrays.

    // Iterate the found files
    NSString *fileName = [NSString string];
    for (int i=0; i<[dataFilesArray count]; i++) {
        fileName = [[dataFilesArray objectAtIndex:i] lastPathComponent];

        // Move file, set success to false if unsuccessful move
        if (![[NSFileManager defaultManager] moveItemAtPath:[dataFilesArray objectAtIndex:i]
                                                    toPath:[myNewLocation stringByAppendingPathComponent:fileName]
                                                     error:nil]) {
            success = false; // Something went wrong
        }
    }
    return success;
}

现在使用success的值在用户默认文件中设置密钥。启动时检查该密钥。如果是假(或缺席),请再次运行此例程。

此示例包含文件路径。如果您愿意,可以使用文件URL执行相同的操作。