Непостоянство объекта, записанного в documentsDirectory - есть

- вопрос о том, как сохранить объект, сохраненный в каталоге документов на диске, и восстановить его после перезагрузки iDevice.

Вот моя проблема. Я делаю объект данных с помощью NSCoding и заполняю его данными. Я пишу это в documentsDirectory каждый раз, когда данные в объекте обновляются. Я останавливаю приложение и снова запускаю приложение, и мой объект данных сохраняется со всеми его данными. Но если я перезагружаю iPhone, код, который я написал, чтобы восстановить и прочитать объект данных, потерпит неудачу.

Код, который я написал изначально, использовал только NSString для пути к файлу. Он хорошо работал под ios7, но не работает под ios8.

Читая о вещах, я нашел эту подсказку из документации Apple:

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

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

Вот моя текущая серия шагов. Сначала я либо определяю (или, если он уже существует в NSUsrDefaults, я восстановлю) абсолютный путь к documentsDirectory, используя закладку:

 + (NSString*) getGeoModelAbsolutePath
 {
     NSString *path;
     NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
     NSURL *documentsDirectoryBookmarkURL;
     NSData* documentsDirectoryBookmark = [userDefaults objectForKey:@"documentDirectoryBookmark"];
     if(documentsDirectoryBookmark == nil)
     {
         documentsDirectoryBookmarkURL = [self getDocumentsDirectoryURL];
         documentsDirectoryBookmark = [self bookmarkForURL:documentsDirectoryBookmarkURL];
     }
     documentsDirectoryBookmarkURL = [self urlForBookmark:documentsDirectoryBookmark];
     path = documentsDirectoryBookmarkURL.path;
     path = [path stringByAppendingString:@"/Model.mod"];

     return path;
 }

используя методы, модифицированные из моего кода ios7 (который использовал только метод getDocumentsDirectory):

 + (NSString *)getDocumentsDirectory
 {
     NSURL *directory = [self getDocumentsDirectoryURL];
     NSString * documentsDirectory = directory.path;
     return documentsDirectory;
 } 

А также

 + (NSURL *)getDocumentsDirectoryURL
 {
      NSURL *directory = [[[NSFileManager defaultManager]
                      URLsForDirectory:NSDocumentDirectory
                      inDomains:NSUserDomainMask]
                     lastObject];
     return directory;
 }

А также

 + (NSData*)bookmarkForURL:(NSURL*)url {
     NSError* theError = nil;
     NSData* bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile
                      includingResourceValuesForKeys:nil
                                       relativeToURL:nil
                                               error:&theError];
     if (theError || (bookmark == nil)) {
         // Handle any errors.
         return nil;
     }
     return bookmark;
 }

Итак, теперь у меня есть путь NSString с именем файла модели, который я могу использовать, чтобы добраться до GeoModel

 - (GeoModel*) openGeoModel
 {

     GeoModel *geoModel;
     NSString* documentsDirectoryGeoModel =[FileManager getGeoModelAbsolutePath];



     if([FileManager fileExistsAtAbsolutePath:documentsDirectoryGeoModel])
     {

         NSData* data = [NSData dataWithContentsOfFile: documentsDirectoryGeoModel]; //]documentsDirectoryGeoModel];
         geoModel = [NSKeyedUnarchiver unarchiveObjectWithData: data];
         NSString *unarchivedGeoModelVersion = geoModel.geoModel_VersionID;

         if(![unarchivedGeoModelVersion isEqual: currentGeoModelVersion])
         {
             [FileManager deleteFile:documentsDirectoryGeoModel];
             geoModel = [GeoModel geoModelInit];
             [Utilities setGeoProjectCounter:0];
         }

     }
     else
     {
         geoModel  = [GeoModel geoModelInit];
     }

     [FileManager saveGeoModel];
     return geoModel;

 }

Который я затем могу сохранить в DocumentsDirectory следующим образом:

 + (BOOL)saveGeoModel
 {

     NSError *error = nil;
     NSString *path = [self getGeoModelAbsolutePath];
     [NSKeyedArchiver archiveRootObject:appDelegate.currentGeoModel toFile:path];

     NSData* encodedData = [NSKeyedArchiver archivedDataWithRootObject: appDelegate.currentGeoModel];
     BOOL success = [encodedData writeToFile: path options:NSDataWritingAtomic error:&error];

  return success;  
 }

Что всегда успешно - но настойчиво только в том случае, если я не выключаю устройство! Я не добиваюсь никакого прогресса в этом: любая помощь будет высоко ценится!

заранее спасибо

Тим Редфилд

1 ответ

Там. Я думаю, что на него дан ответ - если у кого-то еще нет комментариев о том, как улучшить перечисленные выше списки, они ДЕЙСТВУЮТ так, как должны!

Другие вопросы по тегам