0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

uitabbarcontroller reload after login with FirebaseAuth

0
Last updated at Posted at 2021-01-09

追記。書きましたがログイン済みユーザーの場合、Observe(Listen)が2回走ってしまう(ViewControllerのviewDidLoadが2回呼ばれるため)のでおかしくなりますし、やはりListenはviewWillAppearでやるのが正しいみたいです。
https://firebase.googleblog.com/2015/10/best-practices-for-ios-uiviewcontroller_6.html

ただタブ遷移で毎回Listenとremoveを繰り返してしまいますので、これを辞めたい場合は別の方法で回避する必要がありそうです。

一応しばらく残して置きますが、後ほど消すか書き直します。

前提

タブバーのあるアプリでFirebaseAuthを使ったログインを実装。Initial View をMyTabBarControllerにしている。ホームとしてMyTabBarControllerの最初のViewをViewControllerにしている。

もしユーザー認証されていなかったら、LoginView/SignUpViewをPresentModallyで開いて、ログイン完了したらdissmissで閉じる仕様(その方がログイン済みユーザーにとっては余計なparentや処理がないかなと思って)。

viewのライフサイクルのおさらい

https___qiita-image-store.s3.amazonaws.com_0_326574_354ea62b-ca5a-1136-4524-de841e7d7b89.png

ログイン後にホームのcollectionViewが更新されない

Initial View にしているMyTabBarControllerと、その子のViewControllerのviewDidLoad, viewDidAppearは最初に呼ばれる。ログイン後にdissmissしても、子であるViewControllerのviewDidLoadやviewWillAppear, viewDidAppearは呼ばれない。そこでログインしたらMyTabBarControllerか、その子をリロード(初期化)してやる必要があった。

解決方法

dismiss後のMyTabBarControllerのviewDidAppearにて最初の子供だけリロードしてやった。

override func viewDidAppear(_ animated: Bool) {
		super.viewDidAppear(animated)
		guard let _ = Auth.auth().currentUser else {
			self.presentWelcomeView()
			return
		}
		self.viewControllers?.first?.loadView()
		self.viewControllers?.first?.viewDidLoad()
	}

全体のコード

MyTabBarController.swift
import UIKit
import FirebaseAuth

class MyTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
	
    override func viewDidAppear(_ animated: Bool) {
		super.viewDidAppear(animated)
		guard let _ = Auth.auth().currentUser else {
			self.presentWelcomeView() // ここで呼ばないと whose view is not in the window hierarchy! のエラーが出て怒られる(viewDidLoadではViewはロードされただけで生成はされてないかららしい)
			return
		}
//		self.setViewControllers(self.viewControllers, animated: true) //これではダメ
		self.viewControllers?.first?.loadView()
		self.viewControllers?.first?.viewDidLoad()
    }

    func presentWelcomeView() {
		guard let controller = storyboard?.instantiateViewController(identifier: "WelcomeNavigation") else { return }
		controller.modalPresentationStyle = .fullScreen
		self.present(controller, animated: true, completion: nil)
	}
}
ViewController.swift
import UIKit
import FirebaseAuth
import FirebaseFirestore

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    
    var posts: [Post] = []
    
    var user: User!
    let db = Firestore.firestore()
    var userRef: DocumentReference? = nil
	var listener: ListenerRegistration?
                
    override func viewDidLoad() {
        super.viewDidLoad()
		guard let user = Auth.auth().currentUser else {
			return
		}
		self.user = user
		self.userRef = db.collection("users").document(self.user.uid)
        startObservingDatabase() // 省略:addSnapshotListenerによるリッスン処理
        self.collectionView.delegate = self
        self.collectionView.dataSource = self
    }
		    
	override func viewWillAppear(_ animated: Bool) {
		super.viewWillAppear(animated)
                // 公式ではここでAuth.auth().currentUserを読んでいる
                // しかしここはタブを押すたびに呼ばれるので毎回collectionViewが最新に更新されて本意ではない
	}
	
	override func viewWillDisappear(_ animated: Bool) {
		super.viewWillDisappear(animated)
		self.listener?.remove()
	}
}

LoginViewController.swift
import UIKit
import FirebaseAuth

class LoginViewController: UIViewController {

    func signIn() {
		//if let tabvc = self.navigationController?.parent as? UITabBarController { // ここがそもそもnilでダメ
		//	tabvc.viewControllers?.first?.loadView()
		//	tabvc.viewControllers?.first?.viewDidLoad()
		//}
		self.navigationController?.dismiss(animated: true, completion: nil) // 今回はたまたま親にNavigationControllerを持たせていたので、ないならself.dismissでもOKなはず
    }
}

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?