2017-12-29 35 views
0

Ich versuche, Json mit iOS zu lernen. Ich versuche json Daten mit UITableView zu implementieren. In meiner Tabellenansicht in Titel und Untertitel werden die Werte angezeigt. Ich kann Daten in Titel laden, aber wenn versuchen, Untertitel zu laden, wird App abgestürzt, weil im Untertitel Ergebnis dieses Feld von JSON und in dem viele Schlüsselpaar Wert gegeben ist. So kann es nicht möglich sein, in der Tabellenansicht in Untertiteln anzuzeigen.How To Check Schlüssel in Schlüsselpaar ist verfügbar oder nicht?

Meine Frage ist, wie kann ich Untertitel laden und wenn Schlüssel in vielen Schlüsselpaar Wert verfügbar ist, wenn Sie auf klicken, wird es umgeleitet, um andere Tabellenansicht für die Anzeige dieser Daten.

Mein Code:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://query.yahooapis.com/v1/public/yql?q=select+*+from+weather.forecast+where+woeid%3D1100661&format=json"]]; 
    NSError *error=nil; 
    id response=[NSJSONSerialization JSONObjectWithData:data options: 
       NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error]; 
    if (error) { 
     NSLog(@"%@",[error localizedDescription]); 
    } else { 
     _query = [response objectForKey:@"query"]; 
     NSLog(@"%@",_query); 
     _keyArray = [_query allKeys]; 
    } 
} 


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [_keyArray count]; 
} 

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

    NSString *key = [_keyArray objectAtIndex:indexPath.row]; 
    //NSString *dictionary = [_query objectForKey:key]; 
    NSString *dictionary = [_query objectForKey:key]; 
    cell.textLabel.text = key; 
    cell.detailTextLabel.text = dictionary; 
    return cell; 
} 

Dank.

+0

Hängt davon ab .. Was möchten Sie in cell.detailTextLabel anzeigen? –

+0

Ich versuche sehr hart zu verstehen, was Sie wirklich als Ausgabe hier bekommen wollen, aber ich kann nicht. Bitte fügen Sie ein Bild hinzu, wo erwähnt wird, was Sie wirklich wollen. –

+0

Wenn der Wert des Untertitels ein neues Wörterbuch ist, möchten Sie die Tabellenansicht erweitern oder in eine neue Tabellenansicht wechseln, um das Unterschlüssel-Wert-Paar anzuzeigen. –

Antwort

1

Dinge, die ich habe aus Ihrer Frage und Kommentaren zu verstehen, hier ist meine Antwort Schritt für Schritt ...

Zuerst habe ich genommen eine NSArray und eine NSDictionary Eigenschaft in meiner ViewController.h Klasse wie folgt.

{ 
NSArray *_allKeys; 
} 
@property(nonatomic,strong) NSDictionary *query; 

Dann in ViewController.m Ich habe eine Setter-Methode für query Eigenschaft erstellt, wo ich die Daten in _query und _allKeys wie diese bin die Einrichtung ...

-(void)setQuery:(NSDictionary *)query 
{ 
    _query = query; 
    _allKeys = [_query allKeys]; 
    if ([self isViewLoaded]) { 
     [tableView reloadData]; 
    } 

} 

Jetzt in UITableView Datenquelle Methode cellForRow, I habe deinen Code aktualisiert ..

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; 
    NSString *key = _allKeys[indexPath.row]; 
    id value = _query[key]; 
    cell.textLabel.text = key; 
    if ([value isKindOfClass: [NSString class]]) { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
     cell.detailTextLabel.text = (NSString*)value; 
    } 
    else if ([value isKindOfClass: [NSDictionary class]]) 
    { 
     cell.detailTextLabel.text = @"More Info"; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    } 
    else if ([value isKindOfClass: [NSArray class]]) 


     { 
      cell.detailTextLabel.text = @"Multiple Entries Found"; 
      cell.accessoryType = UITableViewCellAccessoryNone; 

// do something show array data with prototype custom cell 
     } 
     return cell; 
    } 

Und jetzt in UITableView Delegatmethode didSelect, habe ich für gleiche eine neue Instanz erstellen ViewController (Wir können es wieder verwenden, weil es gleiche UI-Layout hat) und das Bestehen der Wert von _query ...

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *key = _allKeys[indexPath.row]; 
    id value = _query[key]; 
    if ([value isKindOfClass: [NSDictionary class]]) 
    { 
     ViewController *nextVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController"]; 
     nextVC.query = value; 
     [self.navigationController pushViewController:nextVC animated:YES]; 
    } 
} 

Hinweis: I don Ich möchte den webservice Anruf in ViewController.m aufrufen, wann immer ich die ViewController Instanz instanziiere. Also setze ich den webservice Code in AppDelegatedidFinishLaunch Methode.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://query.yahooapis.com/v1/public/yql?q=select+*+from+weather.forecast+where+woeid%3D1100661&format=json"]]; 
    NSError *error=nil; 
    id response=[NSJSONSerialization JSONObjectWithData:data options: 
       NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error]; 
    if (error) { 
     NSLog(@"%@",[error localizedDescription]); 
    } else { 
    NSDictionary* _query = [response objectForKey:@"query"]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      ViewController *vc = (ViewController*)[(UINavigationController*)self.window.rootViewController topViewController]; 
      vc.query = _query; 
     }); 
    } 
    // Override point for customization after application launch. 
    return YES; 
} 

Es liegt an Ihnen, dass, wenn Sie diesen Code setzen, aber am meisten bevorzugt sollten wir folgenden Code in der vorherigen UIViewController Ihrer setzen DatashowingViewController (Meins ist ViewController) und die Informationen an ViewController (wie ich es getan habe) , so dass wir dasselbe UIViewController für das gleiche Ergebnis wiederverwenden können.

Ich hoffe, diese Antwort wird Ihnen helfen, Ihre Leistung zu erreichen.

+0

app wird auf dispatch_async abstürzen (dispatch_get_main_queue(),^{ ViewController * vc = (ViewController *) [(UINavigationController *) self.window.rootViewController topViewController]; vc.query = _query; }); –

+0

Das zeigt Ihnen, wie Sie Antwortdaten in Ihrem ViewController übergeben. Jetzt sagen Sie mir, haben Sie Ihren Viewcontroller als topViewController von Ihrem UINavigationController, der der rootViewController des Anwendungsfensters ist? –

+0

Ich kann NavigationViewcontroller und meinen Code nicht in den obigen Kommentar einfügen. –