解析JSON并在本地保存

时间:2013-04-05 13:08:36

标签: ios objective-c json

我正在开发一个用Objective-C编写的iOS应用程序,我差不多完成了,除了一件事:

我正在将JSON解析为tableview,我想在应用程序中本地存储数据。但我不知道这样做的最好方法。每行都有一个图像,标题,描述和链接。我有不同的标签与不同的JSON。

(我不想在每次应用程序打开时解析JSON,我想检查是否有新内容添加到JSON中,然后再解析它。但是现在我很高兴,如果我能设法在本地保存JSON数据

我一直在努力解决这个问题,我真的需要一些帮助。这是应用程序为App Store做好准备之前需要修复的最后一件事。

不知道你是否需要查看任何代码,但无论如何我都会发布它,这样你就可以更好地理解我正在做的事情。

解析json的代码:

 jsonData_ = [[NSMutableData alloc] init];
    NSString *urlString = [NSString stringWithFormat:@"http://www.myUrl.se/json/%@.json", _whatState];
    NSURL *url = [NSURL URLWithString: urlString];
    NSURLRequest *urlReq = [NSURLRequest requestWithURL: url];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest: urlReq delegate:self];


-(void)connectionDidFinishLoading:(NSURLConnection*) connection{

    //NSLog(@"Succeeded! Recieved %d bytes of data", [jsonData_ length]);
    NSError *error;
    NSArray *items = [NSJSONSerialization JSONObjectWithData: jsonData_ options: kNilOptions error: &error];

    NSSortDescriptor *sortDesc = [[[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES]copy];
    NSMutableArray *sortedItems = [NSMutableArray arrayWithObject: sortDesc];
    sortedItems = [[items sortedArrayUsingDescriptors: sortedItems] copy];

    if(!error)
    {
        tableData_ = sortedItems;
        tableImgs_ = [[NSMutableArray alloc] initWithArray: tableData_ copyItems: YES];
        [self.tableView reloadData];
        jsonIsFinishedLoading = TRUE;

    }
    else
    {
        NSLog(@"ERROR");
    }
}

我的tableview代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *cellIdentifier = @"listItem";
    TSCustomCell *cell = (TSCustomCell*) [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    [cell setSelectedBackgroundView:selectedCellBgColorView];


    if(jsonIsFinishedLoading)
    {
        NSDictionary *row = [tableData_ objectAtIndex: indexPath.row];
        NSString *title = [row objectForKey:@"title"];

        cell.url = [row objectForKey:@"url"];
        UIFont *defaultFont = [UIFont fontWithName:@"Edmondsans-Bold" size:12.0];

        [cell.listItemLbl setText: title];
        [cell.listItemLbl setFont:defaultFont];


        if([[tableImgs_ objectAtIndex:indexPath.row] isMemberOfClass: [UIImage class]])
            {
                [cell.listItemImage setImage: [tableImgs_ objectAtIndex: indexPath.row]];
            }
            else
            {

                UIActivityIndicatorView *loadingSymbol = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
                loadingSymbol.frame = cell.listItemImage.frame;
                [cell addSubview: loadingSymbol];
                [loadingSymbol startAnimating];


                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);

                dispatch_async(queue, ^{


                    NSString *url = [row objectForKey: @"image"];

                    if([url isEqualToString: @""])
                    {
                        url = @"http://www.myUrl.se/images/standard.png";
                    }
                    else
                    {
                        url = [row objectForKey: @"image"];
                    }

                    NSURL *imgUrl = [NSURL URLWithString: url];
                    NSData *imageData = [NSData dataWithContentsOfURL: imgUrl];
                    UIImage *image = [UIImage imageWithData: imageData];

                    if(image != nil)
                    {
                        [tableImgs_ replaceObjectAtIndex:indexPath.row withObject:image];
                        NSLog(@"tableImgs != nil");

                    }
                    else
                    {
                        NSLog(@"tableImgs = nil");
                        [cell.listItemImage setImage: [UIImage imageNamed:@"standard_transp.png"]];
                    }

                    dispatch_sync(dispatch_get_main_queue(), ^{

                        [loadingSymbol removeFromSuperview];
                        [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationNone];


                    });  
                }); //end dispatch_async
            }
        }
    }


    return cell;

}

谢谢!

3 个答案:

答案 0 :(得分:1)

如果我理解你是对的 - 您可以使用此代码将JSOn的数据保存到用户默认值

[[NSUserDefaults standardUserDefaults] setObject:jsonData_ forKey:@"myData"];

如果要解析json - 你有数据

当你想要它时

jsonData_ = [[NSUserDefaults standardUserDefaults] valueForKey: @"myData"];

答案 1 :(得分:-2)

Here's a useful tutorial使用NSCoding ProtocolNSFileManager将对象保存到磁盘。如果为每行创建一个对象,您将能够保存它们。

您也可以使用此方法保存JSON本身,也可以将其存储在user defaults中。

# Saving
[[NSUserDefaults standardUserDefaults] setObject:jsonData forKey:@"json data"];
[[NSUserDefaults standardUserDefaults] synchronize]; // Generally happens automatically, but if this might happen close to backgrounding you'll want this

# Loading
jsonData = [[NSUserDefaults standardUserDefaults] objectForKey:@"json data"];

答案 2 :(得分:-3)

使用AFNetworking来实现这一目标。它比NSURLConnection更容易,更快速,更好。

在此处阅读更多内容:AFNetworking