How do I programmatically set the InitialViewController for a Storyboard? I want to open my storyboard to a different view depending on some condition which may         
        
If you prefer not to change applicationDidFinish, you can do the following trick:
Set Navigation controller as an initial view controller and assign to it a custom class 'MyNavigationController'. Then you can tweak its root view controller during viewDidLoad - it will override the root view controller that you set in your storyboard.
class MyNavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if !isLoggedIn() {
            viewControllers = [R.storyboard.authentication.loginView()!]
        }
    }
    private func isLoggedIn() -> Bool {
        return false
    }
}
You can programmatically set the key window's rootViewController in (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
for example:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (shouldShowAnotherViewControllerAsRoot) {
        UIStoryboard *storyboard = self.window.rootViewController.storyboard;
        UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"rootNavigationController"];
        self.window.rootViewController = rootViewController;
        [self.window makeKeyAndVisible];
    }
    return YES;
}
Swift 3: Update to @victor-sigler's code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)
    // Assuming your storyboard is named "Main"
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    // Add code here (e.g. if/else) to determine which view controller class (chooseViewControllerA or chooseViewControllerB) and storyboard ID (chooseStoryboardA or chooseStoryboardB) to send the user to
    if(condition){
        let initialViewController: chooseViewControllerA = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardA") as! chooseViewControllerA
        self.window?.rootViewController = initialViewController
    )
    }else{
        let initialViewController: chooseViewControllerB = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardB") as! chooseViewControllerB
        self.window?.rootViewController = initialViewController
    )
    self.window?.makeKeyAndVisible(
    return true
}
I created a routing class to handle dynamic navigation and keep clean AppDelegate class, I hope it will help other too.
//
//  Routing.swift
// 
//
//  Created by Varun Naharia on 02/02/17.
//  Copyright © 2017 TechNaharia. All rights reserved.
//
import Foundation
import UIKit
import CoreLocation
class Routing {
    class func decideInitialViewController(window:UIWindow){
        let userDefaults = UserDefaults.standard
        if((Routing.getUserDefault("isFirstRun")) == nil)
        {
            Routing.setAnimatedAsInitialViewContoller(window: window)
        }
        else if((userDefaults.object(forKey: "User")) != nil)
        {
            Routing.setHomeAsInitialViewContoller(window: window)
        }
        else
        {
            Routing.setLoginAsInitialViewContoller(window: window)
        }
    }
    class func setAnimatedAsInitialViewContoller(window:UIWindow) {
        Routing.setUserDefault("Yes", KeyToSave: "isFirstRun")
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let animatedViewController: AnimatedViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnimatedViewController") as! AnimatedViewController
        window.rootViewController = animatedViewController
        window.makeKeyAndVisible()
    }
    class func setHomeAsInitialViewContoller(window:UIWindow) {
        let userDefaults = UserDefaults.standard
        let decoded  = userDefaults.object(forKey: "User") as! Data
        User.currentUser = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! User
        if(User.currentUser.userId != nil && User.currentUser.userId != "")
        {
            let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let homeViewController: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
            let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
            loginViewController.viewControllers.append(homeViewController)
            window.rootViewController = loginViewController
        }
        window.makeKeyAndVisible()
    }
    class func setLoginAsInitialViewContoller(window:UIWindow) {
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
        window.rootViewController = loginViewController
        window.makeKeyAndVisible()
    }
  class func setUserDefault(_ ObjectToSave : Any?  , KeyToSave : String)
    {
        let defaults = UserDefaults.standard
        if (ObjectToSave != nil)
        {
            defaults.set(ObjectToSave, forKey: KeyToSave)
        }
        UserDefaults.standard.synchronize()
    }
    class func getUserDefault(_ KeyToReturnValye : String) -> Any?
    {
        let defaults = UserDefaults.standard
        if let name = defaults.value(forKey: KeyToReturnValye)
        {
            return name as Any
        }
        return nil
    }
    class func removetUserDefault(_ KeyToRemove : String)
    {
        let defaults = UserDefaults.standard
        defaults.removeObject(forKey: KeyToRemove)
        UserDefaults.standard.synchronize()
    }
}
And in your AppDelegate call this
 self.window = UIWindow(frame: UIScreen.main.bounds)
 Routing.decideInitialViewController(window: self.window!)
You can set Navigation rootviewcontroller as a main view controller. This idea can use for auto login as per application requirement.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UIViewController viewController = (HomeController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"HomeController"];
UINavigationController navController = [[UINavigationController alloc] initWithRootViewController:viewController];
 self.window.rootViewController = navController;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
    // do stuff for iOS 7 and newer
    navController.navigationBar.barTintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
    navController.navigationItem.leftBarButtonItem.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
    navController.navigationBar.tintColor = [UIColor whiteColor];
    navController.navigationItem.titleView.tintColor = [UIColor whiteColor];
    NSDictionary *titleAttributes =@{
                                     NSFontAttributeName :[UIFont fontWithName:@"Helvetica-Bold" size:14.0],
                                     NSForegroundColorAttributeName : [UIColor whiteColor]
                                     };
    navController.navigationBar.titleTextAttributes = titleAttributes;
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
else {
    // do stuff for older versions than iOS 7
    navController.navigationBar.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
    navController.navigationItem.titleView.tintColor = [UIColor whiteColor];
}
[self.window makeKeyAndVisible];
For StoryboardSegue Users
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
// Go to Login Screen of story board with Identifier name : LoginViewController_Identifier
LoginViewController *loginViewController = (LoginViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:@“LoginViewController_Identifier”];
navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
// Go To Main screen if you are already Logged In Just check your saving credential here
if([SavedpreferenceForLogin] > 0){
    [loginViewController performSegueWithIdentifier:@"mainview_action" sender:nil];
}
Thanks
Swift 4, Xcode 9
in file AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let firstVC = storyboard.instantiateViewController(withIdentifier: "firstViewController") as! firstViewController
    self.window?.rootViewController = firstVC
}