- 关于如何使保存到文档目录的对象保留在驱动器上并在重新启动iDevice后可恢复的问题。
这是我的问题。我使用NSCoding创建一个数据对象并用数据填充它。每次更新对象中的数据时,我都会将它写入documentsDirectory。我停止应用程序并再次启动应用程序,我的数据对象仍然存在,包含所有数据。但是,如果我重新启动iPhone,我写的用于恢复和读取数据对象的代码将失败。
我写的代码最初只使用NSString作为文件路径。它在ios7下运行良好但在ios8下失败了。
阅读有关内容的文章,我从Apple文档中找到了这条线索:
"重要提示:虽然在您的应用运行时可以安全地使用它们,但是在应用启动之间存储和重复使用文件引用URL是不安全的,因为如果系统重新启动,文件ID可能会更改。如果要在启动应用程序之间持久存储文件的位置,请按照使用书签查找文件中所述创建书签。"
所以我重写了我的ios7文件open和file close方法,所以他们不再使用字符串或url,而是从使用NSUserDefaults保存的书签中获取字符串和url。同样的问题:只要我不关闭手机电源,一切正常,但一旦我这样做,一切都会丢失。我无法解决这个问题。
这是我目前的一系列步骤。首先,我使用书签确定(或者它是否已存在于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;
}
哪一项总是成功的 - 但只有在我不关闭设备的情况下才会持久!我没有取得任何进展:非常感谢任何帮助!
提前致谢
蒂姆雷德菲尔德答案 0 :(得分:0)
有。我认为它得到了回答 - 除非其他人对如何改进上述列表发表评论,否则他们应该按照应有的方式工作!