3

我的应用程序刚刚被拒绝,因为我在 NSDocumentDirectory 中复制了 sqlite 数据库并且没有将其排除在同步到 iCloud 之外。我尝试添加代码以将其从 iCloud 中排除,但它仍在 iCloud 中占用相同的空间。这是我的代码。

- (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;
    }
}

+ (void)copyDatabaseIfNeeded {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error = nil;
    NSString *toPath = [self getDBPath];
    BOOL success = [fileManager fileExistsAtPath:toPath];

    if(!success) {
        NSString *fromPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

        NSURL *toURL = [NSURL fileURLWithPath:toPath];
        NSURL *fromURL = [NSURL fileURLWithPath:fromPath];


        [[NSFileManager defaultManager] addSkipBackupAttributeToItemAtURL:toURL];
        [[NSFileManager defaultManager] addSkipBackupAttributeToItemAtURL:fromURL];

        success = [fileManager copyItemAtURL:fromURL toURL:toURL error:&error];

        if (!success) 
            NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }   
}

+ (NSString *)getDBPath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];

    return [documentsDir stringByAppendingPathComponent:databaseName];
}

请帮忙。

4

4 回答 4

6

您在处理文件之前将跳过属性设置为文件,因为文件尚未复制到那里,文件管理器无法更改该文件的属性:

此外,您没有调用addSkipBackupAttributeToItemAtURL:on self ,而是在NSFileManager其上声明了此方法。

如果您将其声明为实例方法,则可以 addSkipBackupAttributeToItemAtURL:从类方法中将其更改+为使其成为类方法。

将其更改为:

+ (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;
    }
}

+ (void)copyDatabaseIfNeeded {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error = nil;
    NSString *toPath = [self getDBPath];
    BOOL success = [fileManager fileExistsAtPath:toPath];

    if(!success) {
        NSString *fromPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

        NSURL *toURL = [NSURL fileURLWithPath:toPath];
        NSURL *fromURL = [NSURL fileURLWithPath:fromPath];
        success = [fileManager copyItemAtURL:fromURL toURL:toURL error:&error];

        if (success) {
                [self addSkipBackupAttributeToItemAtURL:toURL];
        } else {
            NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        }
    }   
}

另外我的评论说我删除了,[[NSFileManager defaultManager] addSkipBackupAttributeToItemAtURL:fromURL];因为该文件不会包含在 iCloud 备份中,并且捆绑包中的 b 文件是只读的,不能在那里进行修改。

于 2012-10-17T14:56:59.653 回答
0

请参阅技术问答 QA1719,其中描述了建议您使用的技术addSkipBackupAttributeToItemAtURL适用于 iOS 5.0.1 及更早版本。对于 iOS 5.1 及更高版本,您应该使用以下内容:

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    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;
}
于 2013-01-26T22:05:02.487 回答
0

我正在与一位 Apple 支持人员通电话讨论此事。

但是,这个答案不是重复的东西,而是很好地涵盖了它:设置 NSDocumentDirectory 所以它不会备份到 iCloud

于 2012-10-17T14:48:39.033 回答
-2

NSDocumentDirectory 与 iCloud 无关。iOS 应用程序的文档目录根本不会自动备份到 iCloud。它与以往一样,只是您的应用程序的沙箱目录。

仅当满足以下条件时,才将内容存储在 iCloud 中:

您的应用程序具有指定 iCloud 沙盒容器名称的权利

您的用户已在其设备上登录 iCloud

您显式地获取了 ubiquity 容器的文档目录并将内容存储在那里。

因此,如果您不想在 iCloud 中存储某些内容,请不要获取 ubiquity 容器的文档目录,根本不要连接到 iCloud...

此外,iCloud 备份甚至不是用户设置的应用程序级别设置,所以我不知道为什么你甚至启用了 iCloud。只需将您的数据放在数据目录中,Apple 就没有问题。

于 2012-10-17T15:01:58.357 回答