Skip to content
This repository has been archived by the owner on Sep 6, 2018. It is now read-only.

Commit

Permalink
Merge pull request #36 from juli1quere/master
Browse files Browse the repository at this point in the history
Workaround to fix classname issues with storyboards and customModule
  • Loading branch information
djbe authored Sep 7, 2017
2 parents cf22472 + 0a9a1fd commit 1fbd5b0
Show file tree
Hide file tree
Showing 17 changed files with 741 additions and 7 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ _None_

### New Features

_None_
* Storyboards: Added a new `ignoreTargetModule` parameter if you're using storyboards in multiple targets, to avoid issues with the generated code.
[Julien Quéré](https://github.com/juli1quere)
[#36](https://github.com/SwiftGen/templates/pull/36)

### Internal Changes

Expand Down
1 change: 1 addition & 0 deletions Documentation/storyboards/swift2.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ You can customize some elements of this template by overriding the following par
| `sceneEnumName` | `StoryboardScene` | Allows you to change the name of the generated `enum` containing all storyboard scenes. |
| `segueEnumName` | `StoryboardSegue` | Allows you to change the name of the generated `enum` containing all storyboard segues. |
| `module` | N/A | By default, the template will import the needed modules for custom classes, but won’t import the target’s module to avoid an import warning — using the `PRODUCT_MODULE_NAME` environment variable to detect it. Should you need to ignore an additional module, you can provide it here. |
| `ignoreTargetModule` | N/A | Setting this parameter will disable the behaviour of prefixing classes with their module name for (only) the target module. |

## Generated Code

Expand Down
1 change: 1 addition & 0 deletions Documentation/storyboards/swift3.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You can customize some elements of this template by overriding the following par
| `sceneEnumName` | `StoryboardScene` | Allows you to change the name of the generated `enum` containing all storyboard scenes. |
| `segueEnumName` | `StoryboardSegue` | Allows you to change the name of the generated `enum` containing all storyboard segues. |
| `module` | N/A | By default, the template will import the needed modules for custom classes, but won’t import the target’s module to avoid an import warning — using the `PRODUCT_MODULE_NAME` environment variable to detect it. Should you need to ignore an additional module, you can provide it here. |
| `ignoreTargetModule` | N/A | Setting this parameter will disable the behaviour of prefixing classes with their module name for (only) the target module. |

## Generated Code

Expand Down
1 change: 1 addition & 0 deletions Documentation/storyboards/swift4.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You can customize some elements of this template by overriding the following par
| `sceneEnumName` | `StoryboardScene` | Allows you to change the name of the generated `enum` containing all storyboard scenes. |
| `segueEnumName` | `StoryboardSegue` | Allows you to change the name of the generated `enum` containing all storyboard segues. |
| `module` | N/A | By default, the template will import the needed modules for custom classes, but won’t import the target’s module to avoid an import warning — using the `PRODUCT_MODULE_NAME` environment variable to detect it. Should you need to ignore an additional module, you can provide it here. |
| `ignoreTargetModule` | N/A | Setting this parameter will disable the behaviour of prefixing classes with their module name for (only) the target module. |

## Generated Code

Expand Down
11 changes: 11 additions & 0 deletions Fixtures/stub-env/ExtraDefinitions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#if os(iOS)
import UIKit

public class SLKTextViewController: UIViewController {
}
#elseif os(OSX)
import Cocoa

class DBPrefsWindowController: NSWindowController {
}
#endif
8 changes: 7 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,15 @@ namespace :output do
end
sdks = sdks(f)

if f.match('extra-definitions')
definitions = %("#{MODULE_OUTPUT_PATH}/Definitions.swift" "#{MODULE_OUTPUT_PATH}/ExtraDefinitions.swift")
else
definitions = %("#{MODULE_OUTPUT_PATH}/Definitions.swift")
end

commands = sdks.map do |sdk|
%(--toolchain #{toolchain[:toolchain]} -sdk #{sdk} swiftc -swift-version #{toolchain[:version]} ) +
%(-typecheck -target #{SDKS[sdk]} -I #{toolchain[:module_path]} "#{MODULE_OUTPUT_PATH}/Definitions.swift" #{f})
%(-typecheck -target #{SDKS[sdk]} -I #{toolchain[:module_path]} #{definitions} #{f})
end
subtask = File.basename(f, '.*')

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen

// swiftlint:disable sorted_imports
import Foundation
import UIKit
import CustomSegue
import LocationPicker

// swiftlint:disable file_length

protocol StoryboardType {
static var storyboardName: String { get }
}

extension StoryboardType {
static var storyboard: UIStoryboard {
return UIStoryboard(name: self.storyboardName, bundle: NSBundle(forClass: BundleToken.self))
}
}

struct SceneType<T: Any> {
let storyboard: StoryboardType.Type
let identifier: String

var controller: T {
guard let controller = storyboard.storyboard.instantiateViewControllerWithIdentifier(identifier) as? T else {
fatalError("Controller '\(identifier)' is not of the expected class \(T.self).")
}
return controller
}
}

struct InitialSceneType<T: Any> {
let storyboard: StoryboardType.Type

var controller: T {
guard let controller = storyboard.storyboard.instantiateInitialViewController() as? T else {
fatalError("Controller is not of the expected class \(T.self).")
}
return controller
}
}

protocol SegueType: RawRepresentable { }

extension UIViewController {
func performSegue<S: SegueType where S.RawValue == String>(segue: S, sender: AnyObject? = nil) {
performSegueWithIdentifier(segue.rawValue, sender: sender)
}
}

// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
enum StoryboardScene {
enum AdditionalImport: StoryboardType {
static let storyboardName = "AdditionalImport"

static let initialScene = InitialSceneType<LocationPicker.LocationPickerViewController>(AdditionalImport.self)

static let Public = SceneType<SLKTextViewController>(AdditionalImport.self, identifier: "public")
}
enum Anonymous: StoryboardType {
static let storyboardName = "Anonymous"

static let initialScene = InitialSceneType<UINavigationController>(Anonymous.self)
}
enum Dependency: StoryboardType {
static let storyboardName = "Dependency"

static let Dependent = SceneType<UIViewController>(Dependency.self, identifier: "Dependent")
}
enum Message: StoryboardType {
static let storyboardName = "Message"

static let initialScene = InitialSceneType<UIViewController>(Message.self)

static let Composer = SceneType<UIViewController>(Message.self, identifier: "Composer")

static let MessagesList = SceneType<UITableViewController>(Message.self, identifier: "MessagesList")

static let NavCtrl = SceneType<UINavigationController>(Message.self, identifier: "NavCtrl")

static let URLChooser = SceneType<XXPickerViewController>(Message.self, identifier: "URLChooser")
}
enum Placeholder: StoryboardType {
static let storyboardName = "Placeholder"

static let Navigation = SceneType<UINavigationController>(Placeholder.self, identifier: "Navigation")
}
enum Wizard: StoryboardType {
static let storyboardName = "Wizard"

static let initialScene = InitialSceneType<CreateAccViewController>(Wizard.self)

static let AcceptCGU = SceneType<UIViewController>(Wizard.self, identifier: "Accept-CGU")

static let CreateAccount = SceneType<CreateAccViewController>(Wizard.self, identifier: "CreateAccount")

static let Preferences = SceneType<UITableViewController>(Wizard.self, identifier: "Preferences")

static let ValidatePassword = SceneType<UIViewController>(Wizard.self, identifier: "Validate_Password")
}
}

enum StoryboardSegue {
enum AdditionalImport: String, SegueType {
case Private = "private"
}
enum Message: String, SegueType {
case CustomBack
case Embed
case NonCustom
case ShowNavCtrl = "Show-NavCtrl"
}
enum Wizard: String, SegueType {
case ShowPassword
}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name

private final class BundleToken {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen

// swiftlint:disable sorted_imports
import Foundation
import UIKit
import CustomSegue
import LocationPicker

// swiftlint:disable file_length

protocol StoryboardType {
static var storyboardName: String { get }
}

extension StoryboardType {
static var storyboard: UIStoryboard {
return UIStoryboard(name: self.storyboardName, bundle: Bundle(for: BundleToken.self))
}
}

struct SceneType<T: Any> {
let storyboard: StoryboardType.Type
let identifier: String

func instantiate() -> T {
guard let controller = storyboard.storyboard.instantiateViewController(withIdentifier: identifier) as? T else {
fatalError("ViewController '\(identifier)' is not of the expected class \(T.self).")
}
return controller
}
}

struct InitialSceneType<T: Any> {
let storyboard: StoryboardType.Type

func instantiate() -> T {
guard let controller = storyboard.storyboard.instantiateInitialViewController() as? T else {
fatalError("ViewController is not of the expected class \(T.self).")
}
return controller
}
}

protocol SegueType: RawRepresentable { }

extension UIViewController {
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
performSegue(withIdentifier: segue.rawValue, sender: sender)
}
}

// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
enum StoryboardScene {
enum AdditionalImport: StoryboardType {
static let storyboardName = "AdditionalImport"

static let initialScene = InitialSceneType<LocationPicker.LocationPickerViewController>(storyboard: AdditionalImport.self)

static let `public` = SceneType<SLKTextViewController>(storyboard: AdditionalImport.self, identifier: "public")
}
enum Anonymous: StoryboardType {
static let storyboardName = "Anonymous"

static let initialScene = InitialSceneType<UINavigationController>(storyboard: Anonymous.self)
}
enum Dependency: StoryboardType {
static let storyboardName = "Dependency"

static let dependent = SceneType<UIViewController>(storyboard: Dependency.self, identifier: "Dependent")
}
enum Message: StoryboardType {
static let storyboardName = "Message"

static let initialScene = InitialSceneType<UIViewController>(storyboard: Message.self)

static let composer = SceneType<UIViewController>(storyboard: Message.self, identifier: "Composer")

static let messagesList = SceneType<UITableViewController>(storyboard: Message.self, identifier: "MessagesList")

static let navCtrl = SceneType<UINavigationController>(storyboard: Message.self, identifier: "NavCtrl")

static let urlChooser = SceneType<XXPickerViewController>(storyboard: Message.self, identifier: "URLChooser")
}
enum Placeholder: StoryboardType {
static let storyboardName = "Placeholder"

static let navigation = SceneType<UINavigationController>(storyboard: Placeholder.self, identifier: "Navigation")
}
enum Wizard: StoryboardType {
static let storyboardName = "Wizard"

static let initialScene = InitialSceneType<CreateAccViewController>(storyboard: Wizard.self)

static let acceptCGU = SceneType<UIViewController>(storyboard: Wizard.self, identifier: "Accept-CGU")

static let createAccount = SceneType<CreateAccViewController>(storyboard: Wizard.self, identifier: "CreateAccount")

static let preferences = SceneType<UITableViewController>(storyboard: Wizard.self, identifier: "Preferences")

static let validatePassword = SceneType<UIViewController>(storyboard: Wizard.self, identifier: "Validate_Password")
}
}

enum StoryboardSegue {
enum AdditionalImport: String, SegueType {
case `private`
}
enum Message: String, SegueType {
case customBack = "CustomBack"
case embed = "Embed"
case nonCustom = "NonCustom"
case showNavCtrl = "Show-NavCtrl"
}
enum Wizard: String, SegueType {
case showPassword = "ShowPassword"
}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name

private final class BundleToken {}
Loading

0 comments on commit 1fbd5b0

Please sign in to comment.