3

I got some logic I want to do in my LaunchScreen, and if the check is alright, I want to segue to a viewController and if not I want to segue to another, is that possible?

Recusiwe
  • 1,594
  • 4
  • 31
  • 54

5 Answers5

2

I got some logic I want to do in my LaunchScreen

Now that I understand the question, I can answer it: don't. Do your time-consuming logic later. Your job is to launch fast. You need to get out of applicationDidFinishLaunchingWithOptions, get out of viewDidLoad, and launch.

What you show at that point is up to you; if you have time-consuming stuff (in your case, it sounds like you're networking or doing something else that takes time while you load up the data source for a table) and you want to show a special view controller that covers the time with a spinning activity view or something, fine. But during actual launch is not the time to do that.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • @SAHM Isn't this what we were just talking about at https://stackoverflow.com/questions/51884528/is-rootviewcontroller-always-ready-to-present-a-segue-by-the-time-applicationdi ? _You_ do not launch. The runtime is launching you, and your job is to get out of its way and let it do so. You do not "know when you are out of `viewDidLoad`". You simply implement the event messages to do what is appropriate at the moment they signify, no more and no less. – matt Aug 17 '18 at 00:42
1

No you cant code for launchScreen.Storyboard, The reason why :- when your launchScreen.storyboard shows the app is still loading.

Simply put: You cant access your app when it is displaying launchScreen.storyboard, all you can do is make a UI/UX for that not execute any code for it.

Alternative:- Make a viewController that appears as a first viewController check your logic there and do things from there accordingly!

Reference : - https://stackoverflow.com/a/27642160/6297658

Community
  • 1
  • 1
Dravidian
  • 9,945
  • 3
  • 34
  • 74
0

Run your check in didFinishLaunchingWithOptions() and use that to "jump" directly to a specific vc. Here's an example using userDefaults, but of course you can replace that with whatever check you're running.

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

        // Do some logic

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let welcomeVC = storyboard.instantiateViewControllerWithIdentifier("WelcomeNavController")
            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
            self.window?.rootViewController = welcomeVC
            self.window?.makeKeyAndVisible()
        }
}
Shades
  • 5,568
  • 7
  • 30
  • 48
  • Is there any way I can keep showing the launchscreen while doing some logic? I don't want the launchscreen to go away before the logic is complete. – Recusiwe Sep 13 '16 at 14:27
  • @Recusiwe that's a good question and I don't really know the answer. I'm guessing it depends on where the logic is, appDelegate or in a view controller, but that's just a guess – Shades Sep 13 '16 at 15:33
  • Yea, I want to do some logic in appDelegate and depending on the outcome of the logic, I want to show a specific viewcontroller. – Recusiwe Sep 13 '16 at 15:51
  • @Recusiwe yes, have you implemented my answer in your code. It will do that – Shades Sep 13 '16 at 15:55
  • @Recusiwe see updated answer. Don't forget to accept f it helps ;) – Shades Sep 13 '16 at 15:57
  • "Is there any way I can keep showing the launchscreen while doing some logic? I don't want the launchscreen to go away before the logic is complete" No. If you take too long to launch, you will be killed dead by WatchDog. On the contrary, you must launch _as quickly as possible_. – matt Sep 13 '16 at 15:59
  • @matt what gets shown then when the launch screen goes away? The beginnings of the initial viewcontroller? – Shades Sep 13 '16 at 16:07
  • Yes. You must launch to _something_ immediately. If you have time-consuming logic (e.g. networking), do it in the background. If you want to show the user a view controller that looks like your launch screen so that everything stays frozen, hey, I can't stop you. :) But the point is that you must get out of `didFinishLaunching` and get out of `viewDidLoad` and _launch_ very quickly. What you do _after_ that is your affair. – matt Sep 13 '16 at 16:09
  • @matt Good to know. I actually moved code setting up my data source from my initial vc to the appDelegate because I didn't like the unfinished table being shown while the data was ready, but I'll rethink that – Shades Sep 13 '16 at 16:11
  • @matt I didn't mean setting up the data, I meant showing a welcome screen – Shades Sep 13 '16 at 16:12
  • 1
    "I didn't like the unfinished table being shown while the data was ready, but I'll rethink that" That is what I'm advising you to do. You can show something else in the interim, but it can't be the LaunchScreen.storyboard while your app spins its wheels getting launched. You must launch _fast_. Hope that helps. (PS There's a WWDC video on this very topic.) – matt Sep 13 '16 at 16:18
  • I also provided this as an answer. Your question is reasonable and posterity needs to know what you're supposed to do in this situation. :) – matt Sep 13 '16 at 16:41
0

Your LaunchScreen is shown while your app is loading. Go to your AppDelgate:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {

    window.rootViewController = //your root view controller that you have figured out with logic

    return true
}
Pranav Wadhwa
  • 7,666
  • 6
  • 39
  • 61
0

Add this function into the AppDelegate:

func initialVC(storyboardID: String) {

    let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let initialViewController : UIViewController = mainStoryboard.instantiateViewControllerWithIdentifier("\(storyboardID)") as UIViewController
    self.window?.makeKeyAndVisible()

    if storyboardID == "tabBarVC" {

        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.rootViewController = initialViewController

    } else {

        let navController = UINavigationController(rootViewController: initialViewController)
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.rootViewController = navController

    } 
}

In the didFinishLaunchingWithOptions method inside of the AppDelegate, you can add this:

if currentUser != nil {

    initialVC("tabBarVC")

} else {

    initialVC("loginVC")

}

You can see in my example, I am either loading the main app VC or the Login VC depending on if the user is logged in. In your case, You can use an if - else statement and do the logic within the initialVC function.

Note: When I call for the loginVC to be loaded, I have to load the navigationController because the loginVC is embedded in a navigationController. For the tabBarVC, I don't embed the navController because it isn't needed.

Dan Levy
  • 3,931
  • 4
  • 28
  • 48