0

I am pretty new to programming, thats why I can't really figure out how to solve this issue. I have implemented a rootviewcotnroller in the app delegate so that if the user is logged in he is pushed directly to the app content instead of the login view controller. However it doesn't really work. As is already said I added the following code to the app delegate:

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()
    window?.rootViewController = MainViewController()

The MainViewcontroller is set up like this:

class MainViewController: UINavigationController {

override func viewDidLoad() {
    super.viewDidLoad()
    if isLoggedIn() {
        let homeController = UserViewController()
        viewControllers = [homeController]

    }else {

        perform(#selector(showLoginController), with: nil, afterDelay: 0.01)
    }
}

fileprivate func isLoggedIn() -> Bool {
    return UserDefaults.standard.isLoggedIn()
}

func showLoginController() {
    let loginController = LoginViewController()
    present(loginController, animated: true, completion: {

    })
 }
}

To the Userviewcontroller I have added the following lines:

 func handleSignout() {

    UserDefaults.standard.setisLoggedIn(value: false)
    print("is logged out")

}

@IBAction func SignOut(_ sender: Any) {

    handleSignout()
    if FIRAuth.auth()!.currentUser != nil {

        do {
        try? FIRAuth.auth()?.signOut()

            if FIRAuth.auth()?.currentUser == nil {
                let loginViewViewcontroller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Login") as! LoginViewController
                self.present(loginViewViewcontroller, animated: true, completion: nil)
            }
        }   
    }
}

Then I have created an extension with the UserDefaults to save the boolean Value whether the user is logged in or logged out:

extension UserDefaults {

enum UserDefaultKeys: String {
    case isLoggedIn
}

func setisLoggedIn(value: Bool) {
    set(false, forKey: UserDefaultKeys.isLoggedIn.rawValue)
    synchronize()   
}

func isLoggedIn() -> Bool {
    return bool(forKey: UserDefaultKeys.isLoggedIn.rawValue)
}

}

In the LoginviewController, which just shows a black screen if shown at first sight, I have added :

  func finishLoggingIn() {

    let rootViewController = UIApplication.shared.keyWindow?.rootViewController
    guard let MainNavigationController = rootViewController as? MainViewController else {return}
    MainNavigationController.viewControllers = [UserViewController()]
    print("is logged in")
    UserDefaults.standard.setisLoggedIn(value: true)

    dismiss(animated: true, completion: nil)

}

This function is called when user pushes the login button.

The app recognizes if the user is logged or not, but it doesn't matter if the user is logged in or not, that first view controller which is presented shows a black screen, which is most likely the loginviewcontroller but if the user is logged in the userviewcontroller shows a black screen as well if is the first view controller to be presented. ...

Has anybody an idea why that is?

AlexVilla147
  • 283
  • 2
  • 15
  • http://stackoverflow.com/questions/39776929/swift-3-xcode-8-instantiate-view-controller-is-not-working I don't see how your MainViewController is instantiated in any way. And looking through your code, it seems like MainViewController is not even a UIViewController ? –  Apr 02 '17 at 19:28
  • The mainviewcontroller is set as the new rootviewcontroller in the app delegate. So whenever the app is started the mainviewcontroller is called first. With the logged in function it should switch to either the loginviewcontroller or the userviewcontroller. The Mainviewcontroller is a navigationcontroller which is subclass of a uiviewcontroller?! – AlexVilla147 Apr 02 '17 at 19:44
  • @AlexVilla are you creating your own windows without using storyboard? – Tushar Sharma Apr 02 '17 at 19:58
  • @Tushar Sharma sry I don't really understand you question. To be honest most of the code which is used to implement that rootviewcontroller is from a youtube tutorial in which everything works perfectly fine. But for me, all the steps makes sense. Since it doesn't worj though i am asking stackoverflow. – AlexVilla147 Apr 02 '17 at 20:05
  • @AlexVilla147 My point is are you doing all by code or using storyboard as well? – Tushar Sharma Apr 02 '17 at 20:06
  • I use the storyboard for most of the time. Just the facebook button is added withouth the storyboard. And it is the only things which is shown in the loginvoewcontroller. – AlexVilla147 Apr 02 '17 at 20:09

1 Answers1

1

I have figured out how to solve it. It is way easier then I expected it to be. Maybe the solution I've found is not the best way of doing it, but as long as it works I am happy!

I deleted all function with the UserDefaults. To my MainViewController I have just added a the following code, which is suggested by Firebase itself:

import UIKit
import FirebaseAuth

 // DIeser Viewcontroller wird immer als erstes aufgerufen und entscheidet, ob der loginviewcontroller gestartet wird oder  der UserViewController gestartet wird. 

class MainViewController: UINavigationController {


override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white

    FIRAuth.auth()?.addStateDidChangeListener() { (auth, user) in
        if user != nil {

            let LoginVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "usersVC")

            self.present(LoginVc, animated: true, completion: nil)

        }else {

            let UserVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVc")

            self.present(UserVc, animated: true, completion: nil)
        }
    }
  }
}

The MainViewController is still set as the rootviewcontroller in the AppDelegate. I hope I helps someone else in the future!

AlexVilla147
  • 283
  • 2
  • 15