Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 来自JSON数据的分组表视图_Ios_Objective C_Json_Uitableview - Fatal编程技术网

Ios 来自JSON数据的分组表视图

Ios 来自JSON数据的分组表视图,ios,objective-c,json,uitableview,Ios,Objective C,Json,Uitableview,我一直在关注YouTube上的一个教程,并试图扩展它的功能。我了解了如何使用GCD将retrieveData方法发送到后台线程,了解了如何使用可达性防止应用程序在飞行模式下崩溃,现在我正尝试将tableview更改为分组样式。几个星期后,我就不知所措了 我想做的是使用键“country”对UITableView进行分组以建立组,并且该国家/地区内的任何城市都会显示在组的单元格中。数据库中的国家数量将发生变化,城市数量也将发生变化 考虑到数据结构,我甚至不确定这是否可行,但如果可行,我可以提出一些

我一直在关注YouTube上的一个教程,并试图扩展它的功能。我了解了如何使用GCD将retrieveData方法发送到后台线程,了解了如何使用可达性防止应用程序在飞行模式下崩溃,现在我正尝试将tableview更改为分组样式。几个星期后,我就不知所措了

我想做的是使用键“country”对UITableView进行分组以建立组,并且该国家/地区内的任何城市都会显示在组的单元格中。数据库中的国家数量将发生变化,城市数量也将发生变化

考虑到数据结构,我甚至不确定这是否可行,但如果可行,我可以提出一些建议

JSON数据的结构如下所示:

// you probably want to save these as instance properties
NSMutableArray *countries = [NSMutableArray new];
NSMutableDictionary *citiesForCountries = [NSMutableDictionary new];

for(City *city in citiesArray)
{
    NSString *currentCountry = city.country;

    NSMutableArray *citiesInCountry = citiesForCountries[@"currentCountry"];
    // first city for this country, so add it to our ordered list and create an array to populate with cities
    if(! citiesInCountry)
    {
        [countries addObject:currentCountry];
        citiesInCountry = [NSMutableArray new];
        citiesForCountries[@"currentCountry"] = citiesInCountry;
    }
    [citiesInCountry addObject:city]; 
}

// Then here are some of the relevant methods on how you would use these data structures
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return countries.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    NSString *country = countries[section];
    NSArray *cities = citiesForCountries[country];
    return cities.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    City * cityObject;

    NSString *country = countries[indexPath.section];
    NSArray *cities = citiesForCountries[country];
    cityObject = cities[indexPath.row];

    cell.textLabel.text = cityObject.cityName;
    cell.detailTextLabel.text = cityObject.cityCountry;

    //Accessory
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}
[{“id”:“1”,“城市名称”:“伦敦”,“城市州”:“伦敦”,“城市人口”:“8173194”,“国家”:“联合王国”}

以下是.m文件:

#import "CitiesViewController.h"
#import "City.h"
#import "DetailViewController.h"
#import "Reachability.h"

#define getDataUrl @"http://www.conkave.com/iosdemos/json.php"

@interface CitiesViewController ()

@end

@implementation CitiesViewController
@synthesize jsonArray, citiesArray;

- (void)viewDidLoad {
[super viewDidLoad];

//Set the title of our VC
self.title = @"Cities of the World";

//Load data
[self retrieveData];    

}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

// Return the number of sections.
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

// Return the number of rows in the section.
return citiesArray.count;
}

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

{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

// Configure the cell...
City * cityObject;
cityObject = [citiesArray objectAtIndex:indexPath.row];

cell.textLabel.text = cityObject.cityName;
cell.detailTextLabel.text = cityObject.cityCountry;

//Accessory
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

return cell;
}

#pragma mark - Navigation


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.

if ([[segue identifier] isEqualToString:@"pushDetailView"])
{
    NSIndexPath * indexPath = [self.tableView indexPathForSelectedRow];

    //Get the object for the selected row
    City * object = [citiesArray objectAtIndex:indexPath.row];

    [[segue destinationViewController] getCity:object];
    }
}


#pragma mark -
#pragma mark Class Methods

- (void) retrieveData;
{

Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable) {

        UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"No Internet"
                                                          message:@"You must have an internet connection for this feature"
                                                         delegate:self
                                                cancelButtonTitle:@"OK"
                                                otherButtonTitles:nil];
        [message show];
        [self.refreshControl endRefreshing];
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        return;
    }

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
//Retrieve the data asynchronously
dispatch_async(queue, ^{

    NSURL * url = [NSURL URLWithString:getDataUrl];

    NSData * data = [NSData dataWithContentsOfURL:url];

    jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

    //Set up our cities array
    citiesArray = [[NSMutableArray alloc] init];

    //Loop through our jsonArray

    for (int i = 0; i < jsonArray.count; i++)
    {
        //Create our city object
        NSString * cID = [[jsonArray objectAtIndex:i] objectForKey:@"id"];
        NSString * cName = [[jsonArray objectAtIndex:i] objectForKey:@"cityName"];
        NSString * cState = [[jsonArray objectAtIndex:i] objectForKey:@"cityState"];
        NSString * cPopulation = [[jsonArray objectAtIndex:i] objectForKey:@"cityPopulation"];
        NSString * cCountry = [[jsonArray objectAtIndex:i] objectForKey:@"country"];

        //Add the city object to our cities array
        [citiesArray addObject:[[City alloc] initWithCityName:cName andCityState:cState andCityCountry:cCountry andcityPopulation:cPopulation andCityID:cID]];


    }
    //Back to main thread to update UI.use dispatch_get_main_queue() to get main thread
    dispatch_sync(dispatch_get_main_queue(), ^{

        //Reload our table view
        [self.tableView reloadData];

    });

});

}
@end
#导入“CitiesViewController.h”
#导入“City.h”
#导入“DetailViewController.h”
#导入“可达性.h”
#定义getDataUrl@“http://www.conkave.com/iosdemos/json.php"
@接口CitiesViewController()
@结束
@CitiesViewController的实现
@综合jsonArray、citiesArray;
-(无效)viewDidLoad{
[超级视图下载];
//设置我们VC的标题
self.title=@“世界城市”;
//加载数据
[自检索数据];
}
-(无效)未收到记忆警告{
[超级记忆警告];
//处置所有可以重新创建的资源。
}
#pragma标记-表视图数据源
-(NSInteger)表格视图中的节数:(UITableView*)表格视图{
//返回节数。
返回1;
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节{
//返回节中的行数。
返回citiesArray.count;
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
静态NSString*CellIdentifier=@“Cell”;
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//配置单元格。。。
城市*城市对象;
cityObject=[CitieArray对象索引:indexath.row];
cell.textlab.text=cityObject.cityName;
cell.detailTextLabel.text=cityObject.cityCountry;
//附属品
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
返回单元;
}
#pragma标记-导航
-(void)prepareForSegue:(UIStoryboardSegue*)segue发送方:(id)发送方{
//使用[segue destinationViewController]获取新的视图控制器。
//将选定对象传递给新的视图控制器。
if([[segue identifier]isEqualToString:@“pushDetailView”])
{
NSIndexPath*indexPath=[self.tableView indexPathForSelectedRow];
//获取所选行的对象
City*object=[CitieArray objectAtIndex:indexPath.row];
[[segue destinationViewController]获取城市:对象];
}
}
#布拉格标记-
#pragma标记类方法
-(无效)检索数据;
{
可达性*网络可达性=[Reachability Reachability For InternetConnection];
NetworkStatus NetworkStatus=[networkReachability currentReachabilityStatus];
if(网络状态==不可访问){
UIAlertView*消息=[[UIAlertView alloc]initWithTitle:@“无互联网”
消息:@“您必须具有此功能的internet连接”
代表:赛尔夫
取消按钮:@“确定”
其他按钮:无];
[信息显示];
[自我刷新控制结束刷新];
[UIApplication sharedApplication].networkActivityIndicatorVisible=否;
回来
}
调度队列=调度获取全局队列(调度队列优先级高,0ul);
//异步检索数据
调度异步(队列^{
NSURL*url=[NSURL URLWithString:getDataUrl];
NSData*data=[NSData dataWithContentsOfURL:url];
jsonArray=[NSJSONSerialization JSONObjectWithData:数据选项:针织错误:nil];
//建立我们的城市阵列
CitieArray=[[NSMutableArray alloc]init];
//循环浏览我们的jsonArray
for(int i=0;i
您可以通过几种方法轻松地对数据进行分组。一种方法是使用数组对国家进行排序,并使用字典对其中的城市进行分组

创建完
城市
对象后,可以执行以下操作:

// you probably want to save these as instance properties
NSMutableArray *countries = [NSMutableArray new];
NSMutableDictionary *citiesForCountries = [NSMutableDictionary new];

for(City *city in citiesArray)
{
    NSString *currentCountry = city.country;

    NSMutableArray *citiesInCountry = citiesForCountries[@"currentCountry"];
    // first city for this country, so add it to our ordered list and create an array to populate with cities
    if(! citiesInCountry)
    {
        [countries addObject:currentCountry];
        citiesInCountry = [NSMutableArray new];
        citiesForCountries[@"currentCountry"] = citiesInCountry;
    }
    [citiesInCountry addObject:city]; 
}

// Then here are some of the relevant methods on how you would use these data structures
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return countries.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    NSString *country = countries[section];
    NSArray *cities = citiesForCountries[country];
    return cities.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    City * cityObject;

    NSString *country = countries[indexPath.section];
    NSArray *cities = citiesForCountries[country];
    cityObject = cities[indexPath.row];

    cell.textLabel.text = cityObject.cityName;
    cell.detailTextLabel.text = cityObject.cityCountry;

    //Accessory
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

谢谢。不过有几个问题。你说“创建完城市对象后…”我不确定您引用的确切位置。City是一个类,对象是在City.h和City.m文档中创建的,但它似乎不是您发布代码的正确位置。其次,我收到关于在本地声明变量的警告,以及一个错误,上面写着“country”在类型为City的对象上找不到。如果我好像迷路了,很抱歉-我迷路了。我指的地方是在您完成后立即在您的
retrieveData
方法中