Could not cast value of view controllers error - ios

My app was building fine until today when all of a sudden I got the following errors after a successful build:
Could not cast value of type 'FirebaseApp.HomeViewController' (0x101ab6aa0) to 'FirebaseApp.MenuViewController' (0x101ab6d30).
Could not cast value of type 'FirebaseApp.HomeViewController' (0x101ab6aa0) to 'FirebaseApp.MenuViewController' (0x101ab6d30).
The line in my app delegate
let controller = storyboard.instantiateViewController(withIdentifier:
"mainView") as! MenuViewController
was then highlighted red within this AppDelegate Class:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
// Override point for customization after application launch.
let authListener = Auth.auth().addStateDidChangeListener { auth, user in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if user != nil {
//
let controller = storyboard.instantiateViewController(withIdentifier: "MainTabBarController") as! UITabBarController
self.window?.rootViewController = controller
self.window?.makeKeyAndVisible()
} else {
// main screen
let controller = storyboard.instantiateViewController(withIdentifier: "mainView") as! MenuViewController
self.window?.rootViewController = controller
self.window?.makeKeyAndVisible()
}
}
return true
}
I have in my storyboard the mainView identified:
And I have a HomeViewController
class HomeViewController:UIViewController, UITableViewDelegate, UITableViewDataSource {
which has the bulk of my code.
I am not sure what went wrong here, but I suspect it has something to do with misnaming in my story board.
Edit: I solved this problem by changing "mainView" to "MenuViewController"

In the storyboard for MenuViewController you need to set mainView as Storyboard ID not the Restoration ID.
Like below image:

Related

setting initial viewcontroller in swift [duplicate]

This question already has an answer here:
Xcode 11 & iOS13, using UIKIT can't change background colour of UIViewController
(1 answer)
Closed 3 years ago.
im trying to set the initial view controller if a user has a token in his keychain.
when I try to set it in the appDelegate like this
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let accessToken: String? = KeychainWrapper.standard.string(forKey: "accessToken")
if accessToken != nil
{
// Take user to a home page
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homePage = mainStoryboard.instantiateViewController(withIdentifier: "home") as! ViewLoader
self.window.rootViewController = homePage
}
return true
}
but I get som errors saying "Value of type 'AppDelegate' has no member 'window'"
it tried to clean the project but without luck
Try this:
window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homePage = mainStoryboard.instantiateViewController(withIdentifier: "home") as! ViewLoader
window?.rootViewController = homePage
window?.makeKeyAndVisible()
Init window first and add the function makeKeyAndVisible.
The reason of your error is you do not declare a variable window.
Adding following code in your AppDelegate class is a solution for error:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homePage = mainStoryboard.instantiateViewController(withIdentifier: "home")
self.window?.rootViewController = homePage
self.window?.makeKeyAndVisible()
return true
}
// ..... more code ...
}

using Third Party Slider and couldn't navigate to another view

i am currently using KYDrawerController for a slider menu and I couldn't navigate to another page. Whenever I press a button (even without codes in it), it crashes. Another is i tried to set another view as initial view, it doesnt shows that. I am suspecting it's something to do with my appDelegate file. I need some troubleshooting help around if possible. I changed my AppDelegate file to
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var drawerController = KYDrawerController.init(drawerDirection: .left, drawerWidth: 300)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let mainVC = storyboard.instantiateViewController(withIdentifier: "MainMenu")
let menuVC = storyboard.instantiateViewController(withIdentifier: "drawer")
self.drawerController.mainViewController = mainVC
self.drawerController.drawerViewController = menuVC
self.window?.rootViewController = self.drawerController
self.window?.makeKeyAndVisible()
// Override point for customization after application launch.
return true
}
anything here might have been the problem?
Your are missing to embed your view controller in navigationController. Please update your code for mainVC as follows and try again.
let mainVC = storyboard.instantiateViewController(withIdentifier: "MainMenu")
let mainViewNavigationController = UINavigationController(rootViewController: mainVC)
self.drawerController.mainViewController = mainViewNavigationController
I hope this will fix your issue. Let me know if still facing any issue.

Access a UIViewCotroller in AppDelegate in Swift

I want to access a UIViewcontroller in AppDelegate. The hierarchy is shown here:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navController = self.window!.rootViewController as! UINavigationController
let tabController = navController.topViewController as! UITabBarController
var postController = tabController.topViewController as! UITableViewController
// It is incorrect. has no member of topViewController
return true
}
Have you tried something like:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navController = self.window!.rootViewController as! UINavigationController
let tabController = navController.topViewController as! UITabBarController
var postController = tabController.viewControllers[0]
// It is incorrect. has no member of topViewController
return true
}
Tab bar controller manages a list of ViewControllers. In this case you want the first one in the list. Note the syntax might be a bit wrong as I don't have much swift experience!
var postController = tabController.viewControllers[0]
That is the part I cahanged.
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
}
The problem is that you shouldn't have to access you controller from AppDelegate, it's a mistake in your app's architecture.
AppDelegate should only be used for app's lifecycle (launch/activation/deactivation/push notifications/...)
Why would you like to access your viewController here ?
you already did your forwarding with the storyboard,
all you have to do is:
func applicationDidFinishLaunching(_ application: UIApplication) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navigationController") // here you should insert your identifier (storyboard -> navigationcontroller -> Identity -> Storyboard ID)
window!.rootViewController = navigationController
window!.makeKeyAndVisible()
}
You can use storyboard identifier to access the view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "storyboardIdentifier")

How to Pass Values from Separate Classes to AppDelegate?

I have a class in my SignInViewController.swift:
class CredentialState: NSObject {
static let sharedInstance = CredentialState()
var signedIn = false
var displayName: String?
var photoUrl: NSURL?
}
I would like to use the variable signedIn to authenticate users in AppDelegate with an if-else statement. Currently, I have a way to set the viewcontroller to CustomTabBarController (custom programmatically made) or SignInViewController (storyboard made). The if statement would basically say if the value is false set the controller to the sign in screen and if it's true then go to the tab bar screen.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.makeKeyAndVisible()
// Main view controller is inside of customtabbarcontroller, which gives a tab overlay
// window?.rootViewController = CustomTabBarController()
// Sets the main view to a storyboard element, such as SignInVC
let storyboard = UIStoryboard(name: "SignIn", bundle: nil)
let loginVC = storyboard.instantiateViewControllerWithIdentifier("SignInVC") as! SignInViewController
self.window?.rootViewController = loginVC
return true
}
if i understood you correctly:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.mainScreen().bounds)
// check login state
if CredentialState.sharedInstance.signedIn {
// Main view controller is inside of customtabbarcontroller, which gives a tab overlay
window?.rootViewController = CustomTabBarController()
} else {
// Sets the main view to a storyboard element, such as SignInVC
let storyboard = UIStoryboard(name: "SignIn", bundle: nil)
let loginVC = storyboard.instantiateViewControllerWithIdentifier("SignInVC") as! SignInViewController
window?.rootViewController = loginVC
}
window?.makeKeyAndVisible()
return true
}
I am not so sure of what you are asking, yet I'll try to answer that. Basically what you need to do is just simply have this piece of code above your CredentialState class:
credentialState : CredentialState = CredentialState()
In this way you can change or check your signedIn variable from AppDelegate. So simply in the AppDelegate file you can:
if(credentialState.signedIn == true) ...
Hope I was able to answer your question

iOS Swift SlideMenuControllerSwift

I am learning to develop iOS and come across to this awesome library SlideMenuController. I am able to make use of this library to create awesome slide menu easily.
However, there are some problem that I am facing during implementing with this library.
Environment
In my project storyboard, I have 1 TabBarViewController and 2 ViewController which is under this TabBarViewController. I also have 2 independent ViewController which are LoginViewController and LeftMenuViewController.
I have below code in my AppDelegate.swift file
...
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController = storyboard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
let leftViewController = storyboard.instantiateViewControllerWithIdentifier("LeftMenuViewController") as! LeftMenuViewController
let slideMenuController = SlideMenuController(mainViewController: mainViewController, leftMenuViewController: leftViewController)
SlideMenuOptions.contentViewScale = 1
SlideMenuOptions.hideStatusBar = false;
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
return true
}
...
Everything work perfectly if I don't need my login view as a initial view. I notice that this line of code self.window?.rootViewController = slideMenuController will always make sure that view in mainViewController to be the initial view when the app open.
How can I have my LoginView as the initial view when my app start up and the slide menu is still bind to the TabBarViewController and working properly?
I have try to move the code from AppDelegate.swift to viewDidLoad() function in TabBarViewController.swift but no luck. It is not working.
Need some guilds and help on this. Thanks.
you can use this code instead of yours :
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController = storyboard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
let leftViewController = storyboard.instantiateViewControllerWithIdentifier("LeftMenuViewController") as! LeftMenuViewController
let loginViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as! LoginViewController
let nvc: UINavigationController = UINavigationController(rootViewController: loginViewController)
leftViewController.mainVC = nvc
let slideMenuController = SlideMenuController(mainViewController: nvc, leftMenuViewController: leftViewController)
SlideMenuOptions.contentViewScale = 1
SlideMenuOptions.hideStatusBar = false;
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
return true
}
dont forget to add this variable in your LeftMenuViewController
var mainVC : UIViewController!

Resources