I'm still new to using NSURL to get data and seem to have issues whenever trying to use this. In this case I use debug to check all the date coming in in ViewDidload and all the correct data comes in and is split into the arrays I then want to use to build my table view controller. However when we reach the NumberOfRows in section method, all of the arrays seem to have been reset to nil. I've tried using various combinations of NSURL solutions but none seem to get any further than the one I am using right now (which at least shows some data arrriving). Can anyone please let me know if I am making an obvious mistake, or if not give me a reliable piece of code which I should use to perform a simple GET like this. Thank you very much.
Here below my code:
@implementation MyLessonsTableViewController
NSArray *pastarr = nil;
NSArray *todoarr = nil;
NSArray *comingarr = nil;
NSArray *jsonless = nil;
- (void)viewDidLoad {
[super viewDidLoad];
// GET MY LESSONS FROM DATABASE
jsonless = [[NSArray alloc] init];
pastarr = [[NSArray alloc] init];
todoarr = [[NSArray alloc] init];
comingarr = [[NSArray alloc] init];
NSString *token = @"5cfd28bed3f5f5bd63143c81a50d434a";
NSString *urlString = [NSString stringWithFormat:@"http://soon.nextdoorteacher.com/apps/api/nextdoorteacher/student-lessons?t=%@", token];
NSURL *urlcc = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:urlcc];
NSError *error;
NSMutableDictionary *jsonLess = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions
error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
NSLog(@"My Lessons Json == %@", jsonLess);
// SPLIT ARRAY
NSArray *pastarr = [jsonLess valueForKeyPath:@"past"];
NSArray *todoarr = [jsonLess valueForKeyPath:@"todo"];
NSArray *comingarr = [jsonLess valueForKeyPath:@"upcoming"];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSUInteger lessonRowCount = 0;
switch (section) {
case 0:
lessonRowCount = todoarr.count;
break;
case 1:
lessonRowCount = comingarr.count;
break;
case 2:
lessonRowCount = pastarr.count;
break;
default:
break;
}
return lessonRowCount;
}
Several issues.
reloadData
needlessly in dispatch_async
.reloadData
before you process jsonLess
.Here's your posted code all fixed up:
@implementation MyLessonsTableViewController {
NSArray *pastarr = nil;
NSArray *todoarr = nil;
NSArray *comingarr = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
// GET MY LESSONS FROM DATABASE
NSString *token = @"5cfd28bed3f5f5bd63143c81a50d434a";
NSString *urlString = [NSString stringWithFormat:@"http://soon.nextdoorteacher.com/apps/api/nextdoorteacher/student-lessons?t=%@", token];
NSURL *urlcc = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:urlcc];
NSError *error;
NSMutableDictionary *jsonLess = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions
error:&error];
NSLog(@"My Lessons Json == %@", jsonLess);
// SPLIT ARRAY
pastarr = [jsonLess valueForKeyPath:@"past"];
todoarr = [jsonLess valueForKeyPath:@"todo"];
comingarr = [jsonLess valueForKeyPath:@"upcoming"];
[self.tableView reloadData];
}
Now this still suffers from one big problem. You are doing Internet access on the main thread. That's bad. You really should do it this way:
- (void)viewDidLoad {
[super viewDidLoad];
// GET MY LESSONS FROM DATABASE
NSString *token = @"5cfd28bed3f5f5bd63143c81a50d434a";
NSString *urlString = [NSString stringWithFormat:@"http://soon.nextdoorteacher.com/apps/api/nextdoorteacher/student-lessons?t=%@", token];
NSURL *urlcc = [NSURL URLWithString:urlString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:urlcc];
NSError *error;
NSMutableDictionary *jsonLess = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions
error:&error];
NSLog(@"My Lessons Json == %@", jsonLess);
// SPLIT ARRAY
pastarr = [jsonLess valueForKeyPath:@"past"];
todoarr = [jsonLess valueForKeyPath:@"todo"];
comingarr = [jsonLess valueForKeyPath:@"upcoming"];
// Now this must be done on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}};
}