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

私はこれについてAppleのサポート担当者と電話をしていました。

しかし、繰り返しではなく、この答えはそれをうまくカバーしています:iCloudにバックアップされないようにNSDocumentDirectoryを設定する

于 2012-10-17T14:48:39.033 に答える
0

iOS 5.0.1以前では、使用するテクニックが推奨されると説明されているテクニカルQ&AQA1719を参照してください。addSkipBackupAttributeToItemAtURLiOS 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 に答える
-2

NSDocumentDirectoryはiCloudとは何の関係もありません。iOSアプリケーションのドキュメントディレクトリは、iCloudに自動的にバックアップされません。これまでと同じですが、アプリのサンドボックスディレクトリだけです。

次の条件が満たされた場合にのみ、iCloudに保存します。

アプリには、iCloudサンドボックスコンテナ名を指定する資格があります

ユーザーは自分のデバイスでiCloudにログインしています

ユビキタスコンテナのドキュメントディレクトリを明示的に取得し、そこに保存します。

したがって、iCloudに何かを保存したくない場合は、ユビキタスコンテナのドキュメントディレクトリを取得しないでください。iCloudに接続しないでください...

また、iCloudバックアップは、ユーザーが設定するアプリケーションレベルの設定でもないので、なぜiCloudが有効になっているのかわかりません。データをデータディレクトリに置くだけで、アップルは問題ありません。

于 2012-10-17T15:01:58.357 に答える