使用JSON数组填充UITableView

我正在Storyboard中工作,但我认为现在是面对代码的时候了…

我的服务器上有一个PHP文件,它以JSON格式输出我的MySQL数据库表的内容:

{ "id":"2", "name":"The King's Arms", "city":"London", "day":"Tuesday", } 

我将最终需要所有的数据,但现在我只想输出城市字段作为UITableView。 我怎么去做这个?

我相信是在2012/2013年,苹果在代码实践上覆盖了一个精彩的video,突出的一个子主题是处理JSON对象和为它们创build数据对象的一个​​很好的方法。 对不起,我忘记了实际video的名称,如果有人记得,请为我编辑答案。

苹果覆盖了什么是有一个数据对象,存储每个json对象。 然后我们将创build一个数组来存储这些对象,并在填充tableView时适当地访问必要的字段。 所以在你的情况下,你会做这样的事情。

在项目导航器中添加一个NSObjecttypes的文件并添加下面的代码:

 #import <Foundation/Foundation.h> @interface PlaceDataObject : NSObject -(id)initWithJSONData:(NSDictionary*)data; @property (assign) NSInteger placeId; @property (strong) NSString *placeName; @property (strong) NSString *placeCity; @property (strong) NSString *placeDay; @end 

并在您的.m文件中,您将添加此代码

 #import "PlaceDataObject.h" @implementation PlaceDataObject @synthesize placeId; @synthesize placeName; @synthesize placeCity; @synthesize placeDay; -(id)initWithJSONData:(NSDictionary*)data{ self = [super init]; if(self){ //NSLog(@"initWithJSONData method called"); self.placeId = [[data objectForKey:@"id"] integerValue]; self.placeName = [data objectForKey:@"name"]; self.placeCity = [data objectForKey:@"city"]; self.placeDay = [data objectForKey:@"day"]; } return self; } @end 

你现在拥有的是一个数据对象类,你可以在任何需要的代码中随处使用数据对象类,并为你显示的任何表获取适当的细节,无论是city字段表还是city and name表等等。通过这样做,也将避免在你的项目中到处都有json解码代码。 当你的'钥匙'的名字改变时会发生什么? 而不是通过你的代码来纠正你的所有密钥,你只需要去PlaceDataObject类,并改变appriopriate key ,你的应用程序将继续工作。

苹果解释得很清楚:

模型对象代表了特殊的知识和专业知识,它们拥有应用程序的数据,并定义操纵数据的逻辑。一个devise良好的MVC应用程序将所有重要的数据封装在模型对象中。具体的问题领域,他们往往是可重用的。“

使用来自服务器的每个json条目的自定义对象填充数组

现在填充你所做的这个自定义数据对象的数组。 现在遵循MVC方法,最好的办法是将所有处理数据的方法都放在不同的类(Model类)中。 这就是苹果公司build议把这种方法放在一个单独的模型类中,所有的处理过程都是这样的。

但是现在我们只是将下面的代码添加到View Controller中,仅用于演示目的。

在视图控制器的m文件中创build一个方法来处理你的JSON数组。

 //make sure you have a global NSMutableArray *placesArray in your view controllers.h file. -(void)setupPlacesFromJSONArray:(NSData*)dataFromServerArray{ NSError *error; NSMutableArray *placesArray = [[NSMutableArray alloc] init]; NSArray *arrayFromServer = [NSJSONSerialization JSONObjectWithData:dataFromServerArray options:0 error:error]; if(error){ NSLog(@"error parsing the json data from server with error description - %@", [error localizedDescription]); } else { placesArray = [[NSMutableArray alloc] init]; for(NSDictionary *eachPlace in arrayFromServer) { PlaceDataObject *place = [PlaceDataObject alloc] initWithJSONData:eachPlace]; [placesArray addObject:place]; } //Now you have your placesArray filled up with all your data objects } } 

你可以这样调用上面的方法:

 //This is not what your retrievedConnection method name looks like ;) // but you call the setupPlacesFromJSONArray method inside your connection success method -(void)connectionWasASuccess:(NSData *)data{ [self setupPlacesFromJSONArray:data]; } 

用你的自定义数据对象填充你的tableView

至于在你的TableView中填充你的数据,你可以这样做:

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ //We check against table to make sure we are displaying the right number of cells // for the appropriate table. This is so that things will work even if one day you //decide that you want to have two tables instead of one. if(tableView == myCitysTable){ return([placesArray count]); } return 0; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if(cell) { //set your configuration of your cell } //The beauty of this is that you have all your data in one object and grab WHATEVER you like //This way in the future you can add another field without doing much. if([placesArray count] == 0){ cell.textLabel.text = @"no places to show"; } else{ PlacesDataObject *currentPlace = [placesArray objectAtIndex:indexPath.row]; cell.textLabel.text = [currentPlace placeCity]; // in the future you can grab whatever data you need like this //[currentPlace placeName], or [currentPlace placeDay]; } return(cell); } 

简短的免责声明:上面的代码还没有经过testing,但请让我知道,如果一切正常,或者我已经排除任何字符。

如果您的服务器的原始数据到达NSData对象,则可以使用NSJSONSerialization类为您parsing。

那是:

  NSError *error; NSMutableArray *cityArray = [[NSMutableArray alloc] init]; NSArray *arrayFromServer = [NSJSONSerialization JSONObjectWithData:dataFromServer options:0 error:error]; if(arrayFromServer) { NSLog(@"error parsing data - %@", [error localizedDescription]); } else { for(NSDictionary *eachEntry in arrayFromServer) { NSString *city = [eachEntry objectForKey:@"city"]; [cityArray addObject: city]; } } 

完成填充城市数组后,这就是您可以在表视图的数据源方法中返回的内容:

 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; // your table only has one section, right? } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if(section == 0) { return([cityArray count]); } NSLog(@"if we're at this place in the code, your numberOfSectionsInTableView is returning something other than 1"); return 0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // are you using standard (default) cells or custom cells in your storyboard? UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if(cell) { cell.text = [cityArray objectAtIndex:indexPath.row]; } return(cell); } 

什么是我的城市表,帕文? 那是否应该是TableView的名字? 如果是的话,我正在努力弄清楚如何命名它…