来自JSON的数据直接parsing到UITableView
我正在使用这个代码使用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"}
这是searchfunction:
- (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);
}
那个糖果对象怎么了?
你有一系列的词典,下面是你如何parsing:
获取数组:
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比较滞后的原因是你在主线程上运行networking请求。
您可以通过asynchronous发送请求来解决这个问题,这意味着在不会冻结用户界面的后台线程中。
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 op将使TableView刷新表。 所以最初表格将是空白的。 一个人可能会略微捏造一下,最初呈现一个单元格说“数据正在加载”或任何让用户知道的一个操作正在进行中,如UIActivityIndicator。
阅读Grand Central Dispatch(GCD)
你可以在这里采取几种方法来提高性能。
- 尽快在您的应用程序中开始上传和请求机场。
- 恭维地尝试在后台线程中执行繁重的操作,调度一个asynchronous操作来构build你的Candy对象数组。 你可以使用dispatch_async。
- 另一种方法是有一些自定义逻辑,以避免一次创build整个数组…我会保持例如JSON结果(NSMutableDictionary * routeRes),并会按需(每次需要一个单元格)创build糖果对象,保留JSON中读取/创build的最后一个糖果索引的痕迹,以完成parsing所有字典(然后您可以开始阅读您的糖果arrays)…。 如果糖果创作逻辑不是太重(这不是我认为的),那可能会有效。