[Swift] UIViewController를 Storyboard와 UINiB로 생성하기

개인적으로 Storyboard나 Nib로 UI 구성하는것보다 코드로 구성하는게 더 좋다. 근데 스토리보드나 Nib파일로 UI 작업을 하시는 분들이 많아, 언젠가 나도 협업하기 위해 관련 코드를 기록해둔다.

스토리 보드일때와 UINiB일때, 그리고 코드로만 구성하였을때 분리를 위해 extension으로 UIViewController 클래스 전역이 아닌 프로토콜을 주입받았을때만 사용할 수 있도록 하기 위해서 프로토콜을 사용한다.

아래는 Storyboard

public protocol StoryboardInstantiable: NSObjectProtocol {
   associatedtype T
   static var defaultFileName: String { get }
   static func instantiateViewController(_ bundle: Bundle?) -> T
 }
 public extension StoryboardInstantiable where Self: UIViewController {
   static var defaultFileName: String {
     return NSStringFromClass(Self.self).components(separatedBy: ".").last!
   }
 static func instantiateViewController(_ bundle: Bundle? = nil) -> Self {
     let fileName = defaultFileName
     let storyboard = UIStoryboard(name: fileName, bundle: bundle)
     guard let vc = storyboard.instantiateInitialViewController() as? Self else {
      fatalError("Cannot instantiate initial view controller \(Self.self) from storyboard with name \(fileName)") }
      return vc
   }
 }

아래는 UINiB

public protocol NibInstantiable {
   associatedtype T
   static var className: String { get }
   static func instantiateViewController(bundle: Bundle?) -> T
 }
 extension NibInstantiable where Self: UIViewController {
 static var className: String {
     return String(describing: Self.self)
   }
  static func instantiateViewController(bundle: Bundle? = nil) -> Self {
     return Self(nibName: className, bundle: bundle)
   }
 }

근데 이왕이면 UINiB 쓰는 게 좋을 것 같다. 어차피 Storyboard내의 Segue도 사용하지 않을텐데…