【问题标题】:iOS 5 does not allow to store downloaded data in Documents directory?iOS 5 不允许将下载的数据存储在 Documents 目录中?
【发布时间】:2012-01-02 19:26:18
【问题描述】:

我通过将目标 iOS 设置为 4 为我的客户创建了一个应用程序。
但由于应用程序仍未提交到 Apple Store,我的客户计划将其升级到 iOS 5.0。

为此,我阅读了guideline from Apple 并发现“只有用户生成的数据或您的应用程序无法重新创建的数据,应存储在 /Documents 目录中,其余数据应存储在 /Library/Caches 目录中”

在我的应用程序中,我将应用内购买的服务器模型用于非消耗性产品。为此,我将所有下载的数据(基本上是书籍或杂志)存储到 Documents 目录中。数据库也存在于同一目录中,其中包含有关下载产品的详细信息。

我的问题是,
1. 我是否必须更改代码以将下载的数据存储到 Library/Caches 目录而不是 Documents 目录?
2. 我的数据库文件应该放在哪里(文档或缓存)?

如果我把它放在缓存中,那么我也必须改变检索的逻辑,因为如果数据库中存在记录,则不需要改变文件的存在,它直接打开它用户点击杂志。

请在这个问题上指导我。
提前致谢。

更新:
我正在为那些仍然不确定这个问题的人更新这个。
使用接受答案的指导方针,我已经在我的 2 个应用程序中实现了这一点,并将它们提交到 Apple Store。两者都在审查中获得批准。
这可能会促进接受的答案中建议的解决方案是正确的。

【问题讨论】:

    标签: iphone objective-c ios5 in-app-purchase


    【解决方案1】:

    以下是权衡取舍:

    • 如果您将文件放在 Documents 目录中,那么它们会备份到 iTunes 或 iCloud,但如果它们太大并且可以再次下载文件,那么 Apple 可能会拒绝您的应用
    • 如果您将文件放在缓存目录中,那么它们不会被备份,Apple 也不会拒绝您的应用程序。但是,当 iOS 5 空间不足时,它可能会删除其中的所有文件。

    但是,对于 iOS 5.0.1,还有第三种选择:

    • 将文件放入 Documents 中,但标记它们以便不备份。有关如何执行此操作的技术说明 (QA1719)。

    我认为这可能是最适合你的答案。

    【讨论】:

    • 正如我在回答中所说:“如果您将文件放在缓存目录中,那么......当 iOS 5 空间不足时,它可能会删除其中的所有文件。” Apple 针对这个确切问题提供的解决方案是我在第三个要点中提到的“无备份”标志。
    • "将文件放入 Documents 但标记它们以便不备份。"
    • 请阅读技术说明。如果您将文件放在缓存目录中,iOS 将在空间不足时删除它们。如果您只是将它们放在 Documents 中,Apple 可能不会批准您的应用程序。如果您将它们放入 Documents 并且 标记为“无备份”,Apple 将批准您的应用,并且在空间不足的情况下不会删除这些文件。
    • 只要用户可以删除文件我想你会没事的。
    • iOS 5.0 版本是什么? Apple 在文档中说这一点“重要”新的“不备份”属性将仅由 iOS 5.0.1 或更高版本使用。在 iOS 5.0 及更早版本上,应用程序需要将其数据存储在 /Library/Caches以避免对其进行备份。由于在旧系统上会忽略此属性,因此您需要确保您的应用程序在您的应用程序支持的所有 iOS 版本上都符合 iOS 数据存储指南。”
    【解决方案2】:

    1.我是否必须更改代码以将下载的数据存储到 Library/Caches 目录而不是 Documents 目录? = 是的,您需要将下载的数据存储到 Library/Caches 目录。

    2。我的数据库文件应该放在哪里(到 Documents 或 Caches)? = 您可以将数据库保存在 Documents 目录中。

    【讨论】:

    • 为什么要把数据库放到Caches目录下?它既不会重新生成也不会重新创建。
    【解决方案3】:

    我知道的一个应用曾因此被拒绝。不建议将可下载数据存储在 Documents 目录中。其背后的逻辑是您的数据不应不必要地膨胀应用程序目录。这个app目录备份在iCloud中,所以膨胀的app目录会导致更多的数据保存在iCloud中。

    如果数据可以再次下载,如杂志、书籍 pdf 等。然后将其保存在 Caches 目录中。当然,您可以在 Documents 目录中存储指向数据(如 URL 等)的指针,以便用户稍后检索它们。

    回答您的问题:

    1. 是的,更改您的代码以从文档加载数据库并从缓存中加载数据。
    2. 将数据库保存在文档中

    您必须添加代码来检查数据库中的文档是否存在于缓存中,如果不存在,您的应用应重新下载它。

    【讨论】:

    • “您可以在 Documents 目录中存储指向数据(如 URL 等)的指针”这是什么意思?这是否意味着我必须创建一个包含文档 URL 的文件?我已经将 URL 存储在数据库中。那么每次在数据库中找到记录时,我是否也必须检查文件是否存在?
    • 是的,您必须检查是否存在并在必要时重新下载。
    • +1 快速回复。我会对此进行调查并考虑接受答案。感谢您的回复
    • 您应该将数据库保存在文档中,以便正确备份。如果用户从 iCloud 备份恢复,Caches 目录中的所有内容都将被删除。
    【解决方案4】:

    除了应将数据保存在缓存目录中的建议之外,在将数据保存在缓存文件夹中时还应牢记一个问题:

    每当 iOS 感到内存紧张时,它都会删除所有缓存和临时文件夹。 Problem is described here in detail 为了保护这些目录不被删除并终身保留所有内容,您应该使用将保持上述目录安全的属性。 解决办法是here:

    【讨论】:

    • +1 向我展示了如果我将下载的产品保存在缓存中并且 iOS 将它们全部删除时可能面临的问题。
    • @UPT 是的,你是绝对正确的,我一直在寻找相同的东西,我在苹果数据存储文档中得到了相同的东西 developer.apple.com/icloud/documentation/data-storage
    • 好消息。您应该为 iOS 11 更新它并成为社区 SME。
    【解决方案5】:

    我正在寻找相同的查询,我已经找到了解决方案。 根据苹果数据存储文档,开发人员可能会将数据存储在缓存中,即使用户希望在内存不足的情况下保留该数据。开发人员只需设置Do not back up 标志。

    Use the "do not back up" attribute for specifying files that should remain on device, 
    even in low storage situations. Use this attribute with data that can be recreated but
    needs to persist even in low storage situations for proper functioning of your app or 
    because customers expect it to be available during offline use. 
    
    This attribute works on marked files regardless of what directory they are in, including      the Documents directory. 
    These files will not be purged and will not be included in the user's iCloud 
    or iTunes backup. Because these files do use on-device storage space, your app is 
    responsible for monitoring and purging these files periodically.
    

    For more Information go through this link

    使用下面的代码来设置do not back up 标志。

    import <sys/xattr.h>

    - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
    {
    if (&NSURLIsExcludedFromBackupKey == nil) { // iOS <= 5.0.1
        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;
    } else { // iOS >= 5.1
        NSError *error = nil;
        [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
        return error == nil;
    }
    

    }

    URL is the path of Data.

    【讨论】:

    【解决方案6】:

    我通过将目标 iOS 设置为 4 为我的客户创建了一个应用程序。 但是由于申请还没有提交到苹果商店,我的 客户正计划将其升级到 iOS 5.0

    另一个选择(如果您只支持 iOS 5)是使用 NewsstandKit。这样,当“磁盘”空间不足时,iOS 只会删除选定的杂志。我的理解是 iOS 会根据上次阅读的时间和大小删除选定的问题。

    如果您不使用报亭并且您的应用被定位,则所有问题都将被删除。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    相关资源
    最近更新 更多