简体   繁体   English

NSKeyedArchiver不保留数据

[英]NSKeyedArchiver not persisting data

So, my app queries an Amazon Dynamo DB database and retrieves a few kilobytes worth of data. 因此,我的应用程序查询了Amazon Dynamo数据库数据库并检索了几千字节的数据。 What I want the app to do is download everything the first time, and then every time after, just download a timestamp to see if it has the most recent version of the data. 我希望应用程序执行的操作是第一次下载所有内容,然后每次下载之后,只需下载一个时间戳记以查看其是否具有最新版本的数据。 So that I only have to download the data every once in a while, I'm trying to use NSKeyedArchiver to archive the array that I'm downloading. 为了只需要每隔一段时间下载一次数据,我尝试使用NSKeyedArchiver来存档要下载的阵列。 I have tried this three different ways, and none of them work on an iPhone, although two of them work on the simulator. 我尝试了这三种不同的方式,尽管它们中的两种都在模拟器上运行,但是它们都无法在iPhone上运行。

[NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"dataArray.archive"];

This does not work on the simulator nor the actual iphone. 这不适用于模拟器或实际的iphone。 The result of this method is NO. 此方法的结果为否。

The next thing I used was the full path: 我接下来使用的是完整路径:

[NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"Users/Corey/Desktop/.../dataArray.archive"];

And this worked on the simulator, but not on the iPhone. 这适用于模拟器,但不适用于iPhone。 My guess was that when compiled, the filesystem looks different (and obviously doesn't have the same path). 我的猜测是,在编译时,文件系统看起来有所不同(并且显然没有相同的路径)。 So next I tried: 所以接下来我尝试了:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"dataArray" ofType:@".archive"];

[NSKeyedArchiver archiveRootObject:self.dataArray toFile:filePath];

Once again, this works on the simulator but fails on the iphone. 再次,这在模拟器上有效,但在iphone上失败。 I have confirmed that all of the data is in self.dataArray before writing to the archive, and confirmed that the array is nil after writing back to the archive (in the iphone version). 我已确认所有数据在写入存档之前都在self.dataArray中,并确认在写回存档之后(在iPhone版本中)该数组为nil。 Any ideas what's going on? 有什么想法吗? Is there a better way to do the filepath? 有没有更好的方法来执行文件路径?

This is what I tracked down: 这是我所追踪的:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent: @"dataArray.archive"];
[NSKeyedArchiver archiveRootObject:your_object toFile:filePath];

and it worked perfectly on both the simulator and the iPhone! 它在模拟器和iPhone上均能完美运行!

[NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"dataArray.archive"];

You have to provide a full path. 您必须提供完整的路径。

[NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"Users/Corey/Desktop/.../dataArray.archive"];

That is not a full path. 那不是一条完整的路。 A full path begins with / and does not have /../ anywhere. 完整路径以/开头,并且在任何地方都没有/../

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"dataArray" ofType:@".archive"];

You do not have permission to write inside the mainBundle, it is read only. 您无权在mainBundle中写入,它是只读的。

Also, in general you shouldn't use file paths, you should use URLs. 另外,通常不应使用文件路径,而应使用URL。 Some APIs (including this one) requires a path but URLs are the recommended approach these days. 某些API(包括该API)需要一个路径,但是最近推荐使用URL。

Here's the proper way to write the file to disk: 这是将文件写入磁盘的正确方法:

NSURL *applicationSupportUrl = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask][0];

applicationSupportUrl = [applicationSupportUrl URLByAppendingPathComponent:@"My App"]; // replace with your app name

if (![applicationSupportUrl checkResourceIsReachableAndReturnError:NULL]) {
  [[NSFileManager defaultManager] createDirectoryAtURL:applicationSupportUrl withIntermediateDirectories:YES attributes:@{} error:NULL];
}

NSURL *archiveUrl = [applicationSupportUrl URLByAppendingPathComponent:@"foo.archive"];
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:archiveUrl.path];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM