Firebase Sign Out Not Changing Views Working - swift

I have some firebase code with a listener set up in AppDelegate and a log out set elsewhere. It is not taking me to the login view controller when I click sign out.
Logout Code:
#IBAction func logOutTapped(_ sender: Any) {
try! Auth.auth().signOut()
}
App Delegate Code:
let authListener = Auth.auth().addStateDidChangeListener { auth, user in
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
self.window = UIWindow(frame: UIScreen.main.bounds)
if user != nil
{
...//Some code
}
else
{
print("Headed to login view controller.")
let loginViewController = storyBoard.instantiateViewController(withIdentifier: "loginViewController") as! LoginViewController
self.window?.rootViewController = loginViewController
self.window?.makeKeyAndVisible()
}
I know the sign out code is calling the "else" in app delegate, because my logs are printing "Headed to login view controller" when I press logout. However, the login view controller is never displayed. It stays on the screen where the user clicks log out. When the app is stopped and started again, the login screen is displayed. The storyboard identifier is correctly set as loginViewController.
Any ideas?

Related

Open first View based on condition

I want my app to check at start conditionaly if a variable is correct or not. Based on that it should either go to an intro screen (where he can select a variable in my case select a team) or it should start the main view. After searching i found this code and edited it.
But there still seems to be problems. First of all I dont have two identifier. The Intro has one but not the main view. My main View is called WeatherViewController and the Intro screen is called FirstScreenViewController.
I also added a picture of my Main.storyboard.
I also googled a lot about conditional UINavigationController but I can only understand with a video and did not found a video about it.
I tried to use the code from here.
var id = hello ? "goToIntro" : "???"
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let WeatherViewController: UIViewController = mainStoryboard.FirstScreenViewController(withIdentifier: WVC has no identifier??) as UIViewController
self.window?.rootViewController = WeatherViewController
self.window?.makeKeyAndVisible()
if hello {
self.performSegue(withIdentifier: "goToIntro", sender: self)
} else {
/here nothing should happen. It should open the Main View
self.performSegue(withIdentifier: "???", sender: self)
}
Simply repeat the steps you did for creating the segue goToIntro.
Add a new UIViewController (MainViewController) in your storyboard.
Add a segue and give it an identifier.
Provide the identifier value in the else condition of the code that you've shown in your post to perform the segue to the UIViewController that you've just created.
The final code should look something like this:
var id = hello ? "goToIntro" : "goToMain"
guard let windowScene = scene as? UIWindowScene else { return }
window = UIWindow(windowScene: windowScene)
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let weatherViewController = mainStoryboard.instantiateInitialViewController()
window?.rootViewController = weatherViewController
window?.makeKeyAndVisible()
weatherViewController.performSegue(withIdentifier: id, sender: self)
You don't need the if else block since the id is already determined using the ? ternary operator.

Instantiating deep View Controller with Tab bar and Navigation

I am using Xcode 11 and Swift 5.
Upon receiving an APNS notification, I need to jump to a view controller deep in my storyboard from AppDelegate. This viewController (chatVC) is behind a tabbar and a navigation controller and several other view controllers. See the image below. I know how to check the notification for tags and how to use launchOptions in AppDelegate to trigger the jump. But I am struggling with how to establish the context for that last view controller so that the user can use the back button all the way back to the tab bar controller.
I have read many SO answers, and tried many approaches but none seem to have the same embedding of a nav controller inside a tab bar controller. Here is my code in AppDelegate (after reading the tag in the notification):
if tag == "CS" {
// Set up a Chat View Controller.
if let chatVC = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: Constants.Storyboard.chatVC) as? NewChatViewController,
let tabBarVC = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: Constants.Storyboard.tabBarController) as? UITabBarController,
let csVC = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: Constants.Storyboard.csViewController) as? CustomerServiceViewController,
let helpVC = UIStoryboard(name:"Main", bundle: .main).instantiateViewController(withIdentifier: Constants.Storyboard.helpVC) as? HelpViewController
{
// Set the customer service document Id.
chatVC.cs = cs
// Make the tabBarVC the Root View Controller
self.window?.rootViewController = tabBarVC
self.window?.makeKeyAndVisible()
// Select the Favorites Index.
tabBarVC.selectedIndex = 0
// Push the Customer Service VC on top.
tabBarVC.show(csVC, sender: Any?.self)
// Push the Help VC on top of Customer Service VC.
csVC.show(helpVC, sender: Any?.self)
// Push the the chat detail page on top.
helpVC.show(chatVC, sender: Any?.self)
}
}
}
return true
What can I do to jump to the chatVC and set up the navigation context beneath it so the back button can be used?
Here is how you can do it:
guard let tabBarVC = UIApplication.shared.windows.filter( {$0.rootViewController is UITabBarController } ).first?.rootViewController as? UITabBarController else { return }
tabBarVC.selectedIndex = 0 //you can select another tab if needed
guard let chatVC = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: Constants.Storyboard.chatVC) as? NewChatViewController else { return }
if let navController = tabBarVC.viewControllers?[0] as? UINavigationController {
navController.pushViewController(chatVC, animated: true)
}
You can also pass objects from your notification to your chatVC here before pushing it, in case you need to do that.
Hope this works for you!

dismiss passcode lock screen with correct passcode to last view

I currently have a function in my app delegate willEnterForeground method that if the app goes to background, upon coming to the foreground, it presents a passcode lock screen. The code for the willEnterForeground is as such
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var vc : UIViewController
vc = storyboard.instantiateViewController(withIdentifier: "IdleLockVC")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
print("app entered foreground")
}
My question is, is there an easy way to dismiss the passcode view (logic for determining the correct code is working) to the screen it was before? If not with my current setup, what would i need to change? am i not presenting the passcode screen and therefore can't just dismiss it?
A possible solution would be awesome.

How to push require view controller to navigation controller in swift

I am developing a application which has login screen and verify code screen. Once user logged in,and logout I need to show only login screen so how can I manage the navigation view controller. Right now, my verifycode view controller is coming first before showing the login view controller when I am pressing the sign out button.
Could you please let me know how can I manage the view controller?
You can use this method didFinishLaunchingWithOptions (AppDelegate):
self.window = UIWindow.init(frame: UIScreen.main.bounds)
if (User.isLogged) {
window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "loginVC") as! LoginVC
} else {
window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()!
}
self.window?.makeKeyAndVisible()
Create class User when you can storage information about status user (Authorized or not) and in didFinishLaunchingWithOptions check this status and set rootViewController for window.

See view in tab bar when login success

I have 4 tabs in Tabbar View Controller in storyboard. When open app tab 1 appear and when tap tab 2-4 I want to show modal view for login. When login success, app will show view in tab 2-4. How can I do this ?
you did not provide information on how you want to make a check if the user is logged in. but anyway, here is what i did with Firebase
in tab 2-4, check if user is logged in in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
FIRAuth.auth()?.addAuthStateDidChangeListener({ (auth, user) in
if let user = user {
} else {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let signInViewController = storyboard.instantiateViewControllerWithIdentifier("SignIn")
self.presentViewController(signInViewController, animated: true, completion: nil)
}
})
}
once the view is loaded, it will check if the user is logged in, if not present the viewcontroller SignIn
once logged in is completed, you just have to dismiss the viewcontroller and it would return to which tab that the user clicked on previously
dismissViewControllerAnimated(true, completion: nil)