I am working on an iOS 8 application that requires authentication to a backend. I would like to make the app in such a way that, if the app receives an HTTP 403 error, the user is presented with a login screen. After the login screen view controller successfully authenticates the user, the app should navigate back to the previous screen (whatever screen it was).
In Xcode 6, I can see that the preferred way to navigate between scenes is via segues. As such, I am using segues to navigate back from the login screen, with this code:
[self performSegueWithIdentifier:@"UnwindToNewsfeed" sender:self];
The problem that this presents is, I would have to establish segues to all scenes within the app, as any of them might trigger an authentication request. Therefore, I would like to ask for a recommended approach to implement this navigation requirement.
I'm new to iOS8 and to iPhone programming in general, so it could be that I don't have iOS 8's navigation concepts entirely clear and I'm using a wrong approach.
Unwind segues are different to forward segues and this makes it quite simple to support the functionality you are after.
Prior to creating an unwind segue you need to add a method to the view controller that you want to unwind to. For example -
- (IBAction)unwindFromLogin:(UIStoryboardSegue*)sender {
}
You can then create an unwind segue by ctrl-dragging between an object in your scene (or the UIViewController object for your scene if you want to trigger the unwind with performSegueWithIdentifier
) and the exit icon at the bottom of the screen. Interface Builder will then display the list of methods it found that match the signature above (so it will display unwindFromLogin:
). You can give this segue an identifier so that you can invoke it with performSegueWithIdentifier
as you would normally do. So far so good.
Now, for the clever bit. At runtime when the unwind segue is invoked, iOS looks through the current view controller stack to find the first view controller that implements the nominated method - so if you implement the same unwindFromLogin:
method in each of your view controllers, your login view will unwind to the view controller it came from and you only need a single unwind segue in your login view controller scene.
Apple has a good Tech Note that describes the unwind process in more detail and how you can customise it by implementing additional methods in your UIViewController
subclass, but the default implementation should suit your needs.
If you don't want to create a segue from each source view controller to the login view controller you can present it directly using something like -
LoginViewController *loginVC=(LoginViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"loginVC"];
[self presentViewController:loginVC animated:YES completion:nil];
You can still use the unwind segue to get back