Deciding the initial view controller before app finish loading - ios

Hi I have a login view controller and my app storyboard views. The initial view controller points to the app dashboard. I am checking in my appDelegate application function if the user is logged in. After that I (re)set the correct UIViewController as the initial. Somehow the app always goes to the initial view controller and then says oops I need to go to login because the user is not logged in... How can I avoid this?
This is my current code.
dispatch_async(dispatch_get_main_queue(), {
let storyboard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
if (settings.isLoggedIn())
{
let vc: AnyObject! = storyboard.instantiateInitialViewController()
self.window?.rootViewController = vc as? UIViewController
} else {
let vc: AnyObject! = storyboard.instantiateViewControllerWithIdentifier("login")
self.window?.rootViewController = vc as? UIViewController
}
})

how to check user logged in or not in below method in the appdelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//check user logged or not, if true you can set the initial view controller given below
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController! = storyboard.instantiateViewControllerWithIdentifier("urcontroller")
let window = UIApplication.sharedApplication().windows[0] ;
window.rootViewController = vc;
return true
}

Related

Storyboard's view controller not showing up when programmatically set as root view controller

I am trying to change the rootVC based on some condition on the app launch. All of my VCs are made in the storyboard so I am doing it like this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
checkPhotoLibraryAccess()
return true
}
func checkPhotoLibraryAccess(){
if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.denied || PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.notDetermined {
showPermissionVC()
} else {
showContainerVC()
}
}
func showPermissionVC (){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let rootVC = storyboard.instantiateViewController(withIdentifier: "askPermissionVC")
UIApplication.shared.windows.first?.rootViewController = rootVC
self.window?.makeKeyAndVisible()
}
func showContainerVC (){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let rootVC = storyboard.instantiateViewController(withIdentifier: "containerVC")
UIApplication.shared.windows.first?.rootViewController = rootVC
self.window?.makeKeyAndVisible()
}
I have removed the arrow showing the initial VC from the storyboard so that it won't have a conflict with the code. However, I got this error and nothing showed up on screen in simulator:
[Application] Failed to instantiate the default view controller for
UIMainStoryboardFile 'Main' - perhaps the designated entry point is
not set?
I have now removed the "Main storyboard file base name" property from info.plist. This time the error is gone but still nothing is showing up. What am I doing wrong?
You need to initialize the window programmatically.
Try adding the following to the beginning of your didFinishLaunchingWithOptions method in Appdelegate
self.window = UIWindow()
Also in your showPermissionVC and showContainerVC methods, replace this line:
UIApplication.shared.windows.first?.rootViewController = rootVC
with:
window?.rootViewController = rootVC

How to go from appDelegate to viewController [duplicate]

This question already has answers here:
Storyboard - refer to ViewController in AppDelegate
(5 answers)
Closed 4 years ago.
if i have two viewControllers and i want when condition succeeded i want to go to another ViewController.
but i want to check every time the app launched so i stored the value on userDefaults and in appDelegate i checked for this value.
when i print the value i get it but i can not go to the desired controller.
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let active:Bool = defaults.bool(forKey: "activeBooking")
if active {
print("active \(active)")
let rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Final", bundle: nil)
let setViewController = mainStoryboard.instantiateViewController(withIdentifier: "finalBooking") as! BookingFromCurrentLocationVC
rootViewController?.navigationController?.popToViewController(setViewController, animated: false)
}
return true
}
i print the value in other controller and it return me true(my value) so why i can not go to another controller
You can try this:
In appDelegate and in didFinishLaunching
You can store this value in UserDefault and then check the condition:
if condition == true{
goToVC1()
}else{
goToVC2
}
func goToVC1() {
let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let ObjVC1: ViewController = storyboard.instantiateViewController(withIdentifier: "VC1") as! VC1
let navigationController : UINavigationController = UINavigationController(rootViewController: ObjVC1)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
func goToVC2() {
let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let ObjVC2: ViewController = storyboard.instantiateViewController(withIdentifier: "VC2") as! VC2
let navigationController : UINavigationController = UINavigationController(rootViewController: ObjVC2)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
Add a segue from Navigation controller to desired View Controller (with segue identifier "finalBookingVC") and replace the code inside your if condition with:
self.window?.rootViewController!.performSegue(withIdentifier: "finalBookingVC", sender: nil)
You can initiate your view controller in AppDelegate as below.
Perform your condition check and set the StoryboardID and ViewControllerID as per your requirement.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
//check your condition here and change the Storyboard name and ViewController ID as required
let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeVCID") as! HomeController
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
return true
}
The first thing you need to check if an application is active and already open (top controller is finalBookingVC) then no need to do anything,
second thing finalBookingVC if already available in a stack then no need to push at that time you need to pop view controller.
If finalBookingVC is not available on the stack then you need to push this controller.
func gotoController() {
let navigationController : UINavigationController! = self.window!.rootViewController as! UINavigationController;
let arrViewController = navigationController;
if arrViewController != nil && !(arrViewController?.topViewController is finalBookingVC) {
var finalBookingVCFound:Bool = false;
for aViewController in (arrViewController?.viewControllers)! {
if aViewController is finalBookingVC {
finalBookingVCFound = true;
_ = navigationController?.popToViewController(aViewController, animated: true);
break;
}
}
if !finalBookingVCFound {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil);
let objVC:finalBookingVC = mainStoryboard.instantiateViewController(withIdentifier: "finalBookingVC") as! finalBookingVC;
navigationController?.pushViewController(objVC, animated: true);
}
}
}

How to maintain login session in ios?

I would like to know where I need to change the root view controller in the app programming. Below is my code
class NavigationViewController: UINavigationController {
var window: UIWindow?
override func viewDidLoad() {
super.viewDidLoad()
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let newRootView = storyBoard.instantiateViewController(withIdentifier: "WelcomeViewController") as! WelcomeViewController
let userStatus = UserDefaults.standard.bool(forKey: "isLoggedIn")
if userStatus {
self.window?.rootViewController = newRootView
}
}
}
I am setting the value for isLoggedIn key as true when user logged in and false when the user logged out so that I can retrieve the value in this navigation controller subclass, based on that I can choose the root view controller. But its not working fine it remains the same whenever I am launching the app I am getting the login page only though I already logged in, also please don't suggest me to change the root view controller inside of didfinishlaunchingwithoptions method. Could someone help me to solve it? Thanks in advance.
If I understand correctly the goal of your code, you want to boot directly on WelcomeViewController if the user is already logged in.
You could try to create a custom segue called ReplaceSegue and set this ReplaceSegue to the segue linking the NavigationViewController and the ViewController.
And then you can change the destination of your segue.
class ReplaceSegue: UIStoryboardSegue {
override func perform() {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let newRootView = storyBoard.instantiateViewController(withIdentifier: "WelcomeViewController") as! WelcomeViewController
sourceViewController.navigationController?.setViewControllers([newRootView], animated: true)
}
}
First set user login bool true in NSUserDefults. when User is login Successfully.
UserDefaults.standard.set(true, forKey: "USERISLOGIN")
Now Open Appdelegate.swift -> didFinishLaunchingWithOptions Method:-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if(UserDefaults.standard.bool(forKey: "USERISLOGIN")){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let objLogoutVC = storyboard.instantiateViewController(withIdentifier: "LogoutVC") as! LogoutVC
let navigationController = UINavigationController(rootViewController: objLogoutVC)
navigationController.navigationBar.isTranslucent = false
navigationController.navigationBar.isHidden = true
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
return true
}
Let me know if you needed any thing more.

Display a particular viewcontroller in Xcode/swift using if else conditional statements

I want a to have a conditional if statement to be run immediately when the app is open. Basically, it will be
if x = true {
//segue to viewcontroller1
} else {
//stay on this page
}
This will be in Xcode and coded in swift (obviously the syntax is wrong)... what is the appropriate way to write the syntax to segue to a particular view controller if the condition is true and stay on the one that normally is opened up to upon opening the app? Also, where do I put this? I considered the viewdidload method in the, normally, first displayed viewcontroller, but the variable needs to be checked before the view loads, such that the view changes to a different one if the condition is true and that one opens first instead?
Edit: I tried to set the code in the AppDelegate.swift as follows:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if x{
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let ViewController = mainStoryBoard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = ViewController
} else{
//same code as above but to different VC
}
return true
}
But when I run this I get an error in the appDelegate saying that "libc++abi.dylib: terminating with uncaught exception of type NSException". What is the right way to modify this code?
If you want to select the scene before presenting. You can add the following in appDelegate.swift, in application(application: UIApplication, didFinishLaunchingWithOptions):
var id = x ? "id1" : "id2"
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let exampleVC: UIViewController = mainStoryboard.instantiateViewController(withIdentifier: id) as UIViewController
self.window?.rootViewController = exampleVC
self.window?.makeKeyAndVisible()
Make sure you name the scenes in storyboard
If you OK with the first scene showing and then choosing to segue:
if x {
self.performSegue(withIdentifier: "id1", sender: self)
} else {
self.performSegue(withIdentifier: "id2", sender: self)
}
Again, make sure to name the segues in storyboard
Another option, use UINavigationController. Set a Navigation Controller as your root view controller
let id = x ? "id1" : "id2"
let mainStoryboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
let exampleVC = mainStoryboard.instantiateViewController(withIdentifier: id) as UIViewController
let navigationController = UINavigationController(rootViewController: exampleVC)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window!.rootViewController = navigationController
self.window!.makeKeyAndVisible()

How to change the initial view controller through swift code

I'm developing an app with initial view controller as "Navigation controller". The app contains 2 ideas to implement.
1) From the RegisterViewController, User has to register the mobile no with verification //from sms or call, After verified it enters into HomeViewController( Condition: when the user install the app for the 1st time it shows the RegisterViewController)
2) If the app is already get installed into the iPhone and the user also register the mobile no, then the user opens the same app now the initialViewController must be the HomeViewController
How can I achieve this idea through swift code?
Implement this logic in your appdelegate class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let isRegistered = NSUserDefaults.standardUserDefaults().boolForKey("ALLREADY_REGISTER")
if isRegistered == true{
// implement home view controller
let homeViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("HomeVC") as! HomeViewController
self.window?.rootViewController = homeViewController
self.window?.makeKeyAndVisible()
}else{
// implement register view controller
let registerViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("RegisterVC") as! RegisterViewController
self.window?.rootViewController = registerViewController
self.window?.makeKeyAndVisible()
}
return true
}
Then when first time register completed successfully then set bool variable true for the key ALLREADY_REGISTER
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "ALLREADY_REGISTER")`
do like
var viewController: UIViewController!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if NSUserDefaults.standardUserDefaults().objectForKey("notRegistered") == nil
{
viewController = storyboard.instantiateViewControllerWithIdentifier("RegisterViewController")
}
else {
if NSUserDefaults.standardUserDefaults().objectForKey("notRegistered") as! String == "registred"
{
viewController = storyboard.instantiateViewControllerWithIdentifier("HomeViewController")
}
else
{
viewController = storyboard.instantiateViewControllerWithIdentifier("RegisterViewController")
}
// if you want to create the UINavigationController use this
let nav = UINavigationController(rootViewController: viewController)
self.window!.rootViewController = nav
else directly access use this
self.window!.rootViewController = viewController
self.window.makeKeyAndVisible()
// Override point for customization after application launch.
return true
}
on registration page after the success save like
//Save
NSUserDefaults.standardUserDefaults().setObject("registred", forKey: "notRegistered")
you have to change rootViewController instead of initialViewController. when user verified and enters into HomeViewController store flag in NSUserDefaults.then every time in AppDelegate didFinishLaunchingWithOptions check user is already entered in HomeViewController using NSUserDefaults.
let appdelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var homeViewController = mainStoryboard.instantiateViewControllerWithIdentifier("HomeViewController") as! HomeViewController
let nav = UINavigationController(rootViewController: homeViewController)
appdelegate.window!.rootViewController = nav

Resources