iPhone应用程序因iCloud数据存储指南而被拒绝

Bil*_*ill 18 iphone app-store ios

由于涉嫌违反iCloud数据存储指南,最近拒绝了对我的某个应用程序的严重错误修正更新.

以下是我的应用程序存储数据的方式(自我的应用程序的第一个版本在2009年获得批准以来一直没有问题):

  1. 在启动时,它将"启动"SQLite3数据库从应用程序包复制到Documents文件夹.
  2. 该数据库包含基本架构和一些示例数据,因此用户可以看到如何使用该应用程序.它很小 - 不到3MB.
  3. 然后,用户的未来工作仅保存在此数据库文件中.他们可能删除或保留样本,他们可能会添加大量自己的数据,但该数据库文件将始终存在.

由于同样的原因,今年早些时候的更新被拒绝,但是当我向他们提供上述解释时,应用程序状态从"已拒绝"更改为"在审核中"更改为"处理App Store".他们没有给我任何解释,所以我认为这只是对评论员的误解.

这一次,审阅者回答了我的解释,只是说非用户生成的数据不应该存储在iCloud中,而且我的更新仍处于"已拒绝"状态.

但我不明白我应该在这做什么.因为所有用户的工作都保存在数据库中,所以我不能选择将其从iCloud备份中排除或将其存储在Cache文件夹中.此外,我不能真正干净地将"用户生成的"与"非用户生成的"数据分开,因为该应用程序使用相同的数据库文件.尽管数据库的文件名和目录位置保持不变,但最初的非用户生成的数据将很快被用户自己的数据替换.

即使数据库中没有样本数据,任何数据库支持的应用程序在启动时仍然必须生成一个空数据库 - 即使它所拥有的唯一内容是应用程序的数据库模式.

这一定是一个非常常见的问题,但遗憾的是,我不能仅仅关闭备份 - 用户将大量工作投入到我们应用中存储的数据中,而iCloud备份对他们来说非常重要.

我现在有什么选择?这是我能看到的:

  1. 再次联系Apple并尝试解释发生了什么.

  2. 我可以将文件的备份属性设置为NO,然后仅在用户进行第一次更改时将其切换为YES吗?Apple在技术上是否可以,还可以吗?

  3. 从数据库中删除我的示例数据.这对于可用性来说真的很糟糕,并且会增加我的支持负担,但是如果能够获得我的更新批准,我愿意这样做.但是,我仍然需要在启动时创建一个存根数据库来保存空数据库模式,所以我不确定这是否会在批准过程中产生影响.

  4. 哭.

有人有什么建议吗?我不得不想象有很多其他应用程序使用数据库的方式与我的相同,但是没有选择只禁用备份.

令我非常沮丧的是,我所做的任何更改都需要进行另一轮测试和应用程序审核,这将使我的关键更新再次延迟2-3周.:/

更新:可能还有另一种选择:我可以简单地保存文件Library/而不是Documents/,因为他们的问题似乎特别是使用Documents文件夹?如果文件存储在文件中,它是否会被备份Library/

更新2:我发现最令人困惑的是,任何数据库支持的应用程序(即使它使用Core Data,我认为)都必须创建一个至少包含应用程序架构的数据库文件.问题只是我的数据库的大小太大了吗?因为我无法看到任何数据库支持的应用程序如何避免在启动时创建数据库.

更新3:我正在使用自定义SQLite交互层 - 而不是核心数据.此外,示例数据由初始图像组成,用户在开始使用应用程序时可能会最终删除.

hyp*_*ypt 5

3MB似乎存储在数据库中的相当多的样本数据.如果您拉出图像并存储对数据库中图像的引用,那么您应该能够大量使用这种用法.然后,您可以将数据库的图像获取器代码更改为以下内容:

- (UIImage *)image
{
    NSString *imageName = self.imageName;
    UIImage *image = [UIImage imageNamed:imageName];
    if (!image)
    {
        NSString *imageLibraryPath = ...;
        image = [UIImage imageWithPath:[imageLibraryPath stringByAddingPathComponent:imageName]];
    }
    return image;
}

- (void)setImage:(UIImage *)image
{
    [self setImageData:UIImagePNGRepresentation(image)];
}

- (void)setImageData:(NSData *)imageData
{
    NSString *imageLibraryPath = ...;
    NSString *fileName = self.uniqueId; //or something else, UUID maybe?
    NSString *filePath = [imageLibraryPath stringByAddingPathComponent:imageName];
    [imageData writeToFile:filePath atomically:YES]; // maybe dispatch_async this into the background?
    self.fileName = fileName;
}
Run Code Online (Sandbox Code Playgroud)

self.fileName将由您的数据库支持.

通过以这种方式减少数据存储,您应该能够获得批准,因为您没有在手机上存储相对大量的数据.图像也可以通过这种方式在应用程序包中,根本不需要复制.