Code generation of initializers for storyboard-based view controllers
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.gitignore
LICENSE
README.md
StoryboardDependencyInjection.ejs
StoryboardDependencyInjectionWithSwiftGen.ejs

README.md

StoryboardDependencyInjectionTemplates

This repository provides templates for Sourcery. They allow you to code generate initializers for storyboard-based view controllers.

StoryboardDependencyInjection.ejs

  1. Add the following protocol to your project:
    protocol StoryboardInitializable where Self: UIViewController {
        static func instantiateFromStoryboard() -> Self
    }
  2. Conform view controllers to it.
  3. Use this template with Sourcery.

Example

For the following view controller:

final class ProfileViewController: UIViewController, StoryboardInitializable {
    var viewModel: ProfileViewModel!

    static func instantiateFromStoryboard() -> ProfileViewController {
        let storyboard = UIStoryboard(name: "Profile", bundle: Bundle.main)
        return storyboard.instantiateViewController(withIdentifier: "profileViewController") as! ProfileViewController
    }
}

Sourcery will generate StoryboardDependencyInjection.generated.swift with:

// MARK: - ProfileViewController - StoryboardDependencyInjection
extension ProfileViewController {

    static func makeFromStoryboard(
        viewModel: ProfileViewModel
    ) -> ProfileViewController {
        let viewController = StoryboardScene.Profile.instantiateProfileViewController()
        viewController.setDependencies(
            viewModel: viewModel
        )
        return viewController
    }

    func setDependencies(
        viewModel: ProfileViewModel
    ) {
        self.viewModel = viewModel
    }
}

Now, use makeFromStoryboard(viewModel:) to create instances of ProfileViewController. When you add a new implicitly unwrapped optional property to that view controller, the definition of this method will automatically update, and the Swift compiler will let you know about all call sites needing update.

StoryboardDependencyInjectionWithSwiftGen.ejs

  1. Add the following empty protocol to your project:
    protocol StoryboardInitializable where Self: UIViewController { }
  2. Conform view controllers to it.
  3. Set up and run SwiftGen.
  4. Use this template with Sourcery.

Example

For the following view controller:

final class ProfileViewController: UIViewController, StoryboardInitializable {
    var viewModel: ProfileViewModel!
}

Sourcery will analyze your code and code generated by SwiftGen (enum StoryboardScene) and generate StoryboardDependencyInjectionWithSwiftGen.generated.swift with:

// MARK: - ProfileViewController - StoryboardDependencyInjection
extension ProfileViewController {

    static func makeFromStoryboard(
        viewModel: ProfileViewModel
    ) -> ProfileViewController {
        let viewController = StoryboardScene.Profile.instantiateProfileViewController()
        viewController.setDependencies(
            viewModel: viewModel
        )
        return viewController
    }

    func setDependencies(
        viewModel: ProfileViewModel
    ) {
        self.viewModel = viewModel
    }
}

Now, use makeFromStoryboard(viewModel:) to create instances of ProfileViewController. When you add a new implicitly unwrapped optional property to that view controller, the definition of this method will automatically update, and the Swift compiler will let you know about all call sites needing update.