1

My app has the following layout/flow:

enter image description here

LandingVC: The page a new user will see when first runs the app. This page will explain what the app is for and has 2 buttons: Login and Register

LoginVC: Where the user will use his/her email and password to log in

RegisterVC: Where the user will use his/her email and password to register

MainVC: A tab bar view controller where the user will be redirected if:

  • user registers successfully for the first time
  • user logs in successfully
  • user is logged in

If the user is not logged in he/she should be redirected to LandingVC.

The way I am handling it is as follows:

In appDelegate.swift I check whether the user is logged in or not.

enter image description here

If the user is logged in I set the MainVC as the root controller.

If the user is not logged in, then i set the LandingVC as the root controller.

QUESTION A: Everything work just fine but since I am fairly new to iOS development I worry if the way I present/push/dismiss ViewControllers is the correct one in terms of memory consumption and code efficiency. What do you think? Do I get it all wrong or am I in the right path?

To measure it I followed the procedure below:

Run the app in iOS Simulator using iPhone X. The user is initially not logged in so I used the same flow 3 times: LandingVC --> LoginVC --> MainVC.

The results below:

enter image description here

ps1: to get the results I used the "Debug Navigator" tab in xCode.

enter image description here

To verify that no ViewController was dismissed during the whole flow I used the "View Memory Graph Hierarchy":

enter image description here

As you can see we have 3 instances of every ViewController I navigated through (by the way, MainVC is the MainTabBarController which is consisted of HomeViewController, FavouritesViewController, TrendingViewController, and SettingsViewController).

QUESTION B: Is there a way I can deallocate [remove/pop/dismiss/etc] ViewControllers from memory but still have the same result?

QUESTION C: Is it normal for the memory to increase from 55.4 MB to 68.1 MB following that flow?

ps2: All UI was built programmatically. No Storyboard involved.

Thanks in advance and sorry for the long post.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
christostsang
  • 1,701
  • 3
  • 27
  • 46
  • When you `present` a viewcontroller, do you always `dismiss` it as well? Replacing the `rootViewController` while still presenting a viewcontroller will lead to the presented one still remaining in the view hierarchy somewhere. You may try inspecting the view hierarchy using the button looking like three rectangles above the debugger window in Xcode. – idrougge Jun 14 '18 at 15:04
  • No, I only dismiss the view controller when I move away from ForgotPasswordVC and back to LoginVC. As for the rest, I am using "present" 3 more times: 1 to go from LoginVC to MainVC, 1 to go from RegisterVC to MainVC and 1 to go from MainVC to LandingVC when user logs out. I think i cannot use dismiss() in neither cases. But then again maybe I am wrong. Regarding rootViewController, it is set before any viewController is presented (this is the reason I placed the code inside didFinishLaunchingWithOptions in appDelegate.swift). How would you approach this flow if someone asked you to build it? – christostsang Jun 14 '18 at 20:49
  • `present` method is modal, which means that any modally presented VC must also be dismissed at some point, or the entire view stack beneath the presented VC will be kept. – idrougge Jun 17 '18 at 15:52
  • I made some changes that help to mitigate the issue. First of all i am setting the MainVC as a rootViewController. Then I am deciding inside the MainVC whether the user is logged in or not. If not logged in, then I am presenting the LandingVC. From LandingVC I am pushing the LoginVC. If the credentials are correct then I dismiss() and the MainVC is in front again. The only issue with this approach is that the LoginVC stays in the memory since is pushed but never popped. Is there a way to pop LoginVC while dismissing all modally presented VCs? – christostsang Jun 18 '18 at 14:55
  • https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621855-poptorootviewcontroller – idrougge Jun 18 '18 at 15:01
  • As soon as the user authenticates the credentials, if I use popToRootViewController(animated:) will only remove LoginVC and show the LandingVC, which is not the rootViewController. I want to show MainVC. I can do that if I use dismiss(). This will show the MainVC but the LoginVC will stay in the memory [while popToRootViewController will remove LoginVC from the memory]. What i want is a combination: As soon as the user is authenticated to go to MainVC and remove any viewController from memory. – christostsang Jun 22 '18 at 12:05
  • You will need to use `pop` to remove any viewcontroller that has been `push`ed, and `dismiss` to remove any viewcontroller that has been `present`ed. – idrougge Jun 23 '18 at 23:02
  • Thank you for all your answers. As it turns out the problem was not related to view controller presentation, but rather to retain cycle. You can check my question and answer here https://stackoverflow.com/questions/51051838/swift-presenting-modally-and-dismissing-a-navigation-controller/51078752#51078752 if you are interested! Thanks again! – christostsang Jun 28 '18 at 09:03

0 Answers0