Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Vanessa Cantero G贸mez
7,376 PointsDelay displaying a LoginViewController
I have this app that uses an accessToken that only remains for two hours. My app has three UINavigationController (with UITableViewController) inside a UITabBarController. Every time I click on one of my tabs, a new connection is created and I check if the statusCode of the HTTP response is 200 or 401. If the statusCode is 401 is because my accessToken is no longer operative and I have to relog again.
The problem I have is that when the current viewController calls the LoginViewController because the 401, the LoginViewController shows with delay and you can see the cells of UITableViewController.
My code is:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[CaseCell class] forCellReuseIdentifier:@"identifier"];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.accessToken = [userDefaults objectForKey:@"accessToken"];
if (self.accessToken == nil) {
LoginViewController *loginViewController = [[LoginViewController alloc] init];
[self presentViewController:loginViewController animated:NO completion:nil];
} else {
[self refresh];
}
}
- (void)refresh
{
NSURLSession *session = [NSURLSession sharedSession];
NSString *urlString = [[NSString alloc] initWithFormat:@"myURL", self.accessToken];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSData *data = [[NSData alloc] initWithContentsOfURL:location];
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
NSInteger statusCode = [httpResponse statusCode];
if (statusCode == 200) {
NSArray *responseArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
self.cases = responseArray;
}
dispatch_async(dispatch_get_main_queue(), ^{
if (statusCode == 200) {
[self.tableView reloadData];
} else {
LoginViewController *loginViewController = [[LoginViewController alloc] init];
[self presentViewController:loginViewController animated:NO completion:nil];
}
});
}];
[task resume];
}
I really don't know what is the problem. I mean, I know it has to be related with things happening in background and dispatch_async but I've made everything and I don't know why this delay.
PD: Don't pay attention to NSUserDefaults. I know I have to store the token in Keychain.
THANK YOU VERY MUCH!
1 Answer
Enara L. Otaegi
13,107 PointsHello,
this reminds me the issue I had with the photo bombers app. My problem was in the viewDidAppear method. Do you have that method in your app? Anyway, I get that you want to use the dispatch_async for loading new data but not for showing the login. Have you tried putting that else from inside the dispatch in the if sentence just before it? And thinking further, you just call the refresh when there's no accessToken so you have to present the loginViewController then why don't you do that in the first place and then the rest of the work?