2014-01-18 18 views
6

Ich bin in der Storyboard arbeiten, aber ich nehme an jetzt ist es Zeit, den Code zu Gesicht ...Populate UITableView mit JSON-Array

Ich habe eine PHP-Datei auf meinem Server, der als ein den Inhalt meiner MySQL-Datenbank-Tabelle gibt Array im JSON-Format:

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

ich werde schließlich alle Daten benötigen, aber jetzt möchte ich nur für die Ausgabe der Stadt Felder als UITableView. Wie würde ich das machen?

+0

Möchten Sie wissen, wie Sie die Daten aus dem JSON-Objekt extrahieren? – Dinesh

+0

Ja, das und dann, wie sie in UITableView angezeigt werden. – Sebastian

+1

@Sebastian schreibe jetzt einen Leitfaden für dich auf. Bare mit mir. – Pavan

Antwort

18

Ich glaube, es war Im Jahr 2012/2013, wo Apple ein fantastisches Video über Code-Praktiken behandelte, war ein Unterthema eine gute und clevere Art, JSON-Objekte zu bearbeiten und Datenobjekte für sie zu erstellen. Es tut mir leid, dass ich den Namen des Videos vergessen habe. Wenn sich jemand daran erinnert, bitte bearbeite die Antwort für mich.

Welcher Apfel bedeckt war, um ein Datenobjekt zu haben, das jedes json-Objekt speichert. Wir werden dann ein Array erstellen, um diese Objekte zu speichern und auf die erforderlichen Felder zuzugreifen, wenn wir unser TableView auffüllen. In deinem Fall würdest du so etwas tun.

in Ihrem Projektnavigator eine Datei von NSObject Typ hinzufügen und den folgenden Code hinzu:

#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 

und in Ihrer .m Datei, die Sie diesen Code hinzufügen würde

#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 

Was Sie jetzt haben, ist ein Datenobjektklasse, die Sie überall in Ihrem Code verwenden können, wo immer erforderlich und greifen Sie die entsprechenden Details für die Tabelle, die Sie zeigen, ob es eine city Felder Tabelle oder eine city and name Tabelle usw. ist lch vermeide auch JSON-Decodierungscode überall in deinem Projekt. Was passiert, wenn sich der Name Ihrer "Schlüssel" ändert? Anstatt durch den Code zu scannen und alle Ihre Schlüssel zu korrigieren, gehen Sie einfach in die PlaceDataObject Klasse und ändern die entsprechende key und Ihre Anwendung wird weiter funktionieren.

von Apple erklärt dies gut.

„Modellobjekte Spezialwissen und Know-how stellen Sie halten Daten einer Anwendung und die Logik definieren, dass Daten manipuliert Eine gut gestaltete MVC-Anwendung gekapselt alle seine wichtigen Daten hat in. Modellobjekte .... sie repräsentieren Wissen und Expertise in Bezug auf eine spezifische Problemdomäne, sie sind tendenziell wiederverwendbar. "

Bestücken Sie Ihre Array mit benutzerdefinierten Objekte für jeden json-Eintrag, der in vom Server kommt

Jetzt ein Array dieses Brauches auf bevölkern Datenobjekt Sie gemacht haben. Nach dem MVC-Ansatz ist es wahrscheinlich am besten, dass Sie über alle Methoden verfügen, die Daten in einer anderen Klasse, Ihrer Model-Klasse, verarbeiten.Das empfiehlt Apple, diese Art von Methoden in eine separate Modellklasse zu integrieren, in der die gesamte Verarbeitung stattfindet.

Aber jetzt werden wir nur den folgenden Code zum View-Controller nur zu Demonstrationszwecken hinzufügen.

Erstellen Sie eine Methode in der m-Datei Ihres View-Controllers, die Ihr JSON-Array verarbeitet.

//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 
    } 
} 

und Sie möchten so die obige Methode aufrufen:

//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]; 
} 

Bestücken Ihre Tableview mit benutzerdefinierten Datenobjekte

Was Ihre Daten in Ihrem Tableview Bestücken Sie tun so wie dieses:

- (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); 
} 

Kurzer Haftungsausschluss: Der obige Code wurde nicht getestet, aber bitte lassen Sie mich wissen, ob alles funktioniert oder ob ich irgendwelche Zeichen weggelassen habe.

+1

Vielen Dank dafür, es sieht gut aus. Ich werde mich hinsetzen und es jetzt umsetzen und akzeptieren, wenn ich kann. – Sebastian

+0

Überprüfen Sie den Code jetzt, aktualisieren Sie Ihre Seite, da ich weitere Änderungen hinzugefügt habe, z. B. Array-Verifizierung usw. – Pavan

+0

Eine Frage - Ich habe meine Schnittstelle im Storyboard entwickelt, also habe ich keinen viewcontroller.m - gibt es irgendwo sonst lege ich diesen Code oder gibt es eine Möglichkeit, die Datei zu finden? – Sebastian

1

Wenn die Rohdaten von Ihrem Server in einem NSData-Objekt eingehen, können Sie sie mithilfe der NSJSONSerialization-Klasse analysieren.

Das heißt:

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]; 
    } 
} 

Nachdem Sie Ihre Auswahl an Städten fertig sind bevölkern, ist es das, was Sie Datenquelle Methoden in der Tabellenansicht des zurückkehren können:

- (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); 
} 
+0

Ich glaube nicht, dass dies der beste Weg ist, um Ihr Array zu füllen. – Pavan

+0

Vielleicht hast du recht, @Pavan. Kannst du eine Antwort machen, die einen besseren Weg hat, und ich werde es verbessern. –

+0

@michaeldatuermann Ja, das zu tun, wie wir sprechen. – Pavan

0

Was ist myCitysTable, Paven? soll das der Name des TableView sein? Ich habe Mühe, herauszufinden, wie man es nennt, wenn ja ...