I have an app that may require the user to authenticate during navigation. If this is the case, I'd like the login event to return a callback back to the operation that requested the login event, for it to know that the login was either successful or not.
For example, a method that requires authentication will prompt for credentials by calling the methods of a helper class:
[UserModel promptCredentials:^(NSHTTPURLResponse *response) {
if (response.statusCode == 200) {
[self userWillComment:userActionCell];
}
}];
The helper method instantiates the login view controller, and tries to set the callback property:
+ (void) promptCredentials:(void (^)(NSHTTPURLResponse *response))callback{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *currentViewController = [[UIApplication sharedApplication] keyWindow].rootViewController;
LoginViewController *loginScreenNav = [storyboard instantiateViewControllerWithIdentifier:@"LoginNavigationController"];
loginScreenNav.loginCallback = callback;
if([currentViewController isKindOfClass:[UINavigationController class]]){
currentViewController = [(UINavigationController *)currentViewController visibleViewController];
} else if(currentViewController.presentedViewController){
currentViewController = currentViewController.presentedViewController;
}
dispatch_async(dispatch_get_main_queue(), ^{
[currentViewController presentViewController:loginScreenNav animated:YES completion:nil];
});
}
The Login view controller has the following property defined in its interface:
@property (nonatomic, strong) void (^loginCallback)(NSHTTPURLResponse *response);
When the login takes place within the 'LoginViewController', I am trying to execute the callback, like this:
if (self.loginCallback != nil) {
self.loginCallback(response);
}
However, when this code runs, the line within the helper method loginScreenNav.loginCallback = callback;
makes the app crash with error:
-[UINavigationController setLoginCallback:]: unrecognized selector sent to instance
Essentially, I need some guidance on how to correctly assign this property block within the login view controller so it can get executed after the login network operation takes place.
The reason for the crash is that you are lying to yourself (and the compiler) in this line:
You have instantiated a view controller from the storyboard, yes; but it is not a LoginViewController. It is a UINavigationController. Examine your storyboard carefully, look at the view controller that is marked with the
"LoginNavigationController"
identifier, and you will see that this is true.