In my application, once the user logs in from the LoginViewController
, he is directed to the ProfileTabBarController
.
ProfileTabBarController
is a subclass of UITabBarController
.It consists of three view controllers all of which need a reference to an instance of Profile.
When the ProfileTabBarController
is pushed, it loads the user's profile. Once the profile loads successfully, it sets a reference to profile on each of its view controllers and then adds them as tab items.
The reason I chose this approach is that if the user launches the application and his token hasn't expired, the application should go directly to the ProfileTabController
; the user need not login again. Rather than duplicate the code for loading the profile in both AppDelegate
and LoginViewController
, I felt it was better to encapsulate it in ProfileTabBarController
.
The problem with this approach is that during the segue, the UITabBarController
appears black as no view controller has been set. I managed to remedy this by creating a LoadingViewController
and setting it initially as the only UIViewController
of ProfileTabController
My question is whether there is a better approach to solving this problem. I don't really like the idea of having a UIViewController
with no other purpose then to display a loading icon.
I was able to eliminate the Loading ViewController by making use of NSNotificationCenter
.
ProfileTabBarController
adds the three ViewControllers and then begins loading the profile.override func viewDidLoad() { super.viewDidLoad()
self.setupUI()
self.setupViewControllers()
self.loadProfile()
}
ProfileTabBarController
emits a ProfileDidLoad
notification.let completion = { (profile: Profile?) in
MBProgressHUD.hideHUDForView(self.view, animated: true)
if let profile = profile {
self.profile = profile
NSNotificationCenter.defaultCenter().postNotificationName(Notification.ProfileDidLoad, object: self.profile)
} else {
UIAlertView(
title: "",
message: NSLocalizedString("Error loading profile", comment: ""),
delegate: nil,
cancelButtonTitle: "OK"
).show()
}
}
The ViewControllers observe the ProfileDidLoad
notification:
func setupNotificationObserver(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: "profileDidLoad:", name: Notification.ProfileDidLoad, object: nil)
}
@objc func profileDidLoad(notification: NSNotification){
if let profile = notification.object as? Profile{
self.profile = profile
}
}
In this way, the view controllers are immediately displayed after login without the need of a loading screen.