例如,我有一个返回不同参数的 JSON 请求name
。我想为 name 参数缓存一个变量,以后可以在应用程序中查看。
例如:来自 JSON 请求的名称 = david。该变量被称为firstname
。firstname
应该等于“大卫”。firstname
应该存储,以便我可以在我的应用程序的所有部分中查看它。
对于像字符串这样简单的东西,快速而肮脏的解决方案是将其存储在NSUserDefaults
.
存储
[[NSUserDefaults standardDefaults] setObject:firstname forKey:@"kUserFirstName"];
[[NSUserDefaults standardDefaults] synchronize];
检索
NSString *string = [[NSUserDefaults standardDefaults] objectforKey:@"kUserFirstName"];
如果它变得比这更复杂,您必须考虑更结构化的持久性存储。一个有效的选项是CoreData。
有一些框架可以帮助您在 CoreData 中存储 JSON 资源,最有趣的是RestKit。
首先,您可能会考虑查看 RestKit,因为它成功地完成了 iOS 中的一系列服务器交互和 CoreData 持久性。
我的时间有点短(这里是午休时间),所以我会懒洋洋地从我拥有的应用程序中发布一个示例。
- (void)loadFiltersFromJSON {
NSString *path = [[NSBundle mainBundle] pathForResource:@"FreeFilterBank" ofType:@"json"];
NSData *filterData = [NSData dataWithContentsOfFile:path];
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:filterData options:kNilOptions error:&err];
if (err) { //TODO this can be removed prior to shipping the app
NSLog(@"%@", err);
}
NSArray *definedFilters = [json objectForKey:@"Filter"];
NSManagedObjectContext* moc = [self managedObjectContext];
for (NSDictionary *filter in definedFilters) {
NSString *name = [filter valueForKey:@"name"];
BOOL exists = [self alreadyExists:name inManagedObjectContext:moc];
if (!exists) {
NSString *imageNamed = [filter valueForKey:@"imageName"];
NSString *filterDesignator = [filter valueForKey:@"filterDesignator"];
NSString *paid = [filter valueForKey:@"paidOrFree"];
[self createFilterWithName:name imageNamed:imageNamed filterDesignator:filterDesignator paidOrFree:paid];
}
}
}
- (BOOL)alreadyExists:(NSString*)filterNamed inManagedObjectContext:(NSManagedObjectContext*)moc {
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name == %@", filterNamed];
NSEntityDescription* description = [NSEntityDescription entityForName:@"Filter" inManagedObjectContext:moc];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:description];
[request setPredicate:predicate];
NSError* error;
NSArray* fetchedResult = [moc executeFetchRequest:request error:&error];
if (error) {
NSLog(@"%@",error.localizedDescription);
}
if (fetchedResult.count == 0) {
return NO;
}
else {
return YES;
}
}
- (void)createFilterWithName:(NSString*)name imageNamed:(NSString*)imageName filterDesignator:(NSString*)designator paidOrFree:(NSString *)paid {
NSManagedObjectContext* moc = [self managedObjectContext];
Filter* newFilter = [NSEntityDescription insertNewObjectForEntityForName:@"Filter" inManagedObjectContext:moc];
newFilter.name = name;
newFilter.imageName = imageName;
newFilter.filterDesignator = designator;
newFilter.paidOrFree = paid;
NSError* error;
[moc save:&error];
if (error) {
NSLog(@"%@",error.localizedDescription);
}
}
TL;DR 这从存储在包中的 JSON 加载数据,检查 SQLite 数据存储以查看我们是否已经有同名的东西,如果没有,则创建该对象的新持久实例。
就拿这个例子来说吧,除了这个例子之外,还有更多调用从 Web 中提取的序列化数据和 iOS 中的持久数据。
最简单的方法是使用 NSUserDefaults 并将键设置为 @"firstname",值将是 @"david"。话虽如此,您可能会考虑使用更好的持久性模型,例如 CoreData。您还可以使用 Sqlite 数据库或将键/值保存在 plist 中。有很多方法可以做到这一点。
作为参考,请参见: Save string to the NSUserDefaults?