1

我已经为此苦苦挣扎了很久,我真的需要一些好的帮助。:) 我有一个应用程序,我将一个相当大的 JSON 解析为 appdelegate 的didFinishLaunchingWithOptions.

我的模型对象是:

标签:

NSString *title
NSMutableArray *categories

类别:

NSString *title
NSMutableArray *items

物品

NSString *title
NSString *description
UIImage *image

我需要在本地保存数据,因为每次我的应用程序启动时解析大约需要 15 秒。我正在使用 SBJSON 框架。

这是我的解析代码:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"json_template" ofType:@"json"];

    NSString *contents = [NSString stringWithContentsOfFile: filePath  encoding: NSUTF8StringEncoding error: nil];
    SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
    NSMutableDictionary *json = [jsonParser objectWithString: contents];
    tabs = [[NSMutableArray alloc] init];
    jsonParser = nil;

    for (NSString *tab in json)
    {
        Tab *tabObj = [[Tab alloc] init];
        tabObj.title = tab;

        NSDictionary *categoryDict = [[json valueForKey: tabObj.title] objectAtIndex: 0];
        for (NSString *key in categoryDict)
        {

            Category *catObj = [[Category alloc] init];
            catObj.name = key;


            NSArray *items = [categoryDict objectForKey:key];

            for (NSDictionary *dict in items)
            {
                Item *item = [[Item alloc] init];
                item.title = [dict objectForKey: @"title"];
                item.desc = [dict objectForKey: @"description"];
                item.url = [dict objectForKey: @"url"];
                if([dict objectForKey: @"image"] != [NSNull null])
                {
                    NSURL *imgUrl = [NSURL URLWithString: [dict objectForKey: @"image"]];
                    NSData *imageData = [NSData dataWithContentsOfURL: imgUrl];
                    item.image = [UIImage imageWithData: imageData];
                }
                else
                {
                    UIImage *image = [UIImage imageNamed: @"standard.png"];
                    item.image = image;
                }

                [catObj.items addObject: item];   
            } 
            [tabObj.categories addObject: catObj];
        } 
        [tabs addObject: tabObj];
    }

这样做的最佳方法是什么?使用核心数据或NSFileManager?如果你也有一些代码示例,那会让我很高兴。这是在应用程序准备好进入应用程序商店之前我需要修复的最后一件事,它简直要了我的命!我无法解决这个问题。

4

1 回答 1

2

如果您在 iOS 上工作,则将文件保存到 Documents 文件夹。在 Mac OS X 上,它将位于 Application Support 文件夹中。由于您使用的是 iOS,请阅读此答案以了解如何访问 Documents 文件夹。

您要存储的所有对象都应实现 NSCoding。上面的变量已经做了。如果您想直接存储选项卡、类别和项目,他们将需要实现 NSCoding。然后,您只需将它们序列化到文件中即可。打开您的应用程序时,您可以查找此文件并在不解析的情况下取回您的对象。

代码应如下所示(为简洁起见,省略了未经测试和错误检查):

- (void) saveStateToDocumentNamed:(NSString*)docName
{
    NSError       *error;
    NSFileManager *fileMan = [NSFileManager defaultManager];
    NSArray       *paths   = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString      *docPath = [paths[0] stringByAppendingPathComponent:docName];

    if ([fileMan fileExistsAtPath:docPath])
        [fileMan removeItemAtPath:docPath error:&error];

    // Create the dictionary with all the stuff you want to store locally
    NSDictionary *state = @{ ... };

    // There are many ways to write the state to a file. This is the simplest
    // but lacks error checking and recovery options.
    [NSKeyedArchiver archiveRootObject:state toFile:docPath];
}

- (NSDictionary*) stateFromDocumentNamed:(NSString*)docName
{
    NSError       *error;
    NSFileManager *fileMan = [NSFileManager defaultManager];
    NSArray       *paths   = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString      *docPath = [paths[0] stringByAppendingPathComponent:docName];

    if ([fileMan fileExistsAtPath:docPath])
        return [NSKeyedUnarchiver unarchiveObjectWithFile:docPath];

    return nil;
}
于 2013-04-28T17:25:37.973 回答