LoginSignup
12
8

More than 5 years have passed since last update.

ViewControllerのinit処理ができなかった昔の僕へ

Posted at

ViewControllerのinit処理みなさんどうしていますか?
僕はだいぶイケテナイ呼び出しをしていたので、ちょっとまとめてみました。

1.viewControllerの呼び出し

ViewControllerって当たり前だけど呼び出したいですよね。
例えばユーザー画面とか作る時、こんな書き方をしてみました。

        let viewController = UserViewController()
        viewController.userId = userId
        self.navigationController?.pushViewController(viewController, animated: true)
class UserViewController: UIViewController {
    var userId:Int?
      override func viewDidLoad() {
        super.viewDidLoad()
        //userを呼ぶAPIをかく
      }

}

これでも動くは動くんですよ。

2.動くならいいじゃん何がダメなの?

例えば他でもユーザー画面に遷移したい!!って思った時

        let viewController = UserViewController()
        //viewController.userId = userId
        self.navigationController?.pushViewController(viewController, animated: true)

これでもビルド通るんですよね。そうすると...

class UserViewController: UIViewController {
    var userId:Int?
      override func viewDidLoad() {
        super.viewDidLoad()
        // userを呼ぶAPIをかく
        // user呼べないよおおおおおおおお! 
      }

}

ってなって初期表示の画面になっちゃうんですよね。
こんな感じで呼び出し方によって変わっちゃう動きはイケテナイ。

UserViewController呼ぶときは必須にしたいよねえ!

3.ViewControllerのinit書こうね

普通にinit処理書くこともできますが、便利なライブラリがあるので、それに頼ります。
https://github.com/tarunon/Instantiate

これを使って書くとこうなります

        // 初期化時に必ずuserIdが必要なように書く
        let viewController = UserViewController.instantiate(with: .init(userId:userId))
        self.navigationController?.pushViewController(viewController, animated: true)

import Instantiate
import InstantiateStandard

class UserViewController: UIViewController, StoryboardInstantiatable {

    //ここは初期化時の処理を書く
    func inject(_ dependency: UserViewController.Dependency) {
        self.userId = dependency.userId
    }


    //ここに必要な変数を書く
    struct Dependency {
        var userId:Int
    }

    var userId:Int!

    override func viewDidLoad() {
      super.viewDidLoad()
      //userを呼ぶAPIをかく
      //ここでは必ずuserIdが取れる!!!
    }

}

このように書くことで
UserViewControllerを呼び出すときは必ずuserIdが必要なんだ!
とコード上で力強く宣言できます

4.まとめ

ViewControllerのinit処理を正しく入れると、ViewControllerの使い回しが大変楽になります。
呼び出し側に負担を求めるViewControllerを書くのはやめましょう。(自戒をこめて...)
ちなみに他にもCellやUIViewなどもほぼ同じ方法で、init処理書けます。
ライブラリを作っていただいた人に感謝。

12
8
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
12
8