如何在本地存储JSON资源?

时间:2013-10-24 19:25:35

标签: ios json caching

我有一个JSON请求,它返回不同的参数,例如name。我想为name参数缓存一个变量,稍后我可以在应用程序中查看该变量。

例如:来自JSON request = david的名称。该变量称为firstnamefirstname应该等于“大卫”。应存储firstname,以便我可以在应用的所有部分中查看它。

3 个答案:

答案 0 :(得分:2)

对于简单的字符串,快速而肮脏的解决方案是将其存储在NSUserDefaults中。

贮藏

[[NSUserDefaults standardDefaults] setObject:firstname forKey:@"kUserFirstName"];
[[NSUserDefaults standardDefaults] synchronize];

检索

NSString *string = [[NSUserDefaults standardDefaults] objectforKey:@"kUserFirstName"];

如果它变得更复杂,你必须考虑一个更结构化的持久性存储。有效选项为CoreData

有一些框架可以帮助您在CoreData中存储JSON资源,最有趣的是RestKit

答案 1 :(得分:1)

首先,您可以考虑checking out 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这将从存储在bundle中的JSON加载数据,检查SQLite数据存储以查看我们是否已经拥有相同名称的东西,如果不这样做,则创建该对象的新持久化实例。 / p>

以你的例子为例,除了这个例子之外,还有很多对从网络中提取的序列化数据和iOS内的持久数据的调用。

答案 2 :(得分:0)

最简单的方法是使用NSUserDefaults并将密钥设置为@“firstname”,值为@“david”。话虽这么说,您可以考虑使用更好的持久性模型,如CoreData。您还可以使用Sqlite数据库或将键/值保存在plist中。有很多方法可以做到这一点。

供参考,请参阅: Save string to the NSUserDefaults?