2010-08-15 16 views
2

J'ai une application dans l'App Store, et je viens de recevoir un message d'un utilisateur me disant que lors de la mise à niveau vers une version plus récente de l'application, leurs données enregistrées ont toutes disparu.iPhone enregistrer les données supprimées lors de la mise à niveau?

Existe-t-il une façon nettement incorrecte d'enregistrer des données sur l'iPhone qui entraînerait une perte de données lors de la mise à niveau de l'application vers une nouvelle version?

Voici le code que j'utilise pour charger & enregistrer, ce qui fonctionne très bien sur les machines de développement. Est-ce la mauvaise façon de le faire?

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

Répondre

0

Pour répondre à ma propre question, ce code a un trou d'écriture où le fichier de sauvegarde et fichier de marqueurs sont supprimés, ce qui causerait la charge à l'échec.

J'ai maintenant opté pour une approche plus simple, sinon plus brute, consistant simplement à sauvegarder le fichier, puis à sauvegarder une sauvegarde. Au chargement, il essaie le fichier principal, et si une erreur survient, il tente la même routine de chargement en utilisant le fichier de sauvegarde.