Changed from Navigation to TabBar, CoreData does not load - swift

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

Related

How to navigate to a UIViewController programmatically?

I am having difficulties navigating to a UIViewController programmatically from within another UIViewController. I am using UIKit and Swift 5.
I have tried to follow this Medium article but can't get it to work for me.
In my AppDelegate file I have changed the didFinishLaunchingWithOptions function to this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = LoginViewController()
self.window?.makeKeyAndVisible()
return true
}
And then in my LoginViewController() I attempt to navigate to my DashboardViewController by doing the following:
override func viewDidLoad() {
super.viewDidLoad();
// present a modal with an embed UINavigationController
let rvc = DashboardViewController()
let vc = UINavigationController(rootViewController: rvc)
vc.modalPresentationStyle = .overFullScreen
present(vc, animated: true, completion: nil)
}
But DashboardViewController is never called.
What am I doing wrong and how can I change the code to work?
Thank you.
Try this in your viewDidLoad method:
let rvc = self.storyboard!.instantiateViewControllerWithIdentifier("DashboardViewController") as! DashboardViewControllerSwift
let navController = UINavigationController(rootViewController: rvc)
navController.modalPresentationStyle = .overFullScreen
self.present(navController, animated:true, completion: nil)
Change DashboardViewControllerSwift to the name of your Swift file for your DashboardViewController, without the .swift bit. Make sure it is set as the class for DashboardViewController object in IB/Storyboard.
Also ensure the DashboardViewController object in IB/Storyboard has its Storyboard Identifier set as DashboardViewController.
1- start with SceneDelegate
self.window = UIWindow(windowScene: windowScene)
let navigation = UINavigationController()
window.rootViewController = navigation
window?.makeKeyAndVisible()
2-then
let rvc = DashboardViewController()
self.navigationController?.pushViewController(rvc, animated: true)
3- try it in viewDidLoad() if not work try it in viewWillAppear
I ended up coming across a Youtube video that helped me solve my issue.
AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let login = LoginViewController()
let navigationController = UINavigationController(rootViewController: login)
navigationController.setNavigationBarHidden(true, animated: true)
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
LoginViewController
let dashboard = DashboardViewController()
self.navigationController?.pushViewController(dashboard, animated: true)

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

UINavigationBar not showing

I have a swift project that is programmatic and segues from a mapview to another view. After the segue the navigation bar is not present. Since the files were copied over from an earlier project where this doesn't happen I'm perplexed. It should be very straight forward.
In AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
let homeViewController = MapViewController()
self.navigationController = UINavigationController()
self.navigationController?.setNavigationBarHidden(false, animated: false)
navigationController?.viewControllers = [homeViewController]
self.window!.rootViewController = navigationController
self.window?.makeKeyAndVisible()
let attributes = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 17)!]
UINavigationBar.appearance().titleTextAttributes = attributes
return true
}
And the segue code called in the MapViewController:
let storeViewController = ViewController()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.navigationController?.setNavigationBarHidden(false, animated: false)
appDelegate.navigationController?.pushViewController(storeViewController, animated: true)
You have to embedded MapViewController in UINavigationController and Push ViewControllers as needed
to hide use self.navigationController?.isNavigationBarHidden = false
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
let homeViewController = MapViewController()
let navController = UINavigationController(rootViewController: homeViewController)
self.window!.rootViewController = navController
self.window?.makeKeyAndVisible()
let attributes = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Light", size: 17)!]
UINavigationBar.appearance().titleTextAttributes = attributes
return true
}
and in MapViewController
To navigate:
let storeViewController = ViewController()
self.navigationController?.pushViewController(storeViewController, animated: true)
//if you want to hide or show navigation
//self.navigationController?.isNavigationBarHidden = false // 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