2

I'm getting a Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeedaec488) at the array for tabBar.viewControllers = [cameraVC, galleryVC] and in my console I'm getting my username endlessly printed out, which comes from a different class. The first code snippet shows where the thread was shown:

func addTabBar() {
    let cameraVC = HomeViewController()
    let galleryVC = GalleryViewController()

    let tabBarItem1 = UITabBarItem(title: "Camera", image: UIImage(named: "camera-icon")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal), selectedImage: UIImage(named: "blueCamera-icon")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal))
    let tabBarItem2 = UITabBarItem(title: "Gallery", image: UIImage(named: "gallery-icon")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal), selectedImage: UIImage(named: "blueGallery-icon")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal))



    cameraVC.tabBarItem = tabBarItem1
    galleryVC.tabBarItem = tabBarItem2
    tabBarItem2.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: -6, right: 0)

    tabBar.viewControllers = [cameraVC, galleryVC]

    self.view.addSubview(tabBar.view)
}

This is my second code snippet with all the functions defined where I'm getting my print statement for the username endlessly repeated in the console:

@IBAction func signUpTapped(_ sender: Any) {
    //validate the fields
    let error = validateFields()
    
    if error != nil {
        //something's wrong, show error message
        showError(error!)
    }
    else {
        
        //create trimmed data
        let userName = userNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        let email = emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        let password = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        //create the user
        Auth.auth().createUser(withEmail: email, password: password) { (result,err) in
            
            //check for errors
            if err != nil {
                //error creating user
                self.showError(err?.localizedDescription ?? "Error creating user")
            }
            else {
                    let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
                    changeRequest?.displayName = userName
                    print(userName)
                changeRequest?.commitChanges { (error) in print ("Username not created") }

                //transition to home screen
                self.saveLoggedState()
                self.transitionHome()
            }
        }
    }
}
func showError(_ message:String){
    
    errorLabel.text = message
    errorLabel.alpha = 1
}
func saveLoggedState() {
    
    let def = UserDefaults.standard
    def.set(true, forKey: "is_authenticated")
    def.synchronize()
    
}
func transitionHome() {
    
    let homeVC = self.storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
    self.view.window?.rootViewController = UINavigationController(rootViewController: homeVC!)
    self.view.window?.makeKeyAndVisible()
    
}

I hope that's enough code! I'm really confused about what the problem is and previous stack overflow posts haven't been helpful. Any assistance would be much appreciated. Thanks!

Edit 1: I'm also implementing a side menu in my home controller. The code for it looks like this:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.backgroundColor = color
    view.backgroundColor = color
    tableView.tableFooterView = UIView()
}

// Table
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return menuItems.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = menuItems[indexPath.row].rawValue
    cell.textLabel?.textColor = .white
    cell.backgroundColor = color
    cell.contentView.backgroundColor = color
    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    // Relay to delegate about menu item selection
    let selectedItem = menuItems[indexPath.row]
    delegate?.didSelectMenuItem(named: selectedItem)
}
Gryffin
  • 99
  • 1
  • 8

2 Answers2

1
func addTabBar() {
   let cameraVC = HomeViewController()
   let galleryVC = GalleryViewController()
}

I guess it's a typo, you create HomeViewController inside a HomeViewController, which causes an infinite loop, and I think your Auth is called inside viewViewAppear/didLoad, so it triggers endlessly until you Stack overflow.

If that's not the case, I guess your HomeViewController triggers signUpTapped, and then on user creation it goes back to HomeViewController (which triggers signUpTapped again), so a recursion without an end.

Vitalii Shvetsov
  • 404
  • 2
  • 11
  • Hi Vitalii, I originally created a different view controller for my cameraVC, but I also have a side menu to navigate to different view controllers. When I create a new view controller, my side menu wasn't working. Is there a way to still include the homeVC or is that impossible? Do I have to create a new view controller? Thanks! – Gryffin Aug 24 '20 at 21:28
  • You have to remove recursive calls from the code, look at this example: - You have a HomeViewController (main screen), inside of it you have 2 tabs (CameraVC, GalleryVC). But the problems comes when you try to create HomeVC as a tab inside HomeVC, then the second HomeVC would create another HomeVC tab, so an infinite loop. You can include homeVC, but you have to stop creating them at some point – Vitalii Shvetsov Aug 24 '20 at 21:41
  • I see now, but how would I be able to stop creating them? Sorry about all the questions! The answers may seem fairly obvious, but I'm a newbie at Swift and I don't know much about how to end recursion. Thank you! – Gryffin Aug 24 '20 at 21:57
  • In your example I don't think you ever need to embed HomeViewController as a Tab, because it will have another tabs inside of it and it will look ugly. If you need a third tab - just add a third different tab with content that you need. HomeViewController should only have UITabViewController (basically be a box for your tabs) – Vitalii Shvetsov Aug 24 '20 at 22:05
  • So it should be like this HomeViewController contains GalleryVC + CameraVC + AdditionalDataVC And this way by transitionHome you shouldn't create additional HomeViewController, because you will call it from HomeViewController already – Vitalii Shvetsov Aug 24 '20 at 22:07
  • Ahhh, I think I got it now. So, just to confirm, my HomeViewController will be an 'empty view controller' with just a tab view controller with other view controllers attached. Should I still keep the transitionHome function because it's going to a tabBar controller? And would I still do the same for my side menu even though other view controllers will be displayed? For reference, I will attach the code for side menu in my post – Gryffin Aug 24 '20 at 22:53
  • If you have UiViewControllers other than HomeViewController, and if you call your Auth method outside HomeViewController, then yes you should still transition to it. For side menu look at this example, I have UITabBarController (HomeVC in my app), and MenuVC, which I create and transition to every time the app is called. You just basically have to insert that into view hierarchy, whether it is with UINavigationController or addSubview https://gist.github.com/sanstorik/ba3bc32adb3272a67260f02f57fc5772 – Vitalii Shvetsov Aug 25 '20 at 07:47
0

In my case, I overrode the loadView method but forgot to add super.loadView()

Liang
  • 59
  • 1
  • 4