GitHawkApp / GitHawk

The (second) best iOS app for GitHub.
http://githawk.com
MIT License
2.88k stars 382 forks source link

Refactor VCs from Storyboard with a "create" method w/ all required params #1023

Open rnystrom opened 6 years ago

rnystrom commented 6 years ago

Instead of doing this:

https://github.com/rnystrom/GitHawk/blob/master/Classes/Issues/Managing/IssueManagingSectionController.swift#L64-L75

We should require VCs initialized from a Storyboard to have their own, static func create(...) that take in all params that you would see in the configure(...) method. This get us:

Is there a way we could do this in a generic way so there's only one way to initialize VCs from Storyboards?

Sherlouk commented 6 years ago

Maybe something like this: (Haven't a clue if this would even work, just writing yano)

protocol SomeName: class {
    var storyboardName: String { get }
}

extension SomeName where Self: UIViewController {

    static func create() -> Self? {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        return storyboard.instantiateInitialViewController() as? Self
    }

}

class SomeVC: UIViewController, SomeName {
    var storyboardName: String { return "Milestones" }
}

// Anywhere else
SomeVC.create() = Optional(SomeVC)
rnystrom commented 6 years ago

Love it. I'd like the create() method to take in some sort of params to config the view controller.

Would this work?

protocol SomeName: class {
  associatedtype ConfigureType
  var storyboardName: String { get }
  func configure(injected: ConfigureType)
}

extension SomeName where Self: UIViewController {

  static func create(injected: ConfigureType) -> Self? {
    let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
    let controller = storyboard.instantiateInitialViewController() as? Self
    controller?.configure(injected: injected)
    return controller
  }

}

class SomeVC: UIViewController, SomeName {
  struct Params {
    let title: String
  }
  typealias ConfigureType = Params

  var storyboardName: String { return "Milestones" }

  func configure(injected: Params) {
    self.title = injected.title
  }
}

// Anywhere else
let params = SomeVC.Params(title: "My Title")
let controller = SomeVC.create(injected: params)
Sherlouk commented 6 years ago

assosciatedtype? We'll make a Swift dev out of you yet 😂