我的应用程序被拒绝了,因为似乎有7 MB存储在文档文件夹中,它们会自动发送到iCloud。所以我通过此方法循环了将写入文档文件夹的所有文件:
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL {
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
if (&NSURLIsExcludedFromBackupKey == nil) {
// iOS 5.0.1 and lower
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
}
else {
// First try and remove the extended attribute if it is present
int result = getxattr(filePath, attrName, NULL, sizeof(u_int8_t), 0, 0);
if (result != -1) {
// The attribute exists, we need to remove it
int removeResult = removexattr(filePath, attrName, 0);
if (removeResult == 0) {
NSLog(@"Removed extended attribute on file %@", URL);
}
}
// Set the new key
NSError *error = nil;
[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
return error == nil;
}
在此代码实现之后,我的应用程序的 1.1 版已获得批准。上周我尝试发送同一应用程序的 1.2 版(文件管理没有任何变化,存储在文档文件夹中的所有文件都通过 addSkipBackupAttributeToItemAtURL 方法循环)。出于同样的原因,我的应用程序再次被拒绝。 我无法将文件移动到临时或缓存文件夹,因为我的应用程序无法完全还原文件(其中一个文件是数据库,还原数据库意味着丢失任何用户插入的数据),所以这个不能成为解决方案。无论如何,我在代码中发现了一个问题,这就是我调用该方法的方式:
[self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:fullPath]];
在 ios 5.1 中使用 [NSURL fileURLWithPath:fullPath] 设备会返回错误,并且似乎无法创建该属性。如果我用 [NSURL URLWithString:defaultStorePath] 更改 nsurl 的初始化,则 5.1 的设备似乎正确添加了该属性。
在ios 5.0.1中,所有内容都是反转的,[NSURL URLWithString:defaultStorePath]返回错误,而[NSURL fileURLWithPath:fullPath]工作。
也许我可以检查ios版本并设置适当的nsurl初始化,但这仍然是一个问题。在拒绝解释中,我读到:
特别是,我们发现在启动和/或内容下载时,您的应用程序存储了 7mb。若要检查应用存储的数据量,请执行以下操作:
- 安装并启动应用
- 转到 iCloud>储存>备份>管理储存空间的设置
- 如有必要,点击"显示所有应用程序"
- 检查应用的存储空间
如果我尝试检查此值,我会看到 7 mb 也具有正确的 nsurl 初始化(当所有属性都设置正确时)。什么是正确的行为?有人有这个问题吗? 在苹果建议的应用程序存储检查之前,我是否必须做一些特定的事情才能使其变得重要?
我认为诀窍是添加NSURLIsExcludedFromBackupKey并确保目录在文档目录之外。 我通过将文档移动到库/应用程序支持文件夹来做到这一点(因为它在/tmp 或/Caches 文件夹中没有意义):
// store in /Library/Application Support/BUNDLE_IDENTIFIER/Reference
// make sure Application Support folder exists
NSURL *applicationSupportDirectory = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:&error];
if (error) {
NSLog(@"KCDM: Could not create application support directory. %@", error);
return nil;
}
NSURL *referenceFolder = [applicationSupportDirectory URLByAppendingPathComponent:@"Reference" isDirectory:YES];
if (![[NSFileManager defaultManager] createDirectoryAtPath:[referenceFolder path]
withIntermediateDirectories:YES
attributes:nil
error:&error]) {
NSLog(@"KCDM: Error creating Reference folder to store model %@: %@", modelName, error);
return nil;
}
BOOL success = [referenceFolder setResourceValue:@YES forKey: NSURLIsExcludedFromBackupKey error: &error];
if(!success){
NSLog(@"KCDM: Error excluding %@ from backup %@", referenceFolder, error);
}
我遇到了和你一样的问题,直到我从设备中删除了我的应用程序,然后重新安装。 我还必须通过转到设置->存储和备份->管理存储从iCloud备份中删除现有的缓存数据
这似乎起到了作用。另外,我添加 skip 属性的代码有点不同:从这篇文章中提取的代码
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
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;
}
}