Swift go back to root view controller - ios

I am new to swift but I have implemented FCM but I am having an issue. When I click the notification it loads the NotificationsViewController with the following code.
let sb = UIStoryboard(name: "Main", bundle: nil)
let otherVC = sb.instantiateViewController(withIdentifier: "NotificationsViewController") as! NotificationsViewController
self.window?.rootViewController = otherVC;
Once the NotificationsViewController is loaded I use the following code in on the back button to reassign the root view back to the normal ViewController.
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let redViewController = mainStoryBoard.instantiateViewController(withIdentifier: "splashScreen") as! ViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = redViewController
Once I am on the splashScreen it should show a quick image and then move on to the main dashboard using this code.
let vw = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DashboardViewController") as! DashboardViewController
self.navigationController?.pushViewController(vw, animated: true)
The problem I am having is the splashScreen code is not working when the app loads it from NotificationsViewController, it just hangs on that VC, but if I load the splashScreen without reassigning the root view it works.
So is there some other way I should be doing this? I just want to take the user to the NotificationsViewController when they click the notification and then back to the main part of the app when they click a back button.

If you just need to show the NotificationViewController, you just present it in fullscreen. You can set it by vc.modalPresentationStyle = .fullScreen. Then to go back to the main app, you just need to dismiss it. :)

Related

Why does pushViewController doesn't work after navigating through Dynamic Link?

I'm building an app that can receive Firebase's Dynamic Link and redirects it into a certain UIViewController after clicking the link. So based on this question that I asked, I have the code in AppDelegate.swift that navigates the app to the UIViewController like this:
func goToDynamicLinkVC() { // This function is in AppDelegate.swift
let destinationStoryboard: UIStoryboard = UIStoryboard(name: "DynamicLink", bundle: nil)
let destinationVC = destinationStoryboard.instantiateViewController(withIdentifier: "DynamicLinkView") as? DynamicLinkVC
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = destinationVC
self.window?.makeKeyAndVisible()
}
And in that UIViewController I also have a function that moves to another UIViewController if a user pressed a button like this:
func routeToDynamicForm() { // This function is in DynamicLinkVC class
let destinationVC = UIStoryboard(name: "DynamicLink", bundle: nil).instantiateViewController(withIdentifier: "DynamicFormView") as! DynamicFormVC
self.navigationController?.pushViewController(destinationVC, animated: true)
}
But weirdly enough now that I pressed the button it doesn't move me to the next View Controller (in this case, DynamicFormVC). I've tried to debug the button whether it's working or not by doing this:
print("button tapped")
It shows the message on the debug area, but it still doesn't redirects to the next view controller. So what can I do to resolve this? If you need more information feel free to ask and I will provide it to you. Thank you.
I changed the goToDynamicLinkVC function to something like this:
func goToDynamicLinkVC() { // This function is in AppDelegate.swift
let destinationStoryboard: UIStoryboard = UIStoryboard(name: "DynamicLink", bundle: nil)
let destinationVC = destinationStoryboard.instantiateViewController(withIdentifier: "DynamicLinkView")
let navController = UINavigationController()
navController.setViewControllers([destinationVC], animated: true)
self.window?.rootViewController = navController
}

HomeViewController not loading after Firebase Google SignIN in AppDelegate.swift

I have successfully configured google sign in my iOS App using Firebase.
After a successful login, I need to make the UIViewController move to HomeViewController.
The AppDelegate class has "didSignInFor" method in which I have added the following code
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "HomeVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
HomeVC is a storyboard id of HomeViewController and restoration id is also same.
But still, it doesn't take me to HomeViewController.
I have referred this stack overflow posts.
Opening view controller from app delegate using swift
Please tell me where I am going wrong. I have referred this video for building the app.
https://www.youtube.com/watch?v=20Qlho0G3YQ
Here's my AppDelegate.swift file https://pastebin.com/WfzhYAKH
Try:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "HomeVC")
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
This works for me.
Please comment if you have any questions. Happy to Help!

Swift storyboard login order

I am relatively new to Swift and I don't have much experience with the events and functions. After investigating a little I started working on a login screen on an existing app that didn't have it before. Here's what I decided to do.
My flow goes in this order:
Login screen
After successful login I save the session info
After login screen I show the main screen using a segue
If I close and reopen the app, my login screen is still the start screen, but inside viewDidAppear I have a session check and if the session exists I perform the segue to show the main controller.
I've seen that users do this the other way around - showing the main screen first and if there's no login session they cover it with the login screen or basically show the login screen first.
In my way of doing this, what I don't like is that the login screen always appears, although to be honest it does the job for this app in specific.
Is there a way to do this without the login screen appearing when there's a session? How is this ideally done in terms of order: login screen first or login screen second? And also, what is better to use, a navigation controller for the changes or segues are enough?
many here say is not recomended doing this way but i'll use appDelegate for this, in didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if requestManager.instance.token != nil {
if requestManager.instance.user.birthDate != nil && requestManager.instance.user.iscomplete() {
print("GOING TO TABBARVC")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "TabBarVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}else if requestManager.instance.user.birthDate != nil && !requestManager.instance.user.iscomplete(){
print("GOING TO DATANC")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "TabBarVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}else{
print("GOING TO REGISTER")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "register")
//loginRequest.instance.delegate = initialViewController as profileViewController
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
}
so what i check here is for token saved in userdefault. could be checked from keycahin is it's critical, and depeding on what is found may show one or another screen, the last case is just in case where no data at all going to register or login screen.
so you could check for session is there is a session amke window show the main screen no session go to login screen
just like this in code:
if sesion != nil {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "MainVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}else{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "loginVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
where MainVC is te id in the storyBoard for the mainViewcontroller and loginVC is the storyboard Idetntifier for loginViewController.

MFSideMenu menuContainerViewController is nil

I'm trying to use MFSideMenu but when I ask for the menu to open the app breaks because menuContainerViewController is empty
This is the code that creates the menu at appDelegate (didFinishLaunchingWithOptions):
let s = UIStoryboard(name: "Main", bundle: nil)
let contentView = s.instantiateInitialViewController()
let leftMenu = s.instantiateViewControllerWithIdentifier("LeftMenuViewController") as! LeftMenuViewController
let container:MFSideMenuContainerViewController = MFSideMenuContainerViewController.containerWithCenterViewController(contentView, leftMenuViewController: leftMenu, rightMenuViewController: nil)
window?.rootViewController = container
window?.makeKeyAndVisible()
this is the code responsible for opening my menu:
self.menuContainerViewController.toggleLeftSideMenuCompletion({})
what might be happening? I installed the library using CocoaPods and I'm importing it properly.
Try this one,
self.menuContainerViewController.toggleLeftSideMenuCompletion(nil)

Setting rootViewController then navigate to next view programatically

Initially I have a hierarchy below after login
-> MyCoursesViewController
-> CourseInfo UITabBarController
If the user closes the app, then re-enters, the rootViewController will be the CourseInfo UITabBarController which is correct. However when the user needs to view a different course (exits the course), they can’t go ‘back’ to MyCoursesViewController because its no longer on the stack.
In AppDelegate:
if (inCourse) {
let storyboard : UIStoryboard = UIStoryboard(name: “Main”, bundle: nil)
let courseInfoTabController = storyboard.instantiateViewControllerWithIdentifier(“CourseInfo”) as! UITabBarController
self.window?.rootViewController = courseInfoTabController
} else {
let storyboard : UIStoryboard = UIStoryboard(name: “Main”, bundle: nil)
let myCoursesViewController = storyboard.instantiateViewControllerWithIdentifier(“MyCourses”)
self.window?.rootViewController = myCoursesViewController
}
Is there some way I can put the MyCoursesViewController as the rootViewController then automatically navigate to Course Info UITabBarController just so the MyCoursesViewController is on the hierarchy incase they hit back (exits the course)?
Alternatively is it better if the user exits the course (hit back), we delete the rootViewController somehow and replace with a new rootViewController? Another option is if we just replace the rootViewController, will the old one be freed from memory or is it still referenced somewhere?
e.g.
CourseInfo UITabBarController is currently still rootViewController but now we swap it out with a new one
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let myCoursesViewController = mainStoryBoard.instantiateViewControllerWithIdentifier(“MyCourses”) as! ViewController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window?.rootViewController = myCoursesViewController
In your AppDelegate you can set your hierarchy. Try with something like:
let storyboard : UIStoryboard = UIStoryboard(name: “Main”, bundle: nil)
let myCoursesViewController = storyboard.instantiateViewControllerWithIdentifier(“MyCourses”)
if isInCourse{
let courseInfoTabController = storyboard.instantiateViewControllerWithIdentifier(“CourseInfo”) as! UITabBarController
let navigationBar = UINavigationController()
navigationBar.setViewControllers([myCoursesViewController,courseInfoTabController], animated: false)
self.window?.rootViewController = navigationBar
}else{
self.window.rootViewController = myCoursesViewController
}

Resources