LoginSignup
0
1

More than 1 year has passed since last update.

Genericsパラメータを持つUIViewController/UIViewのStoryboardName/nibNameをいい感じに取得する

Posted at

背景

StoryboardやXibをコードから呼び出す場合、その名前を文字列で指定する必要があります
文字列をベタ書きで指定するのは以下のデメリットがあります

  • タイポする可能性が高まる
    • タイポに気づけなければ無駄に時間を使ってしまう
  • クラス名の更新時に呼び出しの文字列を変更し忘れて、StoryboardやXibが読み込めなくなる
    • 読み込めなくなっていることをコンパイル時に気づけないので最悪そのままリリースしてバグになる

その対策として以下のようなExtensionを活用している方も多いと思います(私もその一人です)

extension NSObject {
    static var className: String {
        String(describing: self)
    }

    var className: String {
        Self.className
    }
}

参考: https://qiita.com/tattn/items/bdce2a589912b489cceb

この解決方法の課題

XibやStoryboardが紐付いているUIViewController/UIViewにGenericsパラメータがついている場合、正しく読み込めません
理由は、Genericsパラメータまでが className に含まれてしまうため、StoryboardNameやnibNameとずれてしまうからです

class HogeViewController<T>: UIViewController {}

print(HogeViewController<String>.className)
// HogeViewController<String>
// 本当は HogeViewController の部分だけがほしい

解決方法

Genericsパラメータの手前までをnibNameとして切り出します
※サンプルはUIViewControllerだけですが、UIViewも同様のExtensionを生やせばOKです

extension UIViewController {
    static var nibName: String {
        let startIndex = className.startIndex
        let endIndex = className.firstIndex(of: "<") ?? className.endIndex
        return String(className[startIndex ..< endIndex])
    }
}

上記ロジックはクラス名に < が含まれていると意図しないところでnibName切れてしまいますが
私が試行錯誤した限りは < をGenericsパラメータ以外の中途半端な位置に入れるとコンパイルエラーがでるので大丈夫だと思います
もし、抜け穴がありましたらコメントください

結果

Genericsパラメータがある場合

class HogeViewController<T>: UIViewController {}

print(HogeViewController<String>.className)
// HogeViewController<String>
print(HogeViewController<String>.nibName)
// HogeViewController

Genericsパラメータがない場合

class FugaViewController: UIViewController {}

print(FugaViewController.className)
// FugaViewController
print(FugaViewController.nibName)
// FugaViewController
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