0

Good day everyone,

I have root view controller set up as my HomeViewController, in this project i am using token based authentication ( which i am storing in user defaults ) and i am using token for all my API calls.

I have a check in my viewWillAppear method to check if there is access token present and then i make the api call in viewDidAppear to populate the collection view, and this works perfectly fine at all times except the first time.

If I log in for the first time it hits the viewWillAppear, viewDidAppear and then login screen pops up and once i authenticate the user and save it in the UserDefaults, dismiss the login screen and in the HomeViewController all i get is a spinner ( which means that viewDidAppear is also been called ) but if i close the app and open it again it all works fine.

What can i change in my code to make it work in the first time please and thank you!!

class HomeViewController: UIViewController {
        
    // MARK: - Properties
        
    let refreshControl = UIRefreshControl()            
    var publishedReportList: [ReportListDetail] = []
    
    private let reportsCollectionView: UICollectionView = {
        let viewLayout = UICollectionViewFlowLayout()
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: viewLayout)
        collectionView.register(ReportsCollectionViewCell.self, forCellWithReuseIdentifier: ReportsCollectionViewCell.identifier)
        collectionView.backgroundColor = .systemBackground
        return collectionView
    }()
    
    // MARK: - Initialisation
    override func viewDidLoad() {
        super.viewDidLoad()
                
        reportsCollectionView.delegate = self
        reportsCollectionView.dataSource = self

        print(publishedReportList.count)
                
        refreshControl.tintColor = .blue
        refreshControl.addTarget(self, action: #selector(pullToRefresh), for: .valueChanged)
        reportsCollectionView.addSubview(refreshControl)
        reportsCollectionView.alwaysBounceVertical = true
    }
    
override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)        
        // check auth status
        handleNotAuthenticated()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        // call for reports
        getReportUserLayout()
    }
    
    // MARK: - Handlers
    
    @objc func pullToRefresh() {
       // Code to refresh table view
        getReportUserLayout()
    }
    
    fileprivate func getReportUserLayout() {
//        publishedReportList.removeAll()
        whySuchEmptyLabel.isHidden = true
        spinner.show(in: view)
        spinner.textLabel.text = "Loading Reports.."
        DispatchQueue.main.async {
            ReportsManager.shared.getReportData { [weak self] (listOfReports) in
                
                guard let strongSelf = self else { return }
                strongSelf.publishedReportList = listOfReports
                if listOfReports.count == 0 {
                    strongSelf.whySuchEmptyLabel.isHidden = false
                }
                strongSelf.reportsCollectionView.reloadData()
                strongSelf.spinner.dismiss()
                strongSelf.refreshControl.endRefreshing()
            }
        }
    }
    
    private func handleNotAuthenticated() {
        
        if UserDefaults.standard.string(forKey: "accessToken") == nil {
            // show login view controller
            let loginVC = LoginViewController()
            loginVC.modalPresentationStyle = .overCurrentContext
            present(loginVC, animated: false)
        }
    }
}
nitpaxy
  • 67
  • 10
  • 1 - check for the token in `AppDelegate` 2 - according to that set your root controller (home or login) 3 - possibly duplicate of [this](https://stackoverflow.com/q/19962276/10279508) – Bhooshan patil May 01 '21 at 02:34

1 Answers1

0

You are in the HomeViewController and presenting loginVC, so it will not trigger viewDidAppear or viewWillAppear because it is not disappeared from the app. You have to use closure or delegate or notification to communicate back to the HomeViewController. You can also use the Combine framework and save the state. Here is an example of using delegate.

// Add protocol
protocol  ViewControllerDelegate {
    func loggedIn()
}
class HomeViewController: UIViewController, ViewControllerDelegate {
    private func handleNotAuthenticated() {
        if UserDefaults.standard.string(forKey: "accessToken") == nil {
            let loginVC = LoginViewController()
            loginVC.modalPresentationStyle = .overCurrentContext
            loginVC.viewDelegate = self
            present(loginVC, animated: false)
        }
    }
}
    

class LoginViewController: UIViewController {
    var viewDelegate: ViewControllerDelegate? = nil
    
    func userLoggedIn() {
        self.viewDelegate?.loggedIn()
    }
}
achu
  • 329
  • 3
  • 7