174

I would like to set the initial viewcontroller from the appdelegate. I found a really good answer, however it's in Objective C and im having trouble achieving the same thing in swift.

Programmatically set the initial view controller using Storyboards

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    UIViewController *viewController = // determine the initial view controller here and instantiate   it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];

    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];

    return YES;
}

Anyone able to help?

I want the initial Viewcontroller to be dependent on certain conditions being met using a conditional statement.

Community
  • 1
  • 1
Abubakar Moallim
  • 4,903
  • 4
  • 13
  • 16
  • This is a possible duplicate of : http://stackoverflow.com/questions/10428629/programatically-set-the-initial-view-controller-using-storyboards/14926009#14926009 – mfaani Sep 18 '16 at 22:24

24 Answers24

301

Xcode11 and SceneDelegate note:

Starting from Xcode11, because of SceneDelegates, it's likely that you shouldn't do it inside AppDelegate. Instead do it from SceneDelegate. For more on that see this other answer


Old answer:

I used this thread to help me convert the objective C to swift, and its working perfectly.

Instantiate and Present a viewController in Swift

Swift 2 code:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
    let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginSignupVC")
    
    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()
    
    return true
}

Swift 3 code:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
    let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginSignupVC")

    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()

    return true
}
mfaani
  • 33,269
  • 19
  • 164
  • 293
Abubakar Moallim
  • 4,903
  • 4
  • 13
  • 16
  • 1
    can not find storyboard "Main", nor "Storyboard.storyboard" in swift 2 app – Async- Oct 31 '15 at 00:36
  • 5
    Is this the current standard way to *set initial view controller in appdelegate*? I ask because it looks like a litttttle bit of a hack (sorry @Abs). – rigdonmr Jan 11 '16 at 23:43
  • 12
    @rigdonmr If the application has a Storyboard set as the Main Interface, the window is loaded automatically and its root view controller is set to the storyboard's initial view controller. If the view controller needs to change based on a condition, or the application does not have a Main Interface, it is acceptable to initialize a `UIWindow` and set its root view controller programmatically. – JAL Jan 14 '16 at 22:41
  • 2
    The surprising (but good) thing here is that instantiating the view controller manually in this way appears to stop iOS from instantiating the default view controller. I might have expected both to be loaded. Is this behavior documented somewhere? – Pat Niemeyer Sep 13 '16 at 14:56
  • 2
    @MayankJain this works fine with Swift 3, just need to translate some of the code from earlier swift – JAB Oct 22 '16 at 00:54
  • You can also use `initialVC = storyboard.instantiateInitialViewController()`. You just need to set the initial view controller in the storyboard editor by checking the *isInitialViewController* box in the attributes inspector. – Derek Soike Jan 19 '17 at 16:32
  • When using this code the default animation for orientation transition doesn't work anymore. – user3427013 May 03 '17 at 10:31
  • The default animation when changing the screen orientation only shows if removing this line: self.window = UIWindow(frame: UIScreen.main.bounds) – user3427013 May 03 '17 at 10:39
  • this does not work in Swift 5 anyone have code for this? – Joseph Astrahan Feb 05 '20 at 23:35
49

For new Xcode 11.xxx and Swift 5.xx, where the target it set to iOS 13+.

For the new project structure, AppDelegate does not have to do anything regarding rootViewController.

A new class is there to handle window(UIWindowScene) class -> 'SceneDelegate' file.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = // Your RootViewController in here
        self.window = window
        window.makeKeyAndVisible()
    }

}
Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
gamal
  • 1,587
  • 2
  • 21
  • 43
44

Try this. For example: You should use UINavigationController as the initial view controller. Then, you can set any view controller as root from the storyboard.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let navigationController = storyboard.instantiateInitialViewController() as UINavigationController
    let rootViewController = storyboard.instantiateViewControllerWithIdentifier("VC") as UIViewController
    navigationController.viewControllers = [rootViewController]
    self.window?.rootViewController = navigationController
    return true
}

See my storyboard screen.

Vukašin Manojlović
  • 3,717
  • 3
  • 19
  • 31
protikhonoff
  • 565
  • 4
  • 6
32

Swift 3, Swift 4:

Change first line to

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

the rest is same.

Swift 5+:

Instantiate root view controller from storyboard:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // this line is important
        self.window = UIWindow(frame: UIScreen.main.bounds)

        // In project directory storyboard looks like Main.storyboard,
        // you should use only part before ".storyboard" as its name,
        // so in this example name is "Main".
        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
        
        // controller identifier sets up in storyboard utilities
        // panel (on the right), it is called 'Storyboard ID'
        let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController

        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()        
        return true
    }

If you want to use UINavigationController as root:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // this line is important
        self.window = UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
        let navigationController = UINavigationController.init(rootViewController: viewController)
        self.window?.rootViewController = navigationController

        self.window?.makeKeyAndVisible()        
        return true
    }

Instantiate root view controller from xib:

It is almost the same, but instead of lines

let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController

you'll have to write

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)
Eridana
  • 2,418
  • 23
  • 26
22

if you are not using storyboard, you can try this

var window: UIWindow?
var initialViewController :UIViewController?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    initialViewController  = MainViewController(nibName:"MainViewController",bundle:nil)

    let frame = UIScreen.mainScreen().bounds
    window = UIWindow(frame: frame)

    window!.rootViewController = initialViewController
    window!.makeKeyAndVisible()

    return true
}
Jibin Jose
  • 368
  • 1
  • 7
18

Code for Swift 4.2 and 5 code:

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     self.window = UIWindow(frame: UIScreen.main.bounds)

     let storyboard = UIStoryboard(name: "Main", bundle: nil)

     let initialViewController = storyboard.instantiateViewController(withIdentifier: "dashboardVC")

     self.window?.rootViewController = initialViewController
     self.window?.makeKeyAndVisible()
}

And for Xcode 11+ and for Swift 5+ :

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

     var window: UIWindow?

     func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
         if let windowScene = scene as? UIWindowScene {
             let window = UIWindow(windowScene: windowScene)

              window.rootViewController = // Your RootViewController in here

              self.window = window
              window.makeKeyAndVisible()
         }
    }
}
Jamil Hasnine Tamim
  • 4,389
  • 27
  • 43
14

Here is a good way to approach it. This example places a navigation controller as the root view controller, and puts the view controller of your choice within it at the bottom of the navigation stack, ready for you to push whatever you need to from it.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
    // mainStoryboard
    let mainStoryboard = UIStoryboard(name: "MainStoryboard", bundle: nil)

    // rootViewController
    let rootViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainViewController") as? UIViewController

    // navigationController
    let navigationController = UINavigationController(rootViewController: rootViewController!)

    navigationController.navigationBarHidden = true // or not, your choice.

    // self.window
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    self.window!.rootViewController = navigationController

    self.window!.makeKeyAndVisible()
}

To make this example work you would set "MainViewController" as the Storyboard ID on your main view controller, and the storyboard's file name in this case would be "MainStoryboard.storyboard". I rename my storyboards this way because Main.storyboard to me is not a proper name, particularly if you ever go to subclass it.

John Bushnell
  • 1,851
  • 22
  • 29
11

I had done it in Objective-C. I hope it will be useful for you.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

UIViewController *viewController;

NSUserDefaults *loginUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *check=[loginUserDefaults objectForKey:@"Checklog"];

if ([check isEqualToString:@"login"]) {
    
    viewController = [storyboard instantiateViewControllerWithIdentifier:@"SWRevealViewController"];
} else {
    
    viewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
}


self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
Vukašin Manojlović
  • 3,717
  • 3
  • 19
  • 31
Patel Jigar
  • 2,141
  • 1
  • 23
  • 30
8

Init ViewController in AppDelegate

[Initial View Controller]

Disable Main.storyboard

1. (old Xcode)General -> Deployment Info -> Main Interface -> remove `Main` 
2. Info.plist -> remove Key/Value for `UISceneStoryboardFile` and `UIMainStoryboardFile`

Add Storyboard ID

Main.storyboard -> Select View Controller -> Inspectors -> Identity inspector -> Storyboard ID -> e.g. customVCStoryboardId

[Set initial ViewController using Storyboards(instead of Main)]
Swift 5 and Xcode 11

Extend UIWindow

class CustomWindow : UIWindow {
    //...
}

Edit generated by Xcode SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: CustomWindow!

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let windowScene = (scene as? UIWindowScene) else { return }

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "customVCStoryboardId")

        //or if your storyboard has `Is Initial View Controller`
        let storyboard = UIStoryboard(name: String(describing: SomeViewController.self), bundle: nil)
        let initialViewController = storyboard.instantiateInitialViewController()

        window = CustomWindow(windowScene: windowScene)
        window.rootViewController = initialViewController
        window.makeKeyAndVisible()
    }

    //...
}

[Access to Framework bundle]
[Get storyboard from a framework]

yoAlex5
  • 29,217
  • 8
  • 193
  • 205
  • Can set root controller to initial view controller window.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() – Kamran Khan Jul 21 '20 at 03:07
7

If you're not using the storyboard. You can initialize your main view controller programmatically.

Swift 4

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let rootViewController = MainViewController()
    let navigationController = UINavigationController(rootViewController: rootViewController)
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

    return true
}
class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .green
    }
}

And also remove Main from Deployment Info.

enter image description here

p-sun
  • 1,776
  • 1
  • 17
  • 10
6

I had done in Xcode 8 and swift 3.0 hope it will be useful for u, and its working perfectly. Use following code :

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {       
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let initialViewController = storyboard.instantiateViewController(withIdentifier: "ViewController")
    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()
    return true
}

And If you are using the navigation controller, then use following code for that:

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as! UINavigationController
    let initialViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController")
    navigationController.viewControllers = [initialViewController]
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()      
    return true
}
Borys Verebskyi
  • 4,160
  • 6
  • 28
  • 42
Kunal
  • 109
  • 1
  • 2
  • 4
  • Hi... Mayank, I had done in Xcode 8 and swift 3.0 Which error comes after using this solution because it's working – Kunal Nov 03 '16 at 05:31
6

Swift 4:

Add these lines inside AppDelegate.swift, within the didFinishLaunchingWithOptions() function...

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Setting the Appropriate initialViewController

    // Set the window to the dimensions of the device
    self.window = UIWindow(frame: UIScreen.main.bounds)

    // Grab a reference to whichever storyboard you have the ViewController within
    let storyboard = UIStoryboard(name: "Name of Storyboard", bundle: nil)

    // Grab a reference to the ViewController you want to show 1st.
    let initialViewController = storyboard.instantiateViewController(withIdentifier: "Name of ViewController")

    // Set that ViewController as the rootViewController
    self.window?.rootViewController = initialViewController

    // Sets our window up in front
    self.window?.makeKeyAndVisible()

    return true
}

Now, for example, many times we do something like this when we want to either drive the user to a login screen or to a initial setup screenl or back to the mainScreen of the app, etc. If you want to do something like that too, you can use this point as a fork-in-the-road for that.

Think about it. You could have a value stored in NSUserDefaults for instance that held a userLoggedIn Boolean and if userLoggedIn == false { use this storyboard & initialViewController... } else { use this storyboard & initialViewController... }

Wade Sellers
  • 323
  • 4
  • 12
  • it doesn't work in a new project with 1 added ViewController. Always starts from initial view controller. Xcode 11.2 Where can be a problem? – Oleh H Dec 10 '19 at 12:00
5

Well all the answers above/below are producing a warning about no entry point in storyboard.

If you want to have 2 (or more) entry view controllers that depend on some condition (say conditionVariable) then what you should do is:

  • In your Main.storyboard create UINavigationController without rootViewController, set it as entry point
  • Create 2 (or more) "Show" segues into view controllers, assign them some id, say id1 and id2
  • Use next code:

    class AppDelegate: UIResponder, UIApplicationDelegate {
    
       var window: UIWindow?
    
       func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
           let navigationController = window!.rootViewController! as! UINavigationController
           navigationController.performSegueWithIdentifier(conditionVariable ? "id1" : "id2")
    
           return true
       }
    

Hope this helps.

OlivierH
  • 3,875
  • 1
  • 19
  • 32
Borzh
  • 5,069
  • 2
  • 48
  • 64
  • 1
    the "no entry point in storyboard" error is due to a project configuration that can be deleted. go to project > info > custom iOS target properties and delete the "Main storyboard file base name" property. The warning should no longer appear. – orangemako Sep 12 '16 at 13:25
4

Here is complete Solution in Swift 4 implement this in didFinishLaunchingWithOptions

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

 let isLogin = UserDefaults.standard.bool(forKey: "Islogin")
    if isLogin{
        self.NextViewController(storybordid: "OtherViewController")


    }else{
        self.NextViewController(storybordid: "LoginViewController")

    }
}

write this Function any where inside Appdelegate.swift

  func NextViewController(storybordid:String)
{

    let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let exampleVC = storyBoard.instantiateViewController(withIdentifier:storybordid )
   // self.present(exampleVC, animated: true)
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = exampleVC
    self.window?.makeKeyAndVisible()
}
M Murteza
  • 1,629
  • 15
  • 10
3

Just in case you want to do it in the view controller and not in the app delegate: Just fetch the reference to the AppDelegate in your view controller and reset it's window object with the right view controller as it's rootviewController.

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("YOUR_VC_IDENTIFIER") as! YourViewController
appDelegate.window?.rootViewController = yourVC
appDelegate.window?.makeKeyAndVisible()
Ankit Goel
  • 6,257
  • 4
  • 36
  • 48
3

For swift 4.0.

In your AppDelegate.swift file in didfinishedlaunchingWithOptions method, put the following code.

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()

    let rootVC = MainViewController() // your custom viewController. You can instantiate using nib too. UIViewController(nib name, bundle)
    //let rootVC = UIViewController(nibName: "MainViewController", bundle: nil) //or MainViewController()
    let navController = UINavigationController(rootViewController: rootVC) // Integrate navigation controller programmatically if you want

    window?.rootViewController = navController

    return true
}

Hope it will work just fine.

Rubaiyat Jahan Mumu
  • 3,887
  • 1
  • 33
  • 35
  • 3
    Worked ..If you havent set initial viewController in stroyboard then you have to add window = UIWindow(frame: UIScreen.main.bounds) – Punit Jan 22 '19 at 07:06
3

Swift 5 & Xcode 11

So in xCode 11 the window solution is no longer valid inside of appDelegate. They moved this to the SceneDelgate. You can find this in the SceneDelgate.swift file.

You will notice it now has a var window: UIWindow? present.

In my situation I was using a TabBarController from a storyboard and wanted to set it as the rootViewController.

This is my code:

sceneDelegate.swift

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        self.window = self.window ?? UIWindow()//@JA- If this scene's self.window is nil then set a new UIWindow object to it.

        //@Grab the storyboard and ensure that the tab bar controller is reinstantiated with the details below.
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController

        for child in tabBarController.viewControllers ?? [] {
            if let top = child as? StateControllerProtocol {
                print("State Controller Passed To:")
                print(child.title!)
                top.setState(state: stateController)
            }
        }

        self.window!.rootViewController = tabBarController //Set the rootViewController to our modified version with the StateController instances
        self.window!.makeKeyAndVisible()

        print("Finished scene setting code")
        guard let _ = (scene as? UIWindowScene) else { return }
    }

Make sure to add this to the correct scene method as I did here. Note that you will need to set the identifier name for the tabBarController or viewController you are using in the storyboard.

how to set the storyboard ID

In my case I was doing this to set a stateController to keep track of shared variables amongst the tab views. If you wish to do this same thing add the following code...

StateController.swift

import Foundation

struct tdfvars{
    var rbe:Double = 1.4
    var t1half:Double = 1.5
    var alphaBetaLate:Double = 3.0
    var alphaBetaAcute:Double = 10.0
    var totalDose:Double = 6000.00
    var dosePerFraction:Double = 200.0
    var numOfFractions:Double = 30
    var totalTime:Double = 168
    var ldrDose:Double = 8500.0
}

//@JA - Protocol that view controllers should have that defines that it should have a function to setState
protocol StateControllerProtocol {
  func setState(state: StateController)
}

class StateController {
    var tdfvariables:tdfvars = tdfvars()
}

Note: Just use your own variables or whatever you are trying to keep track of instead, I just listed mine as an example in tdfvariables struct.

In each view of the TabController add the following member variable.

    class SettingsViewController: UIViewController {
    var stateController: StateController?
.... }

Then in those same files add the following:

extension SettingsViewController: StateControllerProtocol {
  func setState(state: StateController) {
    self.stateController = state
  }
}

What this does is allows you to avoid the singleton approach to passing variables between the views. This allows easily for the dependency injection model which is much better long run then the singleton approach.

Joseph Astrahan
  • 8,659
  • 12
  • 83
  • 154
3

Swift 5.3 + and iOS 13.0 +

Set your initial ViewController in "SceneDelegate.swift" // Only

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        setInitialViewController()
        window?.makeKeyAndVisible()
    }
    
    func setInitialViewController()  {
        
        // Set Story board Controller
        /*
         let storyboard = UIStoryboard(name: "Main", bundle: nil)
         let vc = storyboard.instantiateViewController(withIdentifier: "ViewController")
         */
        
        // Set Custom Xib
        let vc = FrontVC(nibName: "FrontViewController", bundle: nil)
        
        // Navigation Controller
        let nav = UINavigationController(rootViewController: vc)
        nav.isNavigationBarHidden = true
        window?.rootViewController = nav
    }
Lakhdeep Singh
  • 1,212
  • 13
  • 9
2

iOS 13+

In the SceneDelegate:

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options 
connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: windowScene)
    let vc = UIViewController() //Instead of UIViewController() we initilise our initial viewController
    window?.rootViewController = vc
    window?.makeKeyAndVisible()
}
Vadim Zhuk
  • 334
  • 2
  • 10
1
I worked out a solution on Xcode 6.4 in swift. 

// I saved the credentials on a click event to phone memory

    @IBAction func gotobidderpage(sender: AnyObject) {
 if (usernamestring == "bidder" && passwordstring == "day303")
        {
            rolltype = "1"

NSUserDefaults.standardUserDefaults().setObject(usernamestring, forKey: "username")
NSUserDefaults.standardUserDefaults().setObject(passwordstring, forKey: "password")
NSUserDefaults.standardUserDefaults().setObject(rolltype, forKey: "roll")


            self.performSegueWithIdentifier("seguetobidderpage", sender: self)
}


// Retained saved credentials in app delegate.swift and performed navigation after condition check


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

let usernamestring = NSUserDefaults.standardUserDefaults().stringForKey("username")
let passwordstring = NSUserDefaults.standardUserDefaults().stringForKey("password")
let rolltypestring = NSUserDefaults.standardUserDefaults().stringForKey("roll")

        if (usernamestring == "bidder" && passwordstring == "day303" && rolltypestring == "1")
        {

            // Access the storyboard and fetch an instance of the view controller
            var storyboard = UIStoryboard(name: "Main", bundle: nil)
            var viewController: BidderPage = storyboard.instantiateViewControllerWithIdentifier("bidderpageID") as! BidderPage

            // Then push that view controller onto the navigation stack
            var rootViewController = self.window!.rootViewController as! UINavigationController
            rootViewController.pushViewController(viewController, animated: true)
        }

        // Override point for customization after application launch.
        return true
    }



Hope it helps !
Alvin George
  • 14,148
  • 92
  • 64
1
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var exampleViewController: ExampleViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ExampleController") as! ExampleViewController

    self.window?.rootViewController = exampleViewController

    self.window?.makeKeyAndVisible()

    return true
}
ParkerHalo
  • 4,341
  • 9
  • 29
  • 51
1

Open a viewcontroller with SWRevealViewController From App delegate.

 self.window = UIWindow(frame: UIScreen.main.bounds)
 let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
 let swrevealviewcontroller:SWRevealViewController = storyboard.instantiateInitialViewController() as! SWRevealViewController 
 self.window?.rootViewController = swrevealviewcontroller
 self.window?.makeKeyAndVisible()
Abdul Qayyum
  • 77
  • 1
  • 6
0

For Swift 5+


var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            let submodules = (
                home: HomeRouter.createModule(),
                search: SearchRouter.createModule(),
                exoplanets: ExoplanetsRouter.createModule()
            )
            
            let tabBarController = TabBarModuleBuilder.build(usingSubmodules: submodules)
            
            window.rootViewController = tabBarController
            self.window = window
            window.makeKeyAndVisible()
        }
    }

Utsav Dave
  • 85
  • 1
  • 3
  • 9
0

I find this answer helpful and works perfectly for my case when i needed to change the rootviewcontroller if my app user already exist in the keychain or userdefault.

https://stackoverflow.com/a/58413582/6596443