从 JSON 解析数据直接到 UITableView

Posted

技术标签:

【中文标题】从 JSON 解析数据直接到 UITableView【英文标题】:Data from JSON Parsing straight to UITableView 【发布时间】:2014-03-31 23:56:14 【问题描述】:

我正在使用带有此代码的 json 获取数据,我需要在包含两部分代码的 tableview 中显示它,并将其命名为问题是将其全部写入数组需要永远并且数组返回 null。如何将每个返回的元素作为其自己的 tableview 单元格?返还数百个机场。

 NSString* path = @"https://api.flightstats.com/flex/airports/rest/v1/json/active?appId=id&appKey=appkey";

NSMutableURLRequest* _request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:path]];
[_request setHTTPMethod:@"GET"];
NSURLResponse *response = nil;
NSError *error = nil;

NSData* _connectionData = [NSURLConnection sendSynchronousRequest:_request returningResponse:&response error:&error];

if(nil != error)

    NSLog(@"Error: %@", error);

else

    NSMutableDictionary* json = nil;

    if(nil != _connectionData)
    
        json = [NSJSONSerialization JSONObjectWithData:_connectionData options:NSJSONReadingMutableContainers error:&error];
    
    if (error || !json)
    
        NSLog(@"Could not parse loaded json with error:%@", error);
    
    else
    
        NSMutableDictionary *routeRes;
        routeRes = [json objectForKey:@"airports"];

        for(NSMutableDictionary *flight in routeRes)
        
            NSLog(@"ident is %@", [flight objectForKey:@"name"]);
            NSString *code=[json objectForKey:@"fs"];
            NSString *name=[flight objectForKey:@"name"];
            NSLog(@"code %@, name %@", code, name);

            [candyArray addObject:[Candy code:code name:name]];
        
    
    _connectionData = nil;
    NSLog(@"connection done");

以下是未显示任何内容的 cellForRowatIndex

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

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if ( cell == nil ) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    

    // Create a new Candy Object
    Candy *candy = nil;

    // Check to see whether the normal table or search results table is being displayed and set the Candy object from the appropriate array
    if (tableView == self.searchDisplayController.searchResultsTableView)
    
        candy = [filteredCandyArray objectAtIndex:[indexPath row]];
    
    else
    
        candy = [candyArray objectAtIndex:[indexPath row]];
    

    // Configure the cell
    [[cell textLabel] setText:[candy name]];
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];

    return cell;

这是返回的 json 的示例

"airports":["fs":"CLO","iata":"CLO","icao":"SKCL","name":"Alfonso B. Aragon Airport","city":"Cali","cityCode":"CLO","countryCode":"CO","countryName":"Colombia","regionName":"South America","timeZoneRegionName":"America/Bogota","localTime":"2014-03-31T18:51:58.372","utcOffsetHours":-5.0,"latitude":3.543056,"longitude":-76.381389,"elevationFeet":3162,"classification":3,"active":true,"delayIndexUrl":"https://api.flightstats.com/flex/delayindex/rest/v1/json/airports/CLO?codeType=fs","weatherUrl":"https://api.flightstats.com/flex/weather/rest/v1/json/all/CLO?codeType=fs"

这是搜索功能:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope

// Update the filtered array based on the search text and scope.

    // Remove all objects from the filtered search array
[self.filteredCandyArray removeAllObjects];

// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchText];
NSArray *tempArray = [airportsArray filteredArrayUsingPredicate:predicate];
NSLog(@" text %@", searchText);


filteredCandyArray = [NSMutableArray arrayWithArray:tempArray];
NSLog(@"NSLog %@", scope);

【问题讨论】:

它所占用的一些“永远”是由于应用程序在请求运行时阻塞了主线程。您需要使用 sendAsnych 解决此问题。但在此之前,请检查您是否正在取回数据。 NSLog(@"开始");在发送请求之前,和 NSLog(@"json=%@", json);在 JSON 解析之后。 好吧,你需要告诉我们 JSON 是什么样子的。 我将它添加到我的帖子中,但值正在返回 NSLog(@"code %@, name %@", code, name);我需要弄清楚如何将这些信息放在 tableview 中。 我认为没有任何真正需要拥有您的 Candy 对象。只需将“飞行” NSDictionary 对象添加到您的 NSArray 并直接使用它们。 您发布的 JSON 与您尝试反汇编的 JSON 不同。我在任何地方都没有看到包含“机场”的字典,并且代码不承认数组的存在,而实际上航班被包含在数组中。 【参考方案1】:

那个糖果是怎么回事?

你有一个字典数组,下面是你如何解析它:

获取数组:

NSArray *airportsArray = [json objectForKey:@"airports"];

设置单元格文本:

[[cell textLabel] setText:[[airportsArray objectAtIndex:indexPath.row]objectForKey:@"name"]];
[[cell detailTextLabel] setText:[[airportsArray objectAtIndex:indexPath.row]objectForKey:@"code"]];

或者为了更好的可读性:

NSDictionary *airportAtIndex = [airportsArray objectAtIndex:indexPath.row];
[[cell textLabel] setText:[airportAtIndex objectForKey:@"name"]];
[[cell detailTextLabel] setText:[airportAtIndex objectForKey:@"code"]];

您能否详细说明我如何使用 sendAsynch 来加快处理速度?

好的,首先要注意的是,您没有在这里加速任何东西,您感觉 UI 滞后的原因是因为您在主线程上运行网络请求。

您可以通过异步发送请求来解决该问题,这意味着在不会冻结您的用户界面的后台线程中。

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
    //this is where you perform the network request
    //You can fetch data, in your case get the JSON
    dispatch_async(dispatch_get_main_queue(), ^(void)
        //in this block you want to manipulate the the User Interface
        //this is where you reload the tableView
        //or stop an activity indicator
        [self.tableView reloadData];
    );
);

注意事项(来自@HotLicks)

必须设置应用程序,以便 TableView 委托最初将 (在下载数据之前)在该部分报告零行。然后, reloadData 操作将导致 TableView 刷新表。所以 最初该表将为空白。可以稍微捏造一下 最初显示一个单元格,说“数据正在加载”或任何让用户知道>操作正在进行的内容,例如 UIActivityIndi​​cator。

阅读Grand Central Dispatch (GCD)

【讨论】:

您能否详细说明我如何使用 sendAsynch 来加快进程? @user1828081 我扩展了我的答案 应该注意,必须设置应用程序,以便 TableView 委托最初(在下载数据之前)报告该部分中的零行。然后,reloadData 操作将导致 TableView 刷新表。所以最初表格是空白的。可以稍微捏造一下,以首先显示一个单元格,说“数据正在加载”或其他任何内容。 @HotLicks 是的,完全正确,我试图在 cmets 中展示,可能不太清楚,我会再编辑一点。 感谢您的帮助!抱歉,我还有一个问题,我的搜索功能不起作用(添加到问题中)我假设我错过了一些基于更改数据检索和显示方式的愚蠢的东西。【参考方案2】:

您可以在这里采取多种方法来提高性能。

    尽快在您的应用程序中开始上传和请求机场。 免费尝试在后台线程中执行任何繁重的操作,调度异步操作来构建 Candy 对象数组。您可以使用 dispatch_async。 另一种方法是使用某种自定义逻辑来避免一次创建整个数组……例如,我将保留 JSON 结果 (NSMutableDictionary *routeRes) 并按需创建 Candy 对象(每次一个单元格必需),跟踪在 JSON 中读取/创建的最后一个 Candy 索引,以完成对所有字典的解析(然后您可以开始读取您的糖果数组)……。如果 Candy 创建逻辑不太重(我认为不是),这可能会起作用。

【讨论】:

以上是关于从 JSON 解析数据直接到 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何让我检索到的(来自 mysql)JSON 解析数据添加到 ListView 每分钟刷新一次

Linux json解析jq

json snippett for FTP vs SFTP sublime sftp(直接到wp主题文件夹)

json数据解析出错应该怎么办

Android中解析JSON格式数据常见方法合集

对于大数据量的Json解析