0

NavigationController is isinitial viewcontroller in storyboard, NavigationController embedded to LoginViewcontroller

in project storyboard navigation willbe like below

NavigationController->LoginViewcontroller-> RegistrationViewcontroller -> MainViewcontroller

in successful registration with PhNUmber i am getting userId which i have stored in KeychainWrapper

in RegistrationViewcontroller: i am storing userId like below:

 let userID: String=jsonObj?["userId"] as? String ?? "" 
 KeychainWrapper.standard.set(userID, forKey: "USERID")

which i am checking in appdelegate like below to go Mainviewcontroller:

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var savedUserId: String?

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

    savedUserId = KeychainWrapper.standard.string(forKey: "USERID")
    print("appdelegate userid \(savedUserId)")
    if savedUserId != nil{
        print("saveuserid \(savedUserId)")
        let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
        window?.rootViewController = mainStoryBoard.instantiateViewController(withIdentifier: "MainViewController")
    }
    return true
}
}

here savedUserId coming then why i am not going to MainViewcontroller, all the time LoginViewcontroller appears

Swift
  • 1,074
  • 12
  • 46

3 Answers3

1

You need to initialize the window. Give this line above setting the rootViewController:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var savedUserId: String?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        savedUserId = KeychainWrapper.standard.string(forKey: "USERID")
        print("appdelegate userid \(savedUserId)")
        if savedUserId != nil{
            print("saveuserid \(savedUserId)")
            let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
            window = UIWindow()
            window?.rootViewController = mainStoryBoard.instantiateViewController(withIdentifier: "MainViewController")
        }
        return true
    }
}

Update: If you're using SceneDelegate you should use this:

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)print("appdelegate userid \(savedUserId)")
        if savedUserId != nil{
            print("saveuserid \(savedUserId)")
            let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
            window = UIWindow()
            window?.rootViewController = mainStoryBoard.instantiateViewController(withIdentifier: "MainViewController")
        }
    }
}
Frankenstein
  • 15,732
  • 4
  • 22
  • 47
  • if i give like this `var window = UIWindow()` then error: Type of 'window' has different optionality than required by protocol 'UIApplicationDelegate' – Swift Jun 05 '20 at 11:32
  • var window: UIWindow? and in `didFinishLaunchingWithOptions` in window = UIWindow() window?.rootViewController = mainStoryBoard.instantiateViewController(withIdentifier: "MainViewController")............then also login viewcontroller appears – Swift Jun 05 '20 at 11:35
  • I doubt If you're providing your answer as I expect. So I've updated my answer to the entire code that you've provided. – Frankenstein Jun 05 '20 at 11:46
  • both userid coming appdelegate userid Optional("415c6073d45a481f991cb81b4c81bf81") saveuserid Optional("415c6073d45a481f991cb81b4c81bf81"). but loginviewcontroller coming – Swift Jun 05 '20 at 11:53
  • Could you check if `mainStoryBoard.instantiateViewController(withIdentifier: "MainViewController") != nil` is getting `true`. – Frankenstein Jun 05 '20 at 11:54
  • @iOSApp If you're using SceneDelegate you should be using the update I've just posted. – Frankenstein Jun 05 '20 at 12:07
  • SceneDelegate file is there but i am not using.. i am using appdelegate only – Swift Jun 05 '20 at 12:17
  • That doesn't count. If you're not using SceneDelegate then delete it and remove its reference from `info.plist`. – Frankenstein Jun 05 '20 at 12:19
  • oh yeah I have deleted both SceneDelegate file and its reference then its working.. thanks for that information – Swift Jun 06 '20 at 09:41
  • if there is a chance pls suggest me here https://stackoverflow.com/questions/63406320/how-to-stop-autofilling-address-in-textfields-in-swift – Swift Aug 14 '20 at 07:40
1

Try using this extension

  // add this function in your AppDelegate

  func makeRootVC(_ storyBoardName : String, _ vcName : String) {
        let vc = UIStoryboard(name: storyBoardName, bundle: Bundle.main).instantiateViewController(withIdentifier: vcName)
        let nav = UINavigationController(rootViewController: vc)
        nav.navigationBar.isHidden = true
        self.window?.rootViewController = nav
        let options: UIView.AnimationOptions = .transitionCrossDissolve
        let duration: TimeInterval = 0.6
        UIView.transition(with: self.window!, duration: duration, options: options, animations: {}, completion: nil)
    }

then use it like this in your didFinishLaunchingWithOptions

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

    savedUserId = KeychainWrapper.standard.string(forKey: "USERID")
    print("appdelegate userid \(savedUserId)")
    if savedUserId != nil{
        print("saveuserid \(savedUserId)")
        self.makeRootVC("Main","MainViewController")
    }
    return true
}
Keshu R.
  • 5,045
  • 1
  • 18
  • 38
  • UIView.transition(with: self.window!, duration: duration, options: options, animations: {}, completion: nil). error: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value – Swift Jun 05 '20 at 11:14
  • @iOSApp Are you using `SceneDelegate` too ? – Keshu R. Jun 05 '20 at 11:15
  • yes SceneDelegate is there, but in the same line same error – Swift Jun 05 '20 at 11:30
  • @iOSApp Refer this for setting rootViewController from sceneDelegate https://stackoverflow.com/questions/58188296/how-set-rootviewcontroller-in-scene-delegate-ios-13 – Keshu R. Jun 05 '20 at 11:50
1

check if window is nil and add makeKeyAndVisible() after setting rootViewController in AppDelegate

if(window == nil){
    self.window = UIWindow(frame:UIScreen.main.bounds)
}
if savedUserId != nil{
    print("saveuserid \(savedUserId)")
    let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
    window?.rootViewController = mainStoryBoard.instantiateViewController(withIdentifier: "MainViewController")
    self.window?.makeKeyAndVisible()
}
SM Abu Taher Asif
  • 2,221
  • 1
  • 12
  • 14
  • if i print userid in `if(window == nil){` both prints but not going to mainviewcontroller – Swift Jun 05 '20 at 13:15