Непостоянство объекта, записанного в 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 ответ
Там. Я думаю, что на него дан ответ - если у кого-то еще нет комментариев о том, как улучшить перечисленные выше списки, они ДЕЙСТВУЮТ так, как должны!