簡體   English   中英

iOS復制SQLite數據庫並將其從iCloud中排除

[英]iOS Copy SQLite Database and excluding it from iCloud

我的應用程序剛剛被拒絕,因為我在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];
}

請幫忙。

您在處理文件之前將跳回屬性設置為該文件,因為文件尚未復制,文件管理器無法更改該文件的屬性:

你也沒有調用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文件是只讀的,因此無法進行修改。

我正和一位蘋果支持人員通電話。

但是,這個答案很好地涵蓋了它,而不是重復的東西: 設置NSDocumentDirectory,使其不備份到iCloud

請參閱技術問答QA1719 ,其中描述了在iOS 5.0.1及更早版本中建議您在addSkipBackupAttributeToItemAtURL使用的技術。 對於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;
}

NSDocumentDirectory與iCloud無關。 iOS應用程序的文檔目錄根本不會自動備份到iCloud。 它與以往一樣,只是您的應用程序的沙箱目錄。

如果滿足以下條件,您只能在iCloud中存儲內容:

您的應用具有指定iCloud沙箱容器名稱的權利

您的用戶已在其設備上登錄iCloud

您明確獲取ubiquity容器的文檔目錄並將其存儲在那里。

因此,如果您不想在iCloud中存儲內容,請不要獲取ubiquity容器的文檔目錄,根本不要連接到iCloud ...

此外,iCloud備份甚至不是用戶設置它的應用程序級別設置,所以我不知道為什么你甚至啟用了iCloud。 只需將您的數據放在數據目錄中,蘋果就沒有任何問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM