From 5739e01486d0a0fde1222be77ee79f393c83f9e6 Mon Sep 17 00:00:00 2001 From: nevillco Date: Tue, 22 May 2018 10:55:58 -0400 Subject: [PATCH 01/12] Capitalize Actionable.swifttemplate and adjust build phase --- .../app/PRODUCTNAME.xcodeproj/project.pbxproj | 19 +++++++++---------- ...swifttemplate => Actionable.swifttemplate} | 0 2 files changed, 9 insertions(+), 10 deletions(-) rename PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/{actionable.swifttemplate => Actionable.swifttemplate} (100%) diff --git a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj index 4b5a881..c8d9ed3 100644 --- a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj +++ b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj @@ -11,7 +11,7 @@ 0055142620615F9D00E4CF68 /* Storyboards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0055142520615F9C00E4CF68 /* Storyboards.swift */; }; 006EFEF61F264204004A95DE /* TestClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFEF51F264204004A95DE /* TestClient.swift */; }; 209BE2512051C768004CF0FF /* Actionable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2502051C768004CF0FF /* Actionable.swift */; }; - 209BE2562051C90C004CF0FF /* actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 209BE2552051C90C004CF0FF /* actionable.swifttemplate */; }; + 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */; }; 209BE2592051CB4B004CF0FF /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */; }; 2D4FA8F51E8574F9006C38ED /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */; }; 2D4FA8F71E85752B006C38ED /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F61E85752B006C38ED /* Coordinator.swift */; }; @@ -140,7 +140,7 @@ 18117B6A27EAD54897E61F7E /* Pods-PRODUCTNAME-PRODUCTNAMETests.develop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PRODUCTNAME-PRODUCTNAMETests.develop.xcconfig"; path = "Pods/Target Support Files/Pods-PRODUCTNAME-PRODUCTNAMETests/Pods-PRODUCTNAME-PRODUCTNAMETests.develop.xcconfig"; sourceTree = ""; }; 1FE712F80AD5930EEAA24325 /* Pods-Services.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Services.appstore.xcconfig"; path = "Pods/Target Support Files/Pods-Services/Pods-Services.appstore.xcconfig"; sourceTree = ""; }; 209BE2502051C768004CF0FF /* Actionable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actionable.swift; sourceTree = ""; }; - 209BE2552051C90C004CF0FF /* actionable.swifttemplate */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = actionable.swifttemplate; sourceTree = ""; }; + 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; 2D4FA8F61E85752B006C38ED /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; @@ -234,7 +234,7 @@ CD09C93B20741945006D3501 /* Screenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Screenshots.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; CD09C93D20741945006D3501 /* Screenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screenshots.swift; sourceTree = ""; }; CD09C93F20741945006D3501 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CD09C94920741B24006D3501 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapshotHelper.swift; path = SnapshotHelper.swift; sourceTree = ""; }; + CD09C94920741B24006D3501 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = ""; }; CD09C94C207428AE006D3501 /* StatusBarConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarConfiguration.swift; sourceTree = ""; }; D7F90A3B2F8D15AE9564FF78 /* Pods-Services.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Services.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Services/Pods-Services.debug.xcconfig"; sourceTree = ""; }; DCD1E696B5452D855D78934E /* Pods-PRODUCTNAME.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PRODUCTNAME.release.xcconfig"; path = "Pods/Target Support Files/Pods-PRODUCTNAME/Pods-PRODUCTNAME.release.xcconfig"; sourceTree = ""; }; @@ -287,7 +287,7 @@ 209BE2522051C7BB004CF0FF /* Sourcery */ = { isa = PBXGroup; children = ( - 209BE2552051C90C004CF0FF /* actionable.swifttemplate */, + 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */, ); path = Sourcery; sourceTree = ""; @@ -643,7 +643,6 @@ children = ( CD09C94920741B24006D3501 /* SnapshotHelper.swift */, ); - name = Helpers; path = Helpers; sourceTree = ""; }; @@ -687,7 +686,7 @@ 5BD18785D9BC5E2781EBCD52 /* [CP] Check Pods Manifest.lock */, 2DFF1D1F1E8C56C700B1AD70 /* SwiftGen */, ABC778DB1DC9405700815FB9 /* SwiftLint */, - 209BE2572051C936004CF0FF /* Sourcery */, + 209BE2572051C936004CF0FF /* Sourcery (Actionable) */, 0052FE8220605B3A0058A4BC /* Generate xcconfig warnings */, ABC778711DC90B7A00815FB9 /* Sources */, ABC778721DC90B7A00815FB9 /* Frameworks */, @@ -813,7 +812,7 @@ files = ( ABC778DD1DC94EE500815FB9 /* Acknowledgements.plist in Resources */, 00551422206144E300E4CF68 /* InfoPlist.strings in Resources */, - 209BE2562051C90C004CF0FF /* actionable.swifttemplate in Resources */, + 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */, ABF84F811DC97653002DB24D /* Localizable.strings in Resources */, ABC778831DC90B7A00815FB9 /* LaunchScreen.storyboard in Resources */, ABC778801DC90B7A00815FB9 /* Assets.xcassets in Resources */, @@ -865,19 +864,19 @@ shellPath = /bin/sh; shellScript = "if [ ${FABRIC_API_KEY} != \"xxxxxx\" ]; then\nif [ \"${CONFIGURATION}\" != \"Debug\" ]; then\n\"${PODS_ROOT}/Fabric/run\" ${FABRIC_API_KEY} ${FABRIC_BUILD_SECRET}\nfi\nfi"; }; - 209BE2572051C936004CF0FF /* Sourcery */ = { + 209BE2572051C936004CF0FF /* Sourcery (Actionable) */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = Sourcery; + name = "Sourcery (Actionable)"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"PRODUCTNAME\" --templates \"PRODUCTNAME/Resources/Sourcery/actionable.swifttemplate\" --output \"PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; + shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"PRODUCTNAME\" --templates \"PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate\" --output \"PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; }; 2DFF1D1F1E8C56C700B1AD70 /* SwiftGen */ = { isa = PBXShellScriptBuildPhase; diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/actionable.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate similarity index 100% rename from PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/actionable.swifttemplate rename to PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate From 2454a7ffb74fe69a407845d6b8a048b16080f339 Mon Sep 17 00:00:00 2001 From: nevillco Date: Tue, 22 May 2018 10:59:24 -0400 Subject: [PATCH 02/12] Move utility functions into Actionable+Helpers.swift. Remove SwiftLint comment (generated files are already ignored by SwiftLint) --- .../app/PRODUCTNAME.xcodeproj/project.pbxproj | 4 ++ .../Actionable+AutoConformance.swift | 2 +- .../Sourcery/Actionable+Helpers.swifttemplate | 41 ++++++++++++++++++ .../Sourcery/Actionable.swifttemplate | 43 +------------------ 4 files changed, 47 insertions(+), 43 deletions(-) create mode 100644 PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate diff --git a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj index c8d9ed3..28105e4 100644 --- a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj +++ b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 2D75C6C71E8EEAE900F2EB1D /* OnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */; }; 2D75C6C81E8EEB1900F2EB1D /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */; }; 2DAB59F81E95336100310ABF /* OnboardingSamplePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */; }; + 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */; }; 2DFF1CEF1E89493300B1AD70 /* SignInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEE1E89493300B1AD70 /* SignInCoordinator.swift */; }; 2DFF1CF11E8950F000B1AD70 /* ContentCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CF01E8950F000B1AD70 /* ContentCoordinator.swift */; }; 2DFF1D121E8BE27B00B1AD70 /* OnboardingPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1D111E8BE27B00B1AD70 /* OnboardingPageViewController.swift */; }; @@ -146,6 +147,7 @@ 2D4FA8F61E85752B006C38ED /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = ""; }; 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingSamplePageViewModel.swift; sourceTree = ""; }; + 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = ""; }; 2DFF1CEE1E89493300B1AD70 /* SignInCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInCoordinator.swift; sourceTree = ""; }; 2DFF1CF01E8950F000B1AD70 /* ContentCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentCoordinator.swift; sourceTree = ""; }; @@ -288,6 +290,7 @@ isa = PBXGroup; children = ( 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */, + 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */, ); path = Sourcery; sourceTree = ""; @@ -816,6 +819,7 @@ ABF84F811DC97653002DB24D /* Localizable.strings in Resources */, ABC778831DC90B7A00815FB9 /* LaunchScreen.storyboard in Resources */, ABC778801DC90B7A00815FB9 /* Assets.xcassets in Resources */, + 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift index ef40525..f87b457 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift @@ -3,7 +3,7 @@ -//swiftlint:disable:previous vertical_whitespace + // MARK: - AuthCoordinator protocol AuthCoordinatorDelegate: class { diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate new file mode 100644 index 0000000..5fe3243 --- /dev/null +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -0,0 +1,41 @@ +<%_ +func variableName(fromTypeName typeName: String) -> String { +if typeName.hasSuffix("Coordinator") { return "coordinator" } +else if typeName.hasSuffix("ViewController") { return "vc" } +else if typeName.hasSuffix("View") { return "view" } +else { return "component" } +} + +/// Lowercases the first camel-case group of a type name +/// +/// - Parameter input: The name of a type +/// - Returns: The name of the type with the first camel-case group lowercased. +/// Examples: +/// - lowerThingy → lowerThingy +/// - FooViewController → fooViewController +/// - ABCViewController → abcViewController +func lowerFirstCamelCaseGroup(_ input: String) -> String { +guard !input.isEmpty else { return "" } +let firstCapitals = input.prefix { character in +return character.unicodeScalars.contains { unicodeScalar in +CharacterSet.uppercaseLetters.contains(unicodeScalar) +} +} + +guard !firstCapitals.isEmpty else { +return input +} + +let newPrefix: String + +if firstCapitals.count == 1 { +newPrefix = firstCapitals.lowercased() +} +else { +newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" +} +var updated = input +let range = updated.range(of: firstCapitals)! +updated.replaceSubrange(range, with: newPrefix) +return updated +} _%> diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate index c1ba55e..eabe3e4 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate @@ -1,45 +1,4 @@ -<% -func variableName(fromTypeName typeName: String) -> String { - if typeName.hasSuffix("Coordinator") { return "coordinator" } - else if typeName.hasSuffix("ViewController") { return "vc" } - else if typeName.hasSuffix("View") { return "view" } - else { return "component" } -} - -/// Lowercases the first camel-case group of a type name -/// -/// - Parameter input: The name of a type -/// - Returns: The name of the type with the first camel-case group lowercased. -/// Examples: -/// - lowerThingy → lowerThingy -/// - FooViewController → fooViewController -/// - ABCViewController → abcViewController -func lowerFirstCamelCaseGroup(_ input: String) -> String { - guard !input.isEmpty else { return "" } - let firstCapitals = input.prefix { character in - return character.unicodeScalars.contains { unicodeScalar in - CharacterSet.uppercaseLetters.contains(unicodeScalar) - } - } - - guard !firstCapitals.isEmpty else { - return input - } - - let newPrefix: String - - if firstCapitals.count == 1 { - newPrefix = firstCapitals.lowercased() - } - else { - newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" - } - var updated = input - let range = updated.range(of: firstCapitals)! - updated.replaceSubrange(range, with: newPrefix) - return updated -} _%> -//swiftlint:disable:previous vertical_whitespace +<%- include("Actionable+Helpers") %> <% for type in (types.implementing["Actionable"] ?? []) { %> <% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> // MARK: - <%= type.name %> From cfc485bf8e22f0f633228de96676f9c1caee6e9f Mon Sep 17 00:00:00 2001 From: nevillco Date: Tue, 22 May 2018 11:00:53 -0400 Subject: [PATCH 03/12] Add access level annotations to swifttemplate --- .../Generated/Actionable+AutoConformance.swift | 16 ++++++++-------- .../Resources/Sourcery/Actionable.swifttemplate | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift index f87b457..4bbf7e1 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift @@ -6,11 +6,11 @@ // MARK: - AuthCoordinator -protocol AuthCoordinatorDelegate: class { +internal protocol AuthCoordinatorDelegate: class { func authCoordinator(_ coordinator: AuthCoordinator, didNotify action: AuthCoordinator.Action) } -extension AuthCoordinator { +internal extension AuthCoordinator { typealias ActionType = Action typealias Delegate = AuthCoordinatorDelegate @@ -22,11 +22,11 @@ extension AuthCoordinator { } // MARK: - OnboardingCoordinator -protocol OnboardingCoordinatorDelegate: class { +internal protocol OnboardingCoordinatorDelegate: class { func onboardingCoordinator(_ coordinator: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) } -extension OnboardingCoordinator { +internal extension OnboardingCoordinator { typealias ActionType = Action typealias Delegate = OnboardingCoordinatorDelegate @@ -38,11 +38,11 @@ extension OnboardingCoordinator { } // MARK: - OnboardingPageViewController -protocol OnboardingPageViewControllerDelegate: class { +internal protocol OnboardingPageViewControllerDelegate: class { func onboardingPageViewController(_ vc: OnboardingPageViewController, didNotify action: OnboardingPageViewController.Action) } -extension OnboardingPageViewController { +internal extension OnboardingPageViewController { typealias ActionType = Action typealias Delegate = OnboardingPageViewControllerDelegate @@ -54,11 +54,11 @@ extension OnboardingPageViewController { } // MARK: - SignInCoordinator -protocol SignInCoordinatorDelegate: class { +internal protocol SignInCoordinatorDelegate: class { func signInCoordinator(_ coordinator: SignInCoordinator, didNotify action: SignInCoordinator.Action) } -extension SignInCoordinator { +internal extension SignInCoordinator { typealias ActionType = Action typealias Delegate = SignInCoordinatorDelegate diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate index eabe3e4..7e055cb 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate @@ -2,11 +2,11 @@ <% for type in (types.implementing["Actionable"] ?? []) { %> <% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> // MARK: - <%= type.name %> -protocol <%= type.name %>Delegate: class { +<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) } -extension <%= type.name %> { +<%= type.accessLevel %> extension <%= type.name %> { typealias ActionType = Action typealias Delegate = <%= type.name %>Delegate From 96690c8953b6d39966f5be9233abb40d900b4d77 Mon Sep 17 00:00:00 2001 From: nevillco Date: Tue, 22 May 2018 11:08:46 -0400 Subject: [PATCH 04/12] Drop Actionable into Services target. Add Generated folder to ignored in swiftlint.yml. --- PRODUCTNAME/app/.swiftlint.yml | 1 + .../app/PRODUCTNAME.xcodeproj/project.pbxproj | 55 +++++++++++++++++++ .../app/Services/Resources/Actionable.swift | 36 ++++++++++++ .../Actionable+AutoConformance.swift | 2 + .../Sourcery/Actionable+Helpers.swifttemplate | 41 ++++++++++++++ .../Sourcery/Actionable.swifttemplate | 19 +++++++ 6 files changed, 154 insertions(+) create mode 100644 PRODUCTNAME/app/Services/Resources/Actionable.swift create mode 100644 PRODUCTNAME/app/Services/Resources/Generated/Actionable+AutoConformance.swift create mode 100644 PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate create mode 100644 PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate diff --git a/PRODUCTNAME/app/.swiftlint.yml b/PRODUCTNAME/app/.swiftlint.yml index ac5b588..bb12c39 100644 --- a/PRODUCTNAME/app/.swiftlint.yml +++ b/PRODUCTNAME/app/.swiftlint.yml @@ -39,3 +39,4 @@ excluded: - Pods - PRODUCTNAME/Resources/Generated - Screenshots/Helpers/SnapshotHelper.swift + - Services/Resources/Generated diff --git a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj index 28105e4..a9e45ef 100644 --- a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj +++ b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj @@ -19,6 +19,10 @@ 2D75C6C81E8EEB1900F2EB1D /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */; }; 2DAB59F81E95336100310ABF /* OnboardingSamplePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */; }; 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */; }; + 2DE7DAA920B4684500CB51F2 /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */; }; + 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */; }; + 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */; }; + 2DE7DAB220B4692300CB51F2 /* Actionable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE7DAB120B4692300CB51F2 /* Actionable.swift */; }; 2DFF1CEF1E89493300B1AD70 /* SignInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEE1E89493300B1AD70 /* SignInCoordinator.swift */; }; 2DFF1CF11E8950F000B1AD70 /* ContentCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CF01E8950F000B1AD70 /* ContentCoordinator.swift */; }; 2DFF1D121E8BE27B00B1AD70 /* OnboardingPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1D111E8BE27B00B1AD70 /* OnboardingPageViewController.swift */; }; @@ -148,6 +152,10 @@ 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = ""; }; 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingSamplePageViewModel.swift; sourceTree = ""; }; 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; + 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; + 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; + 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; + 2DE7DAB120B4692300CB51F2 /* Actionable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actionable.swift; sourceTree = ""; }; 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = ""; }; 2DFF1CEE1E89493300B1AD70 /* SignInCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInCoordinator.swift; sourceTree = ""; }; 2DFF1CF01E8950F000B1AD70 /* ContentCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentCoordinator.swift; sourceTree = ""; }; @@ -308,6 +316,33 @@ path = Coordinators; sourceTree = ""; }; + 2DE7DAA620B4682D00CB51F2 /* Resources */ = { + isa = PBXGroup; + children = ( + 2DE7DAA720B4683200CB51F2 /* Generated */, + 2DE7DAB020B468EB00CB51F2 /* Sourcery */, + 2DE7DAB120B4692300CB51F2 /* Actionable.swift */, + ); + path = Resources; + sourceTree = ""; + }; + 2DE7DAA720B4683200CB51F2 /* Generated */ = { + isa = PBXGroup; + children = ( + 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */, + ); + path = Generated; + sourceTree = ""; + }; + 2DE7DAB020B468EB00CB51F2 /* Sourcery */ = { + isa = PBXGroup; + children = ( + 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */, + 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */, + ); + path = Sourcery; + sourceTree = ""; + }; 2DFF1D131E8BE3D400B1AD70 /* Onboarding */ = { isa = PBXGroup; children = ( @@ -412,6 +447,7 @@ 86A65AEF1FA0EA2400705C14 /* Services */ = { isa = PBXGroup; children = ( + 2DE7DAA620B4682D00CB51F2 /* Resources */, 86A65AFC1FA0EB0600705C14 /* API */, 86A65B131FA0F22B00705C14 /* Utilities */, 86A65B1C1FA0F2C900705C14 /* BuildType.swift */, @@ -668,6 +704,7 @@ buildConfigurationList = 86A65AFB1FA0EA2400705C14 /* Build configuration list for PBXNativeTarget "Services" */; buildPhases = ( E170C8E4C57A8FB937004E8C /* [CP] Check Pods Manifest.lock */, + 2DE7DAAE20B4689C00CB51F2 /* Sourcery (Actionable) */, 86A65AE91FA0EA2400705C14 /* Sources */, 86A65AEA1FA0EA2400705C14 /* Frameworks */, 86A65AEB1FA0EA2400705C14 /* Headers */, @@ -806,6 +843,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, + 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -882,6 +921,20 @@ shellPath = /bin/sh; shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"PRODUCTNAME\" --templates \"PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate\" --output \"PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; }; + 2DE7DAAE20B4689C00CB51F2 /* Sourcery (Actionable) */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Sourcery (Actionable)"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"Services\" --templates \"Services/Resources/Sourcery/Actionable.swifttemplate\" --output \"Services/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; + }; 2DFF1D1F1E8C56C700B1AD70 /* SwiftGen */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1041,6 +1094,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DE7DAB220B4692300CB51F2 /* Actionable.swift in Sources */, 86A65B0C1FA0EB0600705C14 /* APIEndpoint+Logging.swift in Sources */, 86A65B191FA0F22B00705C14 /* Formatters.swift in Sources */, 86A65B101FA0EB0600705C14 /* APISerialization.swift in Sources */, @@ -1049,6 +1103,7 @@ 86A65B0B1FA0EB0600705C14 /* APIConstants.swift in Sources */, 86A65B181FA0F22B00705C14 /* Closures.swift in Sources */, 86A65B1A1FA0F22B00705C14 /* Marshal+Utility.swift in Sources */, + 2DE7DAA920B4684500CB51F2 /* Actionable+AutoConformance.swift in Sources */, 86A65B091FA0EB0600705C14 /* APIClient+PRODUCTNAME.swift in Sources */, 86A65B121FA0EB0600705C14 /* OAuth.swift in Sources */, 86A65B0F1FA0EB0600705C14 /* APIError.swift in Sources */, diff --git a/PRODUCTNAME/app/Services/Resources/Actionable.swift b/PRODUCTNAME/app/Services/Resources/Actionable.swift new file mode 100644 index 0000000..108a71b --- /dev/null +++ b/PRODUCTNAME/app/Services/Resources/Actionable.swift @@ -0,0 +1,36 @@ +// +// Actionable.swift +// PRODUCTNAME +// +// Created by LEADDEVELOPER on 3/8/18. +// Copyright © 2018 ORGANIZATION. All rights reserved. +// + +protocol Actionable: class { + associatedtype ActionType + associatedtype Delegate + + func notify(_ action: ActionType) +} + +extension Actionable { + + func notify(_ action: ActionType) -> () -> Void { + return { [weak self] in + self?.notify(action) + } + } + + func notify(_ action: ActionType) -> (UIControl) -> Void { + return { [weak self] _ in + self?.notify(action) + } + } + + func notify(_ action: ActionType) -> (UIAlertAction) -> Void { + return { [weak self] _ in + self?.notify(action) + } + } + +} diff --git a/PRODUCTNAME/app/Services/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/Services/Resources/Generated/Actionable+AutoConformance.swift new file mode 100644 index 0000000..14ab93a --- /dev/null +++ b/PRODUCTNAME/app/Services/Resources/Generated/Actionable+AutoConformance.swift @@ -0,0 +1,2 @@ +// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT diff --git a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate new file mode 100644 index 0000000..5fe3243 --- /dev/null +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -0,0 +1,41 @@ +<%_ +func variableName(fromTypeName typeName: String) -> String { +if typeName.hasSuffix("Coordinator") { return "coordinator" } +else if typeName.hasSuffix("ViewController") { return "vc" } +else if typeName.hasSuffix("View") { return "view" } +else { return "component" } +} + +/// Lowercases the first camel-case group of a type name +/// +/// - Parameter input: The name of a type +/// - Returns: The name of the type with the first camel-case group lowercased. +/// Examples: +/// - lowerThingy → lowerThingy +/// - FooViewController → fooViewController +/// - ABCViewController → abcViewController +func lowerFirstCamelCaseGroup(_ input: String) -> String { +guard !input.isEmpty else { return "" } +let firstCapitals = input.prefix { character in +return character.unicodeScalars.contains { unicodeScalar in +CharacterSet.uppercaseLetters.contains(unicodeScalar) +} +} + +guard !firstCapitals.isEmpty else { +return input +} + +let newPrefix: String + +if firstCapitals.count == 1 { +newPrefix = firstCapitals.lowercased() +} +else { +newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" +} +var updated = input +let range = updated.range(of: firstCapitals)! +updated.replaceSubrange(range, with: newPrefix) +return updated +} _%> diff --git a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate new file mode 100644 index 0000000..7e055cb --- /dev/null +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -0,0 +1,19 @@ +<%- include("Actionable+Helpers") %> +<% for type in (types.implementing["Actionable"] ?? []) { %> +<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> +// MARK: - <%= type.name %> +<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { + func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) +} + +<%= type.accessLevel %> extension <%= type.name %> { + + typealias ActionType = Action + typealias Delegate = <%= type.name %>Delegate + + func notify(_ action: ActionType) { + delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) + } + +} +<% } -%> From 1da3fc1707a50826c1e67ab66ff7590ac8e18745 Mon Sep 17 00:00:00 2001 From: nevillco Date: Tue, 22 May 2018 11:16:16 -0400 Subject: [PATCH 05/12] Regenerate template --- .../app/.swiftlint.yml | 1 + .../app/Services/Resources/Actionable.swift | 36 +++++++++ .../Actionable+AutoConformance.swift | 2 + .../Sourcery/Actionable+Helpers.swifttemplate | 41 ++++++++++ .../Sourcery/Actionable.swifttemplate | 19 +++++ .../project.pbxproj | 78 ++++++++++++++++--- .../Actionable+AutoConformance.swift | 18 ++--- .../Sourcery/Actionable+Helpers.swifttemplate | 41 ++++++++++ .../Sourcery/actionable.swifttemplate | 47 +---------- 9 files changed, 220 insertions(+), 63 deletions(-) create mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Actionable.swift create mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Generated/Actionable+AutoConformance.swift create mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate create mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate create mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/.swiftlint.yml b/{{ cookiecutter.project_name | replace(' ', '') }}/app/.swiftlint.yml index d279724..9f39d1f 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/.swiftlint.yml +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/.swiftlint.yml @@ -39,3 +39,4 @@ excluded: - Pods - {{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated - Screenshots/Helpers/SnapshotHelper.swift + - Services/Resources/Generated diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Actionable.swift b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Actionable.swift new file mode 100644 index 0000000..38b5dbb --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Actionable.swift @@ -0,0 +1,36 @@ +// +// Actionable.swift +// {{ cookiecutter.project_name | replace(' ', '') }} +// +// Created by {{ cookiecutter.lead_dev }} on 3/8/18. +// Copyright © 2018 {{ cookiecutter.company_name }}. All rights reserved. +// + +protocol Actionable: class { + associatedtype ActionType + associatedtype Delegate + + func notify(_ action: ActionType) +} + +extension Actionable { + + func notify(_ action: ActionType) -> () -> Void { + return { [weak self] in + self?.notify(action) + } + } + + func notify(_ action: ActionType) -> (UIControl) -> Void { + return { [weak self] _ in + self?.notify(action) + } + } + + func notify(_ action: ActionType) -> (UIAlertAction) -> Void { + return { [weak self] _ in + self?.notify(action) + } + } + +} diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Generated/Actionable+AutoConformance.swift b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Generated/Actionable+AutoConformance.swift new file mode 100644 index 0000000..14ab93a --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Generated/Actionable+AutoConformance.swift @@ -0,0 +1,2 @@ +// Generated using Sourcery 0.12.0 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate new file mode 100644 index 0000000..5fe3243 --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -0,0 +1,41 @@ +<%_ +func variableName(fromTypeName typeName: String) -> String { +if typeName.hasSuffix("Coordinator") { return "coordinator" } +else if typeName.hasSuffix("ViewController") { return "vc" } +else if typeName.hasSuffix("View") { return "view" } +else { return "component" } +} + +/// Lowercases the first camel-case group of a type name +/// +/// - Parameter input: The name of a type +/// - Returns: The name of the type with the first camel-case group lowercased. +/// Examples: +/// - lowerThingy → lowerThingy +/// - FooViewController → fooViewController +/// - ABCViewController → abcViewController +func lowerFirstCamelCaseGroup(_ input: String) -> String { +guard !input.isEmpty else { return "" } +let firstCapitals = input.prefix { character in +return character.unicodeScalars.contains { unicodeScalar in +CharacterSet.uppercaseLetters.contains(unicodeScalar) +} +} + +guard !firstCapitals.isEmpty else { +return input +} + +let newPrefix: String + +if firstCapitals.count == 1 { +newPrefix = firstCapitals.lowercased() +} +else { +newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" +} +var updated = input +let range = updated.range(of: firstCapitals)! +updated.replaceSubrange(range, with: newPrefix) +return updated +} _%> diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate new file mode 100644 index 0000000..7e055cb --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -0,0 +1,19 @@ +<%- include("Actionable+Helpers") %> +<% for type in (types.implementing["Actionable"] ?? []) { %> +<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> +// MARK: - <%= type.name %> +<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { + func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) +} + +<%= type.accessLevel %> extension <%= type.name %> { + + typealias ActionType = Action + typealias Delegate = <%= type.name %>Delegate + + func notify(_ action: ActionType) { + delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) + } + +} +<% } -%> diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj index 6d67a3a..b5775cd 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj @@ -11,13 +11,18 @@ 0055142620615F9D00E4CF68 /* Storyboards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0055142520615F9C00E4CF68 /* Storyboards.swift */; }; 006EFEF61F264204004A95DE /* TestClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFEF51F264204004A95DE /* TestClient.swift */; }; 209BE2512051C768004CF0FF /* Actionable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2502051C768004CF0FF /* Actionable.swift */; }; - 209BE2562051C90C004CF0FF /* actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 209BE2552051C90C004CF0FF /* actionable.swifttemplate */; }; + 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */; }; 209BE2592051CB4B004CF0FF /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */; }; 2D4FA8F51E8574F9006C38ED /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */; }; 2D4FA8F71E85752B006C38ED /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F61E85752B006C38ED /* Coordinator.swift */; }; 2D75C6C71E8EEAE900F2EB1D /* OnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */; }; 2D75C6C81E8EEB1900F2EB1D /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */; }; 2DAB59F81E95336100310ABF /* OnboardingSamplePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */; }; + 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */; }; + 2DE7DAA920B4684500CB51F2 /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */; }; + 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */; }; + 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */; }; + 2DE7DAB220B4692300CB51F2 /* Actionable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE7DAB120B4692300CB51F2 /* Actionable.swift */; }; 2DFF1CEF1E89493300B1AD70 /* SignInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEE1E89493300B1AD70 /* SignInCoordinator.swift */; }; 2DFF1CF11E8950F000B1AD70 /* ContentCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CF01E8950F000B1AD70 /* ContentCoordinator.swift */; }; 2DFF1D121E8BE27B00B1AD70 /* OnboardingPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1D111E8BE27B00B1AD70 /* OnboardingPageViewController.swift */; }; @@ -140,12 +145,17 @@ 18117B6A27EAD54897E61F7E /* Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests.develop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests.develop.xcconfig"; path = "Pods/Target Support Files/Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests/Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests.develop.xcconfig"; sourceTree = ""; }; 1FE712F80AD5930EEAA24325 /* Pods-Services.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Services.appstore.xcconfig"; path = "Pods/Target Support Files/Pods-Services/Pods-Services.appstore.xcconfig"; sourceTree = ""; }; 209BE2502051C768004CF0FF /* Actionable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actionable.swift; sourceTree = ""; }; - 209BE2552051C90C004CF0FF /* actionable.swifttemplate */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = actionable.swifttemplate; sourceTree = ""; }; + 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; 2D4FA8F61E85752B006C38ED /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = ""; }; 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingSamplePageViewModel.swift; sourceTree = ""; }; + 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; + 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; + 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; + 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; + 2DE7DAB120B4692300CB51F2 /* Actionable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actionable.swift; sourceTree = ""; }; 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = ""; }; 2DFF1CEE1E89493300B1AD70 /* SignInCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInCoordinator.swift; sourceTree = ""; }; 2DFF1CF01E8950F000B1AD70 /* ContentCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentCoordinator.swift; sourceTree = ""; }; @@ -234,7 +244,7 @@ CD09C93B20741945006D3501 /* Screenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Screenshots.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; CD09C93D20741945006D3501 /* Screenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screenshots.swift; sourceTree = ""; }; CD09C93F20741945006D3501 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CD09C94920741B24006D3501 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapshotHelper.swift; path = SnapshotHelper.swift; sourceTree = ""; }; + CD09C94920741B24006D3501 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = ""; }; CD09C94C207428AE006D3501 /* StatusBarConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarConfiguration.swift; sourceTree = ""; }; D7F90A3B2F8D15AE9564FF78 /* Pods-Services.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Services.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Services/Pods-Services.debug.xcconfig"; sourceTree = ""; }; DCD1E696B5452D855D78934E /* Pods-{{ cookiecutter.project_name | replace(' ', '') }}.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{ cookiecutter.project_name | replace(' ', '') }}.release.xcconfig"; path = "Pods/Target Support Files/Pods-{{ cookiecutter.project_name | replace(' ', '') }}/Pods-{{ cookiecutter.project_name | replace(' ', '') }}.release.xcconfig"; sourceTree = ""; }; @@ -287,7 +297,8 @@ 209BE2522051C7BB004CF0FF /* Sourcery */ = { isa = PBXGroup; children = ( - 209BE2552051C90C004CF0FF /* actionable.swifttemplate */, + 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */, + 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */, ); path = Sourcery; sourceTree = ""; @@ -305,6 +316,33 @@ path = Coordinators; sourceTree = ""; }; + 2DE7DAA620B4682D00CB51F2 /* Resources */ = { + isa = PBXGroup; + children = ( + 2DE7DAA720B4683200CB51F2 /* Generated */, + 2DE7DAB020B468EB00CB51F2 /* Sourcery */, + 2DE7DAB120B4692300CB51F2 /* Actionable.swift */, + ); + path = Resources; + sourceTree = ""; + }; + 2DE7DAA720B4683200CB51F2 /* Generated */ = { + isa = PBXGroup; + children = ( + 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */, + ); + path = Generated; + sourceTree = ""; + }; + 2DE7DAB020B468EB00CB51F2 /* Sourcery */ = { + isa = PBXGroup; + children = ( + 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */, + 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */, + ); + path = Sourcery; + sourceTree = ""; + }; 2DFF1D131E8BE3D400B1AD70 /* Onboarding */ = { isa = PBXGroup; children = ( @@ -409,6 +447,7 @@ 86A65AEF1FA0EA2400705C14 /* Services */ = { isa = PBXGroup; children = ( + 2DE7DAA620B4682D00CB51F2 /* Resources */, 86A65AFC1FA0EB0600705C14 /* API */, 86A65B131FA0F22B00705C14 /* Utilities */, 86A65B1C1FA0F2C900705C14 /* BuildType.swift */, @@ -643,7 +682,6 @@ children = ( CD09C94920741B24006D3501 /* SnapshotHelper.swift */, ); - name = Helpers; path = Helpers; sourceTree = ""; }; @@ -666,6 +704,7 @@ buildConfigurationList = 86A65AFB1FA0EA2400705C14 /* Build configuration list for PBXNativeTarget "Services" */; buildPhases = ( E170C8E4C57A8FB937004E8C /* [CP] Check Pods Manifest.lock */, + 2DE7DAAE20B4689C00CB51F2 /* Sourcery (Actionable) */, 86A65AE91FA0EA2400705C14 /* Sources */, 86A65AEA1FA0EA2400705C14 /* Frameworks */, 86A65AEB1FA0EA2400705C14 /* Headers */, @@ -687,7 +726,7 @@ 5BD18785D9BC5E2781EBCD52 /* [CP] Check Pods Manifest.lock */, 2DFF1D1F1E8C56C700B1AD70 /* SwiftGen */, ABC778DB1DC9405700815FB9 /* SwiftLint */, - 209BE2572051C936004CF0FF /* Sourcery */, + 209BE2572051C936004CF0FF /* Sourcery (Actionable) */, 0052FE8220605B3A0058A4BC /* Generate xcconfig warnings */, ABC778711DC90B7A00815FB9 /* Sources */, ABC778721DC90B7A00815FB9 /* Frameworks */, @@ -804,6 +843,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, + 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -813,10 +854,11 @@ files = ( ABC778DD1DC94EE500815FB9 /* Acknowledgements.plist in Resources */, 00551422206144E300E4CF68 /* InfoPlist.strings in Resources */, - 209BE2562051C90C004CF0FF /* actionable.swifttemplate in Resources */, + 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */, ABF84F811DC97653002DB24D /* Localizable.strings in Resources */, ABC778831DC90B7A00815FB9 /* LaunchScreen.storyboard in Resources */, ABC778801DC90B7A00815FB9 /* Assets.xcassets in Resources */, + 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -865,19 +907,33 @@ shellPath = /bin/sh; shellScript = "if [ ${FABRIC_API_KEY} != \"xxxxxx\" ]; then\nif [ \"${CONFIGURATION}\" != \"Debug\" ]; then\n\"${PODS_ROOT}/Fabric/run\" ${FABRIC_API_KEY} ${FABRIC_BUILD_SECRET}\nfi\nfi"; }; - 209BE2572051C936004CF0FF /* Sourcery */ = { + 209BE2572051C936004CF0FF /* Sourcery (Actionable) */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Sourcery (Actionable)"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"{{ cookiecutter.project_name | replace(' ', '') }}\" --templates \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable.swifttemplate\" --output \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; + }; + 2DE7DAAE20B4689C00CB51F2 /* Sourcery (Actionable) */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = Sourcery; + name = "Sourcery (Actionable)"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"{{ cookiecutter.project_name | replace(' ', '') }}\" --templates \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate\" --output \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; + shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"Services\" --templates \"Services/Resources/Sourcery/Actionable.swifttemplate\" --output \"Services/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; }; 2DFF1D1F1E8C56C700B1AD70 /* SwiftGen */ = { isa = PBXShellScriptBuildPhase; @@ -1038,6 +1094,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DE7DAB220B4692300CB51F2 /* Actionable.swift in Sources */, 86A65B0C1FA0EB0600705C14 /* APIEndpoint+Logging.swift in Sources */, 86A65B191FA0F22B00705C14 /* Formatters.swift in Sources */, 86A65B101FA0EB0600705C14 /* APISerialization.swift in Sources */, @@ -1046,6 +1103,7 @@ 86A65B0B1FA0EB0600705C14 /* APIConstants.swift in Sources */, 86A65B181FA0F22B00705C14 /* Closures.swift in Sources */, 86A65B1A1FA0F22B00705C14 /* Marshal+Utility.swift in Sources */, + 2DE7DAA920B4684500CB51F2 /* Actionable+AutoConformance.swift in Sources */, 86A65B091FA0EB0600705C14 /* APIClient+{{ cookiecutter.project_name | replace(' ', '') }}.swift in Sources */, 86A65B121FA0EB0600705C14 /* OAuth.swift in Sources */, 86A65B0F1FA0EB0600705C14 /* APIError.swift in Sources */, diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift index ef40525..4bbf7e1 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift @@ -3,14 +3,14 @@ -//swiftlint:disable:previous vertical_whitespace + // MARK: - AuthCoordinator -protocol AuthCoordinatorDelegate: class { +internal protocol AuthCoordinatorDelegate: class { func authCoordinator(_ coordinator: AuthCoordinator, didNotify action: AuthCoordinator.Action) } -extension AuthCoordinator { +internal extension AuthCoordinator { typealias ActionType = Action typealias Delegate = AuthCoordinatorDelegate @@ -22,11 +22,11 @@ extension AuthCoordinator { } // MARK: - OnboardingCoordinator -protocol OnboardingCoordinatorDelegate: class { +internal protocol OnboardingCoordinatorDelegate: class { func onboardingCoordinator(_ coordinator: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) } -extension OnboardingCoordinator { +internal extension OnboardingCoordinator { typealias ActionType = Action typealias Delegate = OnboardingCoordinatorDelegate @@ -38,11 +38,11 @@ extension OnboardingCoordinator { } // MARK: - OnboardingPageViewController -protocol OnboardingPageViewControllerDelegate: class { +internal protocol OnboardingPageViewControllerDelegate: class { func onboardingPageViewController(_ vc: OnboardingPageViewController, didNotify action: OnboardingPageViewController.Action) } -extension OnboardingPageViewController { +internal extension OnboardingPageViewController { typealias ActionType = Action typealias Delegate = OnboardingPageViewControllerDelegate @@ -54,11 +54,11 @@ extension OnboardingPageViewController { } // MARK: - SignInCoordinator -protocol SignInCoordinatorDelegate: class { +internal protocol SignInCoordinatorDelegate: class { func signInCoordinator(_ coordinator: SignInCoordinator, didNotify action: SignInCoordinator.Action) } -extension SignInCoordinator { +internal extension SignInCoordinator { typealias ActionType = Action typealias Delegate = SignInCoordinatorDelegate diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate new file mode 100644 index 0000000..5fe3243 --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -0,0 +1,41 @@ +<%_ +func variableName(fromTypeName typeName: String) -> String { +if typeName.hasSuffix("Coordinator") { return "coordinator" } +else if typeName.hasSuffix("ViewController") { return "vc" } +else if typeName.hasSuffix("View") { return "view" } +else { return "component" } +} + +/// Lowercases the first camel-case group of a type name +/// +/// - Parameter input: The name of a type +/// - Returns: The name of the type with the first camel-case group lowercased. +/// Examples: +/// - lowerThingy → lowerThingy +/// - FooViewController → fooViewController +/// - ABCViewController → abcViewController +func lowerFirstCamelCaseGroup(_ input: String) -> String { +guard !input.isEmpty else { return "" } +let firstCapitals = input.prefix { character in +return character.unicodeScalars.contains { unicodeScalar in +CharacterSet.uppercaseLetters.contains(unicodeScalar) +} +} + +guard !firstCapitals.isEmpty else { +return input +} + +let newPrefix: String + +if firstCapitals.count == 1 { +newPrefix = firstCapitals.lowercased() +} +else { +newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" +} +var updated = input +let range = updated.range(of: firstCapitals)! +updated.replaceSubrange(range, with: newPrefix) +return updated +} _%> diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate index c1ba55e..7e055cb 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate @@ -1,53 +1,12 @@ -<% -func variableName(fromTypeName typeName: String) -> String { - if typeName.hasSuffix("Coordinator") { return "coordinator" } - else if typeName.hasSuffix("ViewController") { return "vc" } - else if typeName.hasSuffix("View") { return "view" } - else { return "component" } -} - -/// Lowercases the first camel-case group of a type name -/// -/// - Parameter input: The name of a type -/// - Returns: The name of the type with the first camel-case group lowercased. -/// Examples: -/// - lowerThingy → lowerThingy -/// - FooViewController → fooViewController -/// - ABCViewController → abcViewController -func lowerFirstCamelCaseGroup(_ input: String) -> String { - guard !input.isEmpty else { return "" } - let firstCapitals = input.prefix { character in - return character.unicodeScalars.contains { unicodeScalar in - CharacterSet.uppercaseLetters.contains(unicodeScalar) - } - } - - guard !firstCapitals.isEmpty else { - return input - } - - let newPrefix: String - - if firstCapitals.count == 1 { - newPrefix = firstCapitals.lowercased() - } - else { - newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" - } - var updated = input - let range = updated.range(of: firstCapitals)! - updated.replaceSubrange(range, with: newPrefix) - return updated -} _%> -//swiftlint:disable:previous vertical_whitespace +<%- include("Actionable+Helpers") %> <% for type in (types.implementing["Actionable"] ?? []) { %> <% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> // MARK: - <%= type.name %> -protocol <%= type.name %>Delegate: class { +<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) } -extension <%= type.name %> { +<%= type.accessLevel %> extension <%= type.name %> { typealias ActionType = Action typealias Delegate = <%= type.name %>Delegate From af83090935435e91b15266d9ac37569d90401030 Mon Sep 17 00:00:00 2001 From: nevillco Date: Thu, 31 May 2018 13:33:53 -0400 Subject: [PATCH 06/12] Remove Actionable.swifttemplate and Actionable+Helpers.swifttemplate from PRODUCTNAME directory. Make Services version available to both targets and update build phase --- .../app/PRODUCTNAME.xcodeproj/project.pbxproj | 22 +++------- .../Sourcery/Actionable+Helpers.swifttemplate | 41 ------------------- .../Sourcery/Actionable.swifttemplate | 19 --------- 3 files changed, 5 insertions(+), 77 deletions(-) delete mode 100644 PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate delete mode 100644 PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate diff --git a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj index a9e45ef..df67a77 100644 --- a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj +++ b/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj @@ -11,14 +11,14 @@ 0055142620615F9D00E4CF68 /* Storyboards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0055142520615F9C00E4CF68 /* Storyboards.swift */; }; 006EFEF61F264204004A95DE /* TestClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFEF51F264204004A95DE /* TestClient.swift */; }; 209BE2512051C768004CF0FF /* Actionable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2502051C768004CF0FF /* Actionable.swift */; }; - 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */; }; 209BE2592051CB4B004CF0FF /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */; }; + 2D1D91A520C06930007D7808 /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */; }; + 2D1D91A620C06932007D7808 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */; }; 2D4FA8F51E8574F9006C38ED /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */; }; 2D4FA8F71E85752B006C38ED /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F61E85752B006C38ED /* Coordinator.swift */; }; 2D75C6C71E8EEAE900F2EB1D /* OnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */; }; 2D75C6C81E8EEB1900F2EB1D /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */; }; 2DAB59F81E95336100310ABF /* OnboardingSamplePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */; }; - 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */; }; 2DE7DAA920B4684500CB51F2 /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */; }; 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */; }; 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */; }; @@ -145,13 +145,11 @@ 18117B6A27EAD54897E61F7E /* Pods-PRODUCTNAME-PRODUCTNAMETests.develop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PRODUCTNAME-PRODUCTNAMETests.develop.xcconfig"; path = "Pods/Target Support Files/Pods-PRODUCTNAME-PRODUCTNAMETests/Pods-PRODUCTNAME-PRODUCTNAMETests.develop.xcconfig"; sourceTree = ""; }; 1FE712F80AD5930EEAA24325 /* Pods-Services.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Services.appstore.xcconfig"; path = "Pods/Target Support Files/Pods-Services/Pods-Services.appstore.xcconfig"; sourceTree = ""; }; 209BE2502051C768004CF0FF /* Actionable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actionable.swift; sourceTree = ""; }; - 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; 2D4FA8F61E85752B006C38ED /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = ""; }; 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingSamplePageViewModel.swift; sourceTree = ""; }; - 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; @@ -294,15 +292,6 @@ path = Protocols; sourceTree = ""; }; - 209BE2522051C7BB004CF0FF /* Sourcery */ = { - isa = PBXGroup; - children = ( - 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */, - 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */, - ); - path = Sourcery; - sourceTree = ""; - }; 2D4FA8F31E8574D2006C38ED /* Coordinators */ = { isa = PBXGroup; children = ( @@ -568,7 +557,6 @@ isa = PBXGroup; children = ( ABF84F8E1DC99D33002DB24D /* Generated */, - 209BE2522051C7BB004CF0FF /* Sourcery */, ABC778CD1DC92BC200815FB9 /* xcconfig */, ABC778DC1DC94EE500815FB9 /* Acknowledgements.plist */, ABC7787F1DC90B7A00815FB9 /* Assets.xcassets */, @@ -854,11 +842,11 @@ files = ( ABC778DD1DC94EE500815FB9 /* Acknowledgements.plist in Resources */, 00551422206144E300E4CF68 /* InfoPlist.strings in Resources */, - 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */, ABF84F811DC97653002DB24D /* Localizable.strings in Resources */, + 2D1D91A520C06930007D7808 /* Actionable.swifttemplate in Resources */, ABC778831DC90B7A00815FB9 /* LaunchScreen.storyboard in Resources */, ABC778801DC90B7A00815FB9 /* Assets.xcassets in Resources */, - 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, + 2D1D91A620C06932007D7808 /* Actionable+Helpers.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -919,7 +907,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"PRODUCTNAME\" --templates \"PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate\" --output \"PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; + shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"PRODUCTNAME\" --templates \"Services/Resources/Sourcery/Actionable.swifttemplate\" --output \"PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; }; 2DE7DAAE20B4689C00CB51F2 /* Sourcery (Actionable) */ = { isa = PBXShellScriptBuildPhase; diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate deleted file mode 100644 index 5fe3243..0000000 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable+Helpers.swifttemplate +++ /dev/null @@ -1,41 +0,0 @@ -<%_ -func variableName(fromTypeName typeName: String) -> String { -if typeName.hasSuffix("Coordinator") { return "coordinator" } -else if typeName.hasSuffix("ViewController") { return "vc" } -else if typeName.hasSuffix("View") { return "view" } -else { return "component" } -} - -/// Lowercases the first camel-case group of a type name -/// -/// - Parameter input: The name of a type -/// - Returns: The name of the type with the first camel-case group lowercased. -/// Examples: -/// - lowerThingy → lowerThingy -/// - FooViewController → fooViewController -/// - ABCViewController → abcViewController -func lowerFirstCamelCaseGroup(_ input: String) -> String { -guard !input.isEmpty else { return "" } -let firstCapitals = input.prefix { character in -return character.unicodeScalars.contains { unicodeScalar in -CharacterSet.uppercaseLetters.contains(unicodeScalar) -} -} - -guard !firstCapitals.isEmpty else { -return input -} - -let newPrefix: String - -if firstCapitals.count == 1 { -newPrefix = firstCapitals.lowercased() -} -else { -newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" -} -var updated = input -let range = updated.range(of: firstCapitals)! -updated.replaceSubrange(range, with: newPrefix) -return updated -} _%> diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate deleted file mode 100644 index 7e055cb..0000000 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/Actionable.swifttemplate +++ /dev/null @@ -1,19 +0,0 @@ -<%- include("Actionable+Helpers") %> -<% for type in (types.implementing["Actionable"] ?? []) { %> -<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> -// MARK: - <%= type.name %> -<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { - func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) -} - -<%= type.accessLevel %> extension <%= type.name %> { - - typealias ActionType = Action - typealias Delegate = <%= type.name %>Delegate - - func notify(_ action: ActionType) { - delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) - } - -} -<% } -%> From fe80cadd2e58d558e6e047ead06a5d98e76a5519 Mon Sep 17 00:00:00 2001 From: nevillco Date: Mon, 4 Jun 2018 14:21:16 -0400 Subject: [PATCH 07/12] Tweak Actionable template to support nested Actionable types --- .../Actionable+AutoConformance.swift | 35 ++++++++- .../Sourcery/Actionable+Helpers.swifttemplate | 73 ++++++++++--------- .../Sourcery/Actionable.swifttemplate | 23 ++++-- 3 files changed, 89 insertions(+), 42 deletions(-) diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift index 4bbf7e1..33ca266 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift @@ -7,7 +7,9 @@ // MARK: - AuthCoordinator internal protocol AuthCoordinatorDelegate: class { - func authCoordinator(_ coordinator: AuthCoordinator, didNotify action: AuthCoordinator.Action) + + func authCoordinator(_ component: AuthCoordinator, didNotify action: AuthCoordinator.Action) + } internal extension AuthCoordinator { @@ -19,11 +21,18 @@ internal extension AuthCoordinator { delegate?.authCoordinator(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } // MARK: - OnboardingCoordinator internal protocol OnboardingCoordinatorDelegate: class { - func onboardingCoordinator(_ coordinator: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) + + func onboardingCoordinator(_ component: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) + } internal extension OnboardingCoordinator { @@ -35,11 +44,18 @@ internal extension OnboardingCoordinator { delegate?.onboardingCoordinator(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } // MARK: - OnboardingPageViewController internal protocol OnboardingPageViewControllerDelegate: class { + func onboardingPageViewController(_ vc: OnboardingPageViewController, didNotify action: OnboardingPageViewController.Action) + } internal extension OnboardingPageViewController { @@ -51,11 +67,18 @@ internal extension OnboardingPageViewController { delegate?.onboardingPageViewController(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } // MARK: - SignInCoordinator internal protocol SignInCoordinatorDelegate: class { - func signInCoordinator(_ coordinator: SignInCoordinator, didNotify action: SignInCoordinator.Action) + + func signInCoordinator(_ component: SignInCoordinator, didNotify action: SignInCoordinator.Action) + } internal extension SignInCoordinator { @@ -67,4 +90,10 @@ internal extension SignInCoordinator { delegate?.signInCoordinator(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } + diff --git a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate index 5fe3243..5dc4041 100644 --- a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -1,41 +1,48 @@ <%_ -func variableName(fromTypeName typeName: String) -> String { -if typeName.hasSuffix("Coordinator") { return "coordinator" } -else if typeName.hasSuffix("ViewController") { return "vc" } -else if typeName.hasSuffix("View") { return "view" } -else { return "component" } +func variableName(for type: Type) -> String { + let lookups = ["ViewController": "vc", "View": "view", "Cell": "cell", "Service": "service"] + for (suffix, specialName) in lookups { + if type.name.hasSuffix(suffix) { + return specialName + } + } + return "component" } -/// Lowercases the first camel-case group of a type name -/// -/// - Parameter input: The name of a type -/// - Returns: The name of the type with the first camel-case group lowercased. -/// Examples: -/// - lowerThingy → lowerThingy -/// - FooViewController → fooViewController -/// - ABCViewController → abcViewController -func lowerFirstCamelCaseGroup(_ input: String) -> String { -guard !input.isEmpty else { return "" } -let firstCapitals = input.prefix { character in -return character.unicodeScalars.contains { unicodeScalar in -CharacterSet.uppercaseLetters.contains(unicodeScalar) -} +func delegateName(for type: Type) -> String { + var delegateName = "\(type.localName)Delegate" + var currentType = type + while let parent = currentType.parent { + delegateName = "\(parent.localName)\(delegateName)" + currentType = parent + } + return delegateName } -guard !firstCapitals.isEmpty else { -return input -} +func lowerFirstCamelCaseGroup(_ input: String) -> String { + guard !input.isEmpty else { return "" } + let firstCapitals = input.prefix { character in + return character.unicodeScalars.contains { unicodeScalar in + CharacterSet.uppercaseLetters.contains(unicodeScalar) + } + } -let newPrefix: String + guard !firstCapitals.isEmpty else { + return input + } -if firstCapitals.count == 1 { -newPrefix = firstCapitals.lowercased() -} -else { -newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" + let newPrefix: String + + if firstCapitals.count == 1 { + newPrefix = firstCapitals.lowercased() + } + else { + newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" + } + + var updated = input + let range = updated.range(of: firstCapitals)! + updated.replaceSubrange(range, with: newPrefix) + return updated } -var updated = input -let range = updated.range(of: firstCapitals)! -updated.replaceSubrange(range, with: newPrefix) -return updated -} _%> +_%> diff --git a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate index 7e055cb..e379472 100644 --- a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -1,19 +1,30 @@ <%- include("Actionable+Helpers") %> -<% for type in (types.implementing["Actionable"] ?? []) { %> -<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> +<%_ let allTypes = types.implementing["Actionable"] +for type in allTypes { +let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.localName) +let delegate = delegateName(for: type) _%> // MARK: - <%= type.name %> -<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { - func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) +<%= type.accessLevel %> protocol <%= delegate %>: class { + + func <%= lowerFirstTypeName %>(_ <%= variableName(for: type) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) + } <%= type.accessLevel %> extension <%= type.name %> { typealias ActionType = Action - typealias Delegate = <%= type.name %>Delegate + typealias Delegate = <%= delegate %> func notify(_ action: ActionType) { delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + +} +<%_ } -<% } -%> +_%> From 289eee558c52b5238a19946a41e2b7b42df8d5c4 Mon Sep 17 00:00:00 2001 From: nevillco Date: Mon, 4 Jun 2018 14:23:52 -0400 Subject: [PATCH 08/12] Regenerate template --- .../Sourcery/Actionable+Helpers.swifttemplate | 73 ++++++++++--------- .../Sourcery/Actionable.swifttemplate | 23 ++++-- .../project.pbxproj | 22 ++---- .../Actionable+AutoConformance.swift | 35 ++++++++- .../Sourcery/Actionable+Helpers.swifttemplate | 41 ----------- .../Sourcery/actionable.swifttemplate | 19 ----- 6 files changed, 94 insertions(+), 119 deletions(-) delete mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate delete mode 100644 {{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate index 5fe3243..5dc4041 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -1,41 +1,48 @@ <%_ -func variableName(fromTypeName typeName: String) -> String { -if typeName.hasSuffix("Coordinator") { return "coordinator" } -else if typeName.hasSuffix("ViewController") { return "vc" } -else if typeName.hasSuffix("View") { return "view" } -else { return "component" } +func variableName(for type: Type) -> String { + let lookups = ["ViewController": "vc", "View": "view", "Cell": "cell", "Service": "service"] + for (suffix, specialName) in lookups { + if type.name.hasSuffix(suffix) { + return specialName + } + } + return "component" } -/// Lowercases the first camel-case group of a type name -/// -/// - Parameter input: The name of a type -/// - Returns: The name of the type with the first camel-case group lowercased. -/// Examples: -/// - lowerThingy → lowerThingy -/// - FooViewController → fooViewController -/// - ABCViewController → abcViewController -func lowerFirstCamelCaseGroup(_ input: String) -> String { -guard !input.isEmpty else { return "" } -let firstCapitals = input.prefix { character in -return character.unicodeScalars.contains { unicodeScalar in -CharacterSet.uppercaseLetters.contains(unicodeScalar) -} +func delegateName(for type: Type) -> String { + var delegateName = "\(type.localName)Delegate" + var currentType = type + while let parent = currentType.parent { + delegateName = "\(parent.localName)\(delegateName)" + currentType = parent + } + return delegateName } -guard !firstCapitals.isEmpty else { -return input -} +func lowerFirstCamelCaseGroup(_ input: String) -> String { + guard !input.isEmpty else { return "" } + let firstCapitals = input.prefix { character in + return character.unicodeScalars.contains { unicodeScalar in + CharacterSet.uppercaseLetters.contains(unicodeScalar) + } + } -let newPrefix: String + guard !firstCapitals.isEmpty else { + return input + } -if firstCapitals.count == 1 { -newPrefix = firstCapitals.lowercased() -} -else { -newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" + let newPrefix: String + + if firstCapitals.count == 1 { + newPrefix = firstCapitals.lowercased() + } + else { + newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" + } + + var updated = input + let range = updated.range(of: firstCapitals)! + updated.replaceSubrange(range, with: newPrefix) + return updated } -var updated = input -let range = updated.range(of: firstCapitals)! -updated.replaceSubrange(range, with: newPrefix) -return updated -} _%> +_%> diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate index 7e055cb..e379472 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -1,19 +1,30 @@ <%- include("Actionable+Helpers") %> -<% for type in (types.implementing["Actionable"] ?? []) { %> -<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> +<%_ let allTypes = types.implementing["Actionable"] +for type in allTypes { +let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.localName) +let delegate = delegateName(for: type) _%> // MARK: - <%= type.name %> -<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { - func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) +<%= type.accessLevel %> protocol <%= delegate %>: class { + + func <%= lowerFirstTypeName %>(_ <%= variableName(for: type) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) + } <%= type.accessLevel %> extension <%= type.name %> { typealias ActionType = Action - typealias Delegate = <%= type.name %>Delegate + typealias Delegate = <%= delegate %> func notify(_ action: ActionType) { delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + +} +<%_ } -<% } -%> +_%> diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj index b5775cd..f4fed64 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}.xcodeproj/project.pbxproj @@ -11,14 +11,14 @@ 0055142620615F9D00E4CF68 /* Storyboards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0055142520615F9C00E4CF68 /* Storyboards.swift */; }; 006EFEF61F264204004A95DE /* TestClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFEF51F264204004A95DE /* TestClient.swift */; }; 209BE2512051C768004CF0FF /* Actionable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2502051C768004CF0FF /* Actionable.swift */; }; - 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */; }; 209BE2592051CB4B004CF0FF /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */; }; + 2D1D91A520C06930007D7808 /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */; }; + 2D1D91A620C06932007D7808 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */; }; 2D4FA8F51E8574F9006C38ED /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */; }; 2D4FA8F71E85752B006C38ED /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F61E85752B006C38ED /* Coordinator.swift */; }; 2D75C6C71E8EEAE900F2EB1D /* OnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFF1CEC1E8944B900B1AD70 /* OnboardingCoordinator.swift */; }; 2D75C6C81E8EEB1900F2EB1D /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */; }; 2DAB59F81E95336100310ABF /* OnboardingSamplePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */; }; - 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */; }; 2DE7DAA920B4684500CB51F2 /* Actionable+AutoConformance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */; }; 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */; }; 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */ = {isa = PBXBuildFile; fileRef = 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */; }; @@ -145,13 +145,11 @@ 18117B6A27EAD54897E61F7E /* Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests.develop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests.develop.xcconfig"; path = "Pods/Target Support Files/Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests/Pods-{{ cookiecutter.project_name | replace(' ', '') }}-{{ cookiecutter.project_name | replace(' ', '') }}Tests.develop.xcconfig"; sourceTree = ""; }; 1FE712F80AD5930EEAA24325 /* Pods-Services.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Services.appstore.xcconfig"; path = "Pods/Target Support Files/Pods-Services/Pods-Services.appstore.xcconfig"; sourceTree = ""; }; 209BE2502051C768004CF0FF /* Actionable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actionable.swift; sourceTree = ""; }; - 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; 209BE2582051CB4B004CF0FF /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; 2D4FA8F41E8574F9006C38ED /* AppCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; 2D4FA8F61E85752B006C38ED /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = ""; }; 2D4FA8F81E8577B5006C38ED /* AuthCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = ""; }; 2DAB59F71E95336100310ABF /* OnboardingSamplePageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingSamplePageViewModel.swift; sourceTree = ""; }; - 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; 2DE7DAA820B4684500CB51F2 /* Actionable+AutoConformance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Actionable+AutoConformance.swift"; sourceTree = ""; }; 2DE7DAAA20B4686000CB51F2 /* Actionable.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = Actionable.swifttemplate; sourceTree = ""; }; 2DE7DAAC20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Actionable+Helpers.swifttemplate"; sourceTree = ""; }; @@ -294,15 +292,6 @@ path = Protocols; sourceTree = ""; }; - 209BE2522051C7BB004CF0FF /* Sourcery */ = { - isa = PBXGroup; - children = ( - 209BE2552051C90C004CF0FF /* Actionable.swifttemplate */, - 2DE7DAA420B4671A00CB51F2 /* Actionable+Helpers.swifttemplate */, - ); - path = Sourcery; - sourceTree = ""; - }; 2D4FA8F31E8574D2006C38ED /* Coordinators */ = { isa = PBXGroup; children = ( @@ -568,7 +557,6 @@ isa = PBXGroup; children = ( ABF84F8E1DC99D33002DB24D /* Generated */, - 209BE2522051C7BB004CF0FF /* Sourcery */, ABC778CD1DC92BC200815FB9 /* xcconfig */, ABC778DC1DC94EE500815FB9 /* Acknowledgements.plist */, ABC7787F1DC90B7A00815FB9 /* Assets.xcassets */, @@ -854,11 +842,11 @@ files = ( ABC778DD1DC94EE500815FB9 /* Acknowledgements.plist in Resources */, 00551422206144E300E4CF68 /* InfoPlist.strings in Resources */, - 209BE2562051C90C004CF0FF /* Actionable.swifttemplate in Resources */, ABF84F811DC97653002DB24D /* Localizable.strings in Resources */, + 2D1D91A520C06930007D7808 /* Actionable.swifttemplate in Resources */, ABC778831DC90B7A00815FB9 /* LaunchScreen.storyboard in Resources */, ABC778801DC90B7A00815FB9 /* Assets.xcassets in Resources */, - 2DE7DAA520B4671A00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, + 2D1D91A620C06932007D7808 /* Actionable+Helpers.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -919,7 +907,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"{{ cookiecutter.project_name | replace(' ', '') }}\" --templates \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable.swifttemplate\" --output \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; + shellScript = "if [ -x \"$PODS_ROOT/Sourcery/bin/sourcery\" ]; then\n\"$PODS_ROOT/Sourcery/bin/sourcery\" --sources \"{{ cookiecutter.project_name | replace(' ', '') }}\" --templates \"Services/Resources/Sourcery/Actionable.swifttemplate\" --output \"{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; }; 2DE7DAAE20B4689C00CB51F2 /* Sourcery (Actionable) */ = { isa = PBXShellScriptBuildPhase; diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift index 4bbf7e1..33ca266 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift @@ -7,7 +7,9 @@ // MARK: - AuthCoordinator internal protocol AuthCoordinatorDelegate: class { - func authCoordinator(_ coordinator: AuthCoordinator, didNotify action: AuthCoordinator.Action) + + func authCoordinator(_ component: AuthCoordinator, didNotify action: AuthCoordinator.Action) + } internal extension AuthCoordinator { @@ -19,11 +21,18 @@ internal extension AuthCoordinator { delegate?.authCoordinator(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } // MARK: - OnboardingCoordinator internal protocol OnboardingCoordinatorDelegate: class { - func onboardingCoordinator(_ coordinator: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) + + func onboardingCoordinator(_ component: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) + } internal extension OnboardingCoordinator { @@ -35,11 +44,18 @@ internal extension OnboardingCoordinator { delegate?.onboardingCoordinator(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } // MARK: - OnboardingPageViewController internal protocol OnboardingPageViewControllerDelegate: class { + func onboardingPageViewController(_ vc: OnboardingPageViewController, didNotify action: OnboardingPageViewController.Action) + } internal extension OnboardingPageViewController { @@ -51,11 +67,18 @@ internal extension OnboardingPageViewController { delegate?.onboardingPageViewController(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } // MARK: - SignInCoordinator internal protocol SignInCoordinatorDelegate: class { - func signInCoordinator(_ coordinator: SignInCoordinator, didNotify action: SignInCoordinator.Action) + + func signInCoordinator(_ component: SignInCoordinator, didNotify action: SignInCoordinator.Action) + } internal extension SignInCoordinator { @@ -67,4 +90,10 @@ internal extension SignInCoordinator { delegate?.signInCoordinator(self, didNotify: action) } + func with(delegate: Delegate) -> Self { + self.delegate = delegate + return self + } + } + diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate deleted file mode 100644 index 5fe3243..0000000 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/Actionable+Helpers.swifttemplate +++ /dev/null @@ -1,41 +0,0 @@ -<%_ -func variableName(fromTypeName typeName: String) -> String { -if typeName.hasSuffix("Coordinator") { return "coordinator" } -else if typeName.hasSuffix("ViewController") { return "vc" } -else if typeName.hasSuffix("View") { return "view" } -else { return "component" } -} - -/// Lowercases the first camel-case group of a type name -/// -/// - Parameter input: The name of a type -/// - Returns: The name of the type with the first camel-case group lowercased. -/// Examples: -/// - lowerThingy → lowerThingy -/// - FooViewController → fooViewController -/// - ABCViewController → abcViewController -func lowerFirstCamelCaseGroup(_ input: String) -> String { -guard !input.isEmpty else { return "" } -let firstCapitals = input.prefix { character in -return character.unicodeScalars.contains { unicodeScalar in -CharacterSet.uppercaseLetters.contains(unicodeScalar) -} -} - -guard !firstCapitals.isEmpty else { -return input -} - -let newPrefix: String - -if firstCapitals.count == 1 { -newPrefix = firstCapitals.lowercased() -} -else { -newPrefix = "\(firstCapitals.dropLast().lowercased())\(firstCapitals.last!)" -} -var updated = input -let range = updated.range(of: firstCapitals)! -updated.replaceSubrange(range, with: newPrefix) -return updated -} _%> diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate deleted file mode 100644 index 7e055cb..0000000 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate +++ /dev/null @@ -1,19 +0,0 @@ -<%- include("Actionable+Helpers") %> -<% for type in (types.implementing["Actionable"] ?? []) { %> -<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> -// MARK: - <%= type.name %> -<%= type.accessLevel %> protocol <%= type.name %>Delegate: class { - func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) -} - -<%= type.accessLevel %> extension <%= type.name %> { - - typealias ActionType = Action - typealias Delegate = <%= type.name %>Delegate - - func notify(_ action: ActionType) { - delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) - } - -} -<% } -%> From a6b1378cda33f6a886c1f586a10ddecc98c59a0c Mon Sep 17 00:00:00 2001 From: nevillco Date: Mon, 4 Jun 2018 14:31:38 -0400 Subject: [PATCH 09/12] Add Coordinator special-case back for Actionable naming --- .../Resources/Generated/Actionable+AutoConformance.swift | 6 +++--- .../Resources/Sourcery/Actionable+Helpers.swifttemplate | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift index 33ca266..770bd83 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift @@ -8,7 +8,7 @@ // MARK: - AuthCoordinator internal protocol AuthCoordinatorDelegate: class { - func authCoordinator(_ component: AuthCoordinator, didNotify action: AuthCoordinator.Action) + func authCoordinator(_ coordinator: AuthCoordinator, didNotify action: AuthCoordinator.Action) } @@ -31,7 +31,7 @@ internal extension AuthCoordinator { // MARK: - OnboardingCoordinator internal protocol OnboardingCoordinatorDelegate: class { - func onboardingCoordinator(_ component: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) + func onboardingCoordinator(_ coordinator: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) } @@ -77,7 +77,7 @@ internal extension OnboardingPageViewController { // MARK: - SignInCoordinator internal protocol SignInCoordinatorDelegate: class { - func signInCoordinator(_ component: SignInCoordinator, didNotify action: SignInCoordinator.Action) + func signInCoordinator(_ coordinator: SignInCoordinator, didNotify action: SignInCoordinator.Action) } diff --git a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate index 5dc4041..6f5765e 100644 --- a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -1,6 +1,11 @@ <%_ func variableName(for type: Type) -> String { - let lookups = ["ViewController": "vc", "View": "view", "Cell": "cell", "Service": "service"] + let lookups = [ + "Cell": "cell", + "Coordinator": "coordinator", + "View": "view", + "ViewController": "vc", + "Service": "service"] for (suffix, specialName) in lookups { if type.name.hasSuffix(suffix) { return specialName From ed3d547ed2dde2957a1233e7f6de64dfd90b1629 Mon Sep 17 00:00:00 2001 From: nevillco Date: Mon, 4 Jun 2018 14:34:06 -0400 Subject: [PATCH 10/12] Regenerate template --- .../Resources/Sourcery/Actionable+Helpers.swifttemplate | 7 ++++++- .../Resources/Generated/Actionable+AutoConformance.swift | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate index 5dc4041..6f5765e 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -1,6 +1,11 @@ <%_ func variableName(for type: Type) -> String { - let lookups = ["ViewController": "vc", "View": "view", "Cell": "cell", "Service": "service"] + let lookups = [ + "Cell": "cell", + "Coordinator": "coordinator", + "View": "view", + "ViewController": "vc", + "Service": "service"] for (suffix, specialName) in lookups { if type.name.hasSuffix(suffix) { return specialName diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift index 33ca266..770bd83 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift @@ -8,7 +8,7 @@ // MARK: - AuthCoordinator internal protocol AuthCoordinatorDelegate: class { - func authCoordinator(_ component: AuthCoordinator, didNotify action: AuthCoordinator.Action) + func authCoordinator(_ coordinator: AuthCoordinator, didNotify action: AuthCoordinator.Action) } @@ -31,7 +31,7 @@ internal extension AuthCoordinator { // MARK: - OnboardingCoordinator internal protocol OnboardingCoordinatorDelegate: class { - func onboardingCoordinator(_ component: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) + func onboardingCoordinator(_ coordinator: OnboardingCoordinator, didNotify action: OnboardingCoordinator.Action) } @@ -77,7 +77,7 @@ internal extension OnboardingPageViewController { // MARK: - SignInCoordinator internal protocol SignInCoordinatorDelegate: class { - func signInCoordinator(_ component: SignInCoordinator, didNotify action: SignInCoordinator.Action) + func signInCoordinator(_ coordinator: SignInCoordinator, didNotify action: SignInCoordinator.Action) } From da9762aba72ceda3fdd3bf1264d00aa311bd5923 Mon Sep 17 00:00:00 2001 From: nevillco Date: Mon, 4 Jun 2018 16:00:42 -0400 Subject: [PATCH 11/12] Remove with(delegate:) --- .../Actionable+AutoConformance.swift | 20 ------------------- .../Sourcery/Actionable.swifttemplate | 5 ----- 2 files changed, 25 deletions(-) diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift index 770bd83..6c03b5a 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift @@ -21,11 +21,6 @@ internal extension AuthCoordinator { delegate?.authCoordinator(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } // MARK: - OnboardingCoordinator @@ -44,11 +39,6 @@ internal extension OnboardingCoordinator { delegate?.onboardingCoordinator(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } // MARK: - OnboardingPageViewController @@ -67,11 +57,6 @@ internal extension OnboardingPageViewController { delegate?.onboardingPageViewController(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } // MARK: - SignInCoordinator @@ -90,10 +75,5 @@ internal extension SignInCoordinator { delegate?.signInCoordinator(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } diff --git a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate index e379472..ed7bad7 100644 --- a/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -19,11 +19,6 @@ let delegate = delegateName(for: type) _%> delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } <%_ } From 03a831afaea6d2892ca528a21ce45c2eabd89d36 Mon Sep 17 00:00:00 2001 From: nevillco Date: Mon, 4 Jun 2018 16:19:40 -0400 Subject: [PATCH 12/12] Regenerate template --- .../Sourcery/Actionable.swifttemplate | 5 ----- .../Actionable+AutoConformance.swift | 20 ------------------- 2 files changed, 25 deletions(-) diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate index e379472..ed7bad7 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -19,11 +19,6 @@ let delegate = delegateName(for: type) _%> delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } <%_ } diff --git a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift index 770bd83..6c03b5a 100644 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Generated/Actionable+AutoConformance.swift @@ -21,11 +21,6 @@ internal extension AuthCoordinator { delegate?.authCoordinator(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } // MARK: - OnboardingCoordinator @@ -44,11 +39,6 @@ internal extension OnboardingCoordinator { delegate?.onboardingCoordinator(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } // MARK: - OnboardingPageViewController @@ -67,11 +57,6 @@ internal extension OnboardingPageViewController { delegate?.onboardingPageViewController(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - } // MARK: - SignInCoordinator @@ -90,10 +75,5 @@ internal extension SignInCoordinator { delegate?.signInCoordinator(self, didNotify: action) } - func with(delegate: Delegate) -> Self { - self.delegate = delegate - return self - } - }