iPhone сохранить данные будут удалены при обновлении? - PullRequest
2 голосов
/ 15 августа 2010

У меня есть приложение в магазине приложений, и я только что получил сообщение от пользователя, в котором говорится, что после обновления до новой версии приложения сохраненные данные исчезли.

Существует ли явно неправильный способ сохранения данных на iphone, который может привести к потере данных при обновлении приложения до новой версии?

Вот код, который я использую для загрузки и сохранения, который отлично работает на машинах разработки. Это неправильный способ сделать это?

- (bool) saveData:(NSData*) data toFile:(NSString*) filename
{
    NSError* error;

    NSFileManager *fileMgr = [[[NSFileManager alloc] init] autorelease];
    NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString* filePath = [docsDir stringByAppendingPathComponent:filename];
    NSString* validMarkerPath = [docsDir stringByAppendingPathComponent:[filename stringByAppendingString:@".val"]];
    NSString* backupPath = [docsDir stringByAppendingPathComponent:[filename stringByAppendingString:@".bak"]];

    // If the file exists and is marke valid, copy it over the backup.
    if([fileMgr fileExistsAtPath:filePath] && [fileMgr fileExistsAtPath:validMarkerPath])
    {
        if([fileMgr fileExistsAtPath:backupPath])
        {
            if(![fileMgr removeItemAtPath:backupPath error:&error])
            {
                NSLog(@"Error: SafeFileManager: Could not remove backup file %@: %@", backupPath, [error localizedDescription]);
            }
        }

        if(![fileMgr moveItemAtPath:filePath toPath:backupPath error:&error])
        {
            NSLog(@"Error: SafeFileManager: Could not move %@ to %@: %@", filePath, backupPath, [error localizedDescription]);
        }
    }

    // Remove the "valid" marker file, if present.
    if([fileMgr fileExistsAtPath:validMarkerPath])
    {
        if(![fileMgr removeItemAtPath:validMarkerPath error:&error])
        {
            NSLog(@"Error: SafeFileManager: Could not remove validation file %@: %@", validMarkerPath, [error localizedDescription]);
        }
    }

    // Save the new file.
    if(![data writeToFile:filePath options:NSAtomicWrite error:&error])
    {
        NSLog(@"Error: SafeFileManager: Could not save to %@: %@", filePath, [error localizedDescription]);
        return NO;
    }

    // If we succeeded, save the "valid" marker file.
    NSData* markerData = [NSData dataWithBytes:"0" length:1];
    if(![markerData writeToFile:validMarkerPath options:NSAtomicWrite error:&error])
    {
        NSLog(@"Error: SafeFileManager: Could not save validation file %@: %@", validMarkerPath, [error localizedDescription]);
        return NO;
    }
    return YES;
}

- (NSData*) loadDataFromFile:(NSString*) filename
{
    NSError* error;

    NSFileManager *fileMgr = [[[NSFileManager alloc] init] autorelease];
    NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    NSString* filePath = [docsDir stringByAppendingPathComponent:filename];
    NSString* validMarkerPath = [docsDir stringByAppendingPathComponent:[filename stringByAppendingString:@".val"]];

    // If the file isn't valid, we'll try to load the backup.
    if(![fileMgr fileExistsAtPath:validMarkerPath])
    {
        filePath = [docsDir stringByAppendingPathComponent:[filename stringByAppendingString:@".bak"]];
    }

    NSData* data = nil;

    @try
    {
        data = [NSData dataWithContentsOfFile:filePath options:NSUncachedRead error:&error];
        if(nil == data)
        {
            NSLog(@"Error: SafeFileManager: Could not load from %@: %@", filePath, [error localizedDescription]);
        }
    }
    @catch (NSException * e)
    {
        NSLog(@"Error: SafeFileManager: Could not load from %@: %@", filePath, [e description]);
        data = nil;
    }

    return data;
}

1 Ответ

0 голосов
/ 16 августа 2010

Чтобы ответить на мой собственный вопрос, в этом коде есть отверстие для записи, где удаляются файл резервной копии и файл маркера, что может привести к сбою загрузки.

Теперь я выбрал более простой, если не более грубый подход: просто сохранить файл, а затем сохранить резервную копию. При загрузке он пытается выполнить основной файл и, если возникает какая-либо ошибка, он пытается выполнить ту же процедуру загрузки с использованием файла резервной копии.

...