userId coming to appdelegate still not going to Mainviewcontroller why? in swift - swift

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

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")
}
}
}

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
}

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()
}

Related

Error: Missing return in a closure expected to return 'UIViewController' (Xcode, Swift, iOS 13)

I'm getting the error: "Missing return in a closure expected to return 'UIViewController'" on the bolded line. How can I fix this? Thank you!!
Var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let hasSession = UserDefaults.standard.value(forKey: "UserHasSubmittedPassword") as? Bool
let vc: UIViewController = {
if let hasSession = hasSession, hasSession == true {
// next vc you want to show
} else {
// enter password vc
}
**}()**
let navigationController = UINavigationController(rootViewController: vc)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
return true
}
you just need to return ViewController inside closure
Var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let Myvc = UIViewController()
let hasSession = UserDefaults.standard.value(forKey: "UserHasSubmittedPassword") as? Bool
let vc: UIViewController = {
if let hasSession = hasSession, hasSession == true {
// next vc you want to show
return Myvc
} else {
// enter password vc
return Myvc
}
**}()**
let navigationController = UINavigationController(rootViewController: vc)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
return true
}

Appdelegate sigabrt not appearing anything ! in main storyboard

I am making a newsfeed and when I try to add a post it appears this alert[SIGABRT]and not go to the next viewController to write the post here it's a picture , any idea?
and those are some ss from the breakpoint and exception.
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let authListener = Auth.auth().addStateDidChangeListener { auth, user in
let storyboard = UIStoryboard(name: "Main", bundle: nil )
if user != nil {
UserService.observeUserProfile(user!.uid) { UserProfile in
UserService.currentUserProfile = UserProfile
}
//
let controller = storyboard.instantiateViewController(withIdentifier: "MainTabBarController") as! UITabBarController
self.window?.rootViewController = controller
self.window?.makeKeyAndVisible()
} else {
UserService.currentUserProfile = nil
let controller = storyboard.instantiateViewController(withIdentifier: "MenuViewController") as! ViewController
self.window?.rootViewController = controller
self.window?.makeKeyAndVisible()
}
}
return true
}
}

iOS - How to remove UINavigationController from AppDelegate? [duplicate]

This question already has answers here:
Removing NavigationController Programmatically
(2 answers)
Closed 4 years ago.
I have to remove UINavigationController from my app to add UITabBarController and keep
my if statement works as is.
My Code :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if UserDefaults.standard.value(forKey: "URL") == nil
{
let viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
let navController = UINavigationController(rootViewController: viewController)
self.window?.rootViewController = navController
self.window?.makeKeyAndVisible()
}else{
let viewController = storyboard.instantiateViewController(withIdentifier: "ChannelsViewController") as! ChannelsViewController
let navController = UINavigationController(rootViewController: viewController)
self.window?.rootViewController = navController
self.window?.makeKeyAndVisible()
}
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if UserDefaults .standard .value(forKey: "URL") == nil
{
let viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
}else{
let viewController = storyboard.instantiateViewController(withIdentifier: "ChannelsViewController") as! ChannelsViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
}
return true
}

Swift, Firebase - Present different ViewControllers in AppDelegate if User is Logged-in

I'm using Firebase for my app and I want to present different view controllers in AppDelegate with the code below but I keep getting an error.
import UIKit
import Firebase
import FirebaseAuth
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
if Auth.auth().currentUser != nil {
window?.rootViewController = HomeController()
} else {
window?.rootViewController = LoginController()
}
return true
}
...
This is the error.
libc++abi.dylib: terminating with uncaught exception of type
NSException
(lldb)
How can I fix this problem?
Swift 4.0
You can use this function as like below in AppDelegate.
func configureWindowAndMakeVisible(rootVC: UIViewController) {
if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
window.rootViewController = rootVC
window.makeKeyAndVisible()
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if Auth.auth().currentUser != nil {
// Use initialization (i.e HomeController()) only if you had initialize view in Controller
configureWindowAndMakeVisible(rootVC: HomeController())
} else {
configureWindowAndMakeVisible(rootVC: LoginController())
}
return true
}
First of all, you need to know that you need a reference to the already created instance instead of creating a new one. There can be two case
Case 1. If you want to change the initial view controller on the check of if Auth.auth().currentUser == nil or iAuth.auth().currentUser != nil then you can simply write the code in didFinishLaunchingWithOptions in AppDelegate and make sure you must give the identifier in storyboard and use the same identifier in the code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let mainView = UIStoryboard(name: "MainStoryboard", bundle: nil)
if Auth.auth().currentUser != nil {
let viewcontroller : MainViewController = mainView.instantiateViewController(withIdentifier: "MainViewIdentifier") as! MainViewController
self.window!.rootViewController = viewcontroller
self.window?.makeKeyAndVisible();
} else {
let viewcontroller : LoginViewController = mainView.instantiateViewController(withIdentifier: "loginViewIdentifier") as! LoginViewController
self.window!.rootViewController = viewcontroller
self.window?.makeKeyAndVisible();
}
return true
}
Case 2. Suppose you have Main/Home/Dash VC (View controller) and it’s always is the initial view controller then there you have implemented the check if Auth.auth().currentUser == nil then present/push the Login view controller else not.
You are Direct Creating New Instance of ViewController
Try the following code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if Auth.auth().currentUser != nil {
var mainView: UIStoryboard!
mainView = UIStoryboard(name: "MainStoryboard", bundle: nil)
let viewcontroller : HomeController = mainView.instantiateViewController(withIdentifier: "someViewController") as! HomeController
self.window!.rootViewController = viewcontroller
self.window?.makeKeyAndVisible();
} else {
var mainView: UIStoryboard!
mainView = UIStoryboard(name: "MainStoryboard", bundle: nil)
let viewcontroller : LoginController = mainView.instantiateViewController(withIdentifier: "loginVCIdentifier") as! LoginController
self.window!.rootViewController = viewcontroller
self.window?.makeKeyAndVisible();
}
return true
}
Make Sure you have given identifier to controller from storyboard

Changed from Navigation to TabBar, CoreData does not load

I changed my Navigation Controller to Tab Bar Controller, then I wanted to compile the app. But it does not load my managedContext anymore.
This is my launching code when I load the app:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
guard let navController = window?.rootViewController as? UINavigationController,
let viewController = navController.topViewController as? ViewController else {
return true
}
viewController.managedContext = coreDataStack.managedContext
// Override point for customization after application launch.
return true
}
Therefore I tried to edit the code like this:
Edit:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
//let controller = storyboard.instantiateViewController(withIdentifier: "TabBarVC")
self.window?.rootViewController = controller
guard let tabController = window?.rootViewController as? UITabBarController,
let navController = tabController.viewControllers![0] as? UINavigationController,
let viewController = navController.topViewController as? ViewController else {
return true
}
// Version that works for UINavigationCOntroller
// guard let navController = window?.rootViewController as? UINavigationController,
// let viewController = navController.topViewController as? ViewController else {
// return true
// }
viewController.managedContext = coreDataStack.managedContext
// Override point for customization after application launch.
return true
}
I changed the code, but I still can not load managedContext, and it returns nil when I want to use it in ViewController, I also set the initial Viewcontroller to the tabBarController.
Set rootviewcontroller for your window first and then right your logic afterwards.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(<StoryboardName>, bundle: nil)
let controller = storyboard.initializeInitialViewController()
window.rootViewController = controller
guard let navController = window?.rootViewController as? UITabBarController,
let viewController = navController.moreNavigationController as? ViewController else {
return true
}
viewController.managedContext = coreDataStack.managedContext
// Override point for customization after application launch.
return