2013-03-31 4 views
0

J'ai 2 contrôleurs, 1 est de charger des données de JSON, l'autre est un UITableViewController simple. Mon problème est que la vue est chargée avant les données. Comment puis-je charger les données avant ma table? Je suis nouveau à POO Objective-C:/Charger DataController avant ViewController iOS

le code

#import "MasterViewController.h" 

#import "DetailViewController.h" 

#import "DealsDataController.h" 

#import "Deals.h" 


@implementation MasterViewController 

- (void)awakeFromNib 
{ 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { 
     self.clearsSelectionOnViewWillAppear = NO; 
     self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0); 
    } 
    [super awakeFromNib]; 

    self.dataController = [[DealsDataController alloc] init]; 
    NSLog(@"this is the awake from nib count %i",[self.dataController countOfList]); 

} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Do any additional setup after loading the view, typically from a nib. 

} 

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

#pragma mark - Table View 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    NSLog(@"did this count the list %i",[self.dataController countOfList]); 
    return [self.dataController countOfList]; 

} 

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

    static NSString *CellIdentifier = @"DealCell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    Deals *dealAtIndex = [self.dataController objectInListAtIndex:indexPath.row]; 
    [[cell textLabel] setText:dealAtIndex.name]; 

    return cell; 
} 

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Return NO if you do not want the specified item to be editable. 
    return NO; 
} 


/* 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     [_objects removeObjectAtIndex:indexPath.row]; 
     [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    } else if (editingStyle == UITableViewCellEditingStyleInsert) { 
     // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view. 
    } 
} 



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { 
     NSDate *object = _objects[indexPath.row]; 
     self.detailViewController.detailItem = object; 
    } 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"showDetail"]) { 
     NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
     NSDate *object = _objects[indexPath.row]; 
     [[segue destinationViewController] setDetailItem:object]; 
    } 
} 

*/ 
@end 

et le contrôleur de données

#import "DealsDataController.h" 
#import "Deals.h" 

@implementation DealsDataController 
@synthesize masterDealsList = _masterDealsList; 

-(id)init { 
    if (self = [super init]) { 
     [self initializeDataList]; 
     return self; 
    } 
    return nil; 
} 

-(NSMutableArray *)masterDealsList { 
    if (!_masterDealsList) { 
     _masterDealsList = [[NSMutableArray alloc] init]; 
    } 
    return _masterDealsList; 
} 

-(void)setMasterDealsList:(NSMutableArray *)newList { 
    if (_masterDealsList != newList) { 
     _masterDealsList = newList; 
    } 
} 

- (void)fetchedData:(NSData *)responseData { 
    //parse out the json data 
    NSError* error; 
    NSDictionary *json = [NSJSONSerialization 
          JSONObjectWithData:responseData //1 
          options:kNilOptions 
          error:&error]; 

    _deals = [json objectForKey:@"deals"]; //2 

    NSLog(@"deals: %@", _deals); 
    NSArray *dealName = [_deals valueForKey:@"deal_name"]; 
    NSLog(@"deals Name: %@", dealName); 

    for (int i = 1;i <= [_deals count]; i++) { 
    NSDictionary* dict = [_deals objectAtIndex:i-1]; 
    Deals *deal =[[Deals alloc] initWithProdID:1 name:[dict valueForKey:@"deal_name"] description:[dict objectForKey:@"deal_description"] price:10.00 specs:@"specs" terms:@"terms"]; 
    [self addDealWithDeal:deal]; 

    NSLog (@"masterListCount %i ", [self countOfList]); 

    } 

} 

-(void)initializeDataList { 
    //NSDate *today = [NSDate date]; 
    dispatch_async(sweetDealsQueue, ^{ 
     NSData* data = [NSData dataWithContentsOfURL:sweetDealsURL]; 
     [self performSelectorOnMainThread:@selector(fetchedData:) 
           withObject:data waitUntilDone:YES]; 
    }); 

} 

-(NSUInteger)countOfList { 

    return [self.masterDealsList count]; 

} 

-(Deals *)objectInListAtIndex:(NSUInteger)theIndex { 

    return [self.masterDealsList objectAtIndex:theIndex]; 
} 

-(void)addDealWithDeal:(Deals *)deal { 

     [self.masterDealsList addObject:deal]; 
} 


@end 
+0

Je l'ai compris ... Tout ce que je devais faire était de changer dispatch_async à dispatch_sync ... Il n'attendait pas que mes données se chargent avec async ... Ce qui est logique. – vinylDeveloper

Répondre

2

Dans MVC, vous avez généralement un contrôleur de vue par vue. Ainsi, un seul contrôleur de vue serait responsable de tout affichage sur une vue. Bien sûr, vous pouvez avoir des classes auxiliaires, ou utiliser des contrôleurs subview (par exemple des widgets), ou si vous développez pour iPad, vous pouvez avoir deux contrôleurs de vue (un pour le menu latéral, un pour la vue principale).

Je vous suggère de faire ce qui suit

  1. Faites votre DataController une sous-classe de NSObject au lieu de UIViewController. D'après ce que je comprends, c'est une classe d'accès aux données, pas responsable de l'interface utilisateur.
  2. Dans la méthode viewDidLoad de votre MasterViewController, alloue et initialise un objet DataController et déclenche sa méthode de chargement de données.
  3. Vous pouvez définir un rappel de sorte que lorsque les données sont extraites, une méthode sur le MasterViewController est appelée avec les données. Ou définissez votre MasterViewController en tant que délégué pour votre DataController et lorsque c'est fait, assignez les données à une propriété de MasterViewController.
+1

Merci, j'aime ta réponse ... Surtout que j'avais déjà fait les deux premiers points, ça fait du bien d'entendre que je suis sur le bon chemin. Salutations – vinylDeveloper

+0

De rien, content que cela fonctionne pour vous @vinylDeveloper –

0

je suppose que vous devez effectuer le chargement des données avant initialisant votre TableViewController et que vous get response Les données chargent le TableViewController. pour cela refer this post comment attendre jusqu'à ce que l'exécution complète de la méthode, effectuer le chargement des données dans cette méthode.

0

Il est possible d'afficher une tablevue vide avec un indicateur d'activité pendant le chargement des données. Lorsque le chargement des données est terminé, vous pouvez simplement recharger la tableview avec les données et supprimer l'indicateur d'activité. [tableview reloaddata] appelle toutes les méthodes déléguées de la source de données qui auraient alors vos données dedans.

Questions connexes