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 4b5a881..df67a77 100644 --- a/PRODUCTNAME/app/PRODUCTNAME.xcodeproj/project.pbxproj +++ b/PRODUCTNAME/app/PRODUCTNAME.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 */; }; 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 */; }; + 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,15 @@ 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 = ""; }; + 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 +242,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 = ""; }; @@ -284,14 +292,6 @@ path = Protocols; sourceTree = ""; }; - 209BE2522051C7BB004CF0FF /* Sourcery */ = { - isa = PBXGroup; - children = ( - 209BE2552051C90C004CF0FF /* actionable.swifttemplate */, - ); - path = Sourcery; - sourceTree = ""; - }; 2D4FA8F31E8574D2006C38ED /* Coordinators */ = { isa = PBXGroup; children = ( @@ -305,6 +305,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 +436,7 @@ 86A65AEF1FA0EA2400705C14 /* Services */ = { isa = PBXGroup; children = ( + 2DE7DAA620B4682D00CB51F2 /* Resources */, 86A65AFC1FA0EB0600705C14 /* API */, 86A65B131FA0F22B00705C14 /* Utilities */, 86A65B1C1FA0F2C900705C14 /* BuildType.swift */, @@ -529,7 +557,6 @@ isa = PBXGroup; children = ( ABF84F8E1DC99D33002DB24D /* Generated */, - 209BE2522051C7BB004CF0FF /* Sourcery */, ABC778CD1DC92BC200815FB9 /* xcconfig */, ABC778DC1DC94EE500815FB9 /* Acknowledgements.plist */, ABC7787F1DC90B7A00815FB9 /* Assets.xcassets */, @@ -643,7 +670,6 @@ children = ( CD09C94920741B24006D3501 /* SnapshotHelper.swift */, ); - name = Helpers; path = Helpers; sourceTree = ""; }; @@ -666,6 +692,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 +714,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 +831,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, + 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -813,10 +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 */, + 2D1D91A620C06932007D7808 /* Actionable+Helpers.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -865,19 +895,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 \"PRODUCTNAME\" --templates \"Services/Resources/Sourcery/Actionable.swifttemplate\" --output \"PRODUCTNAME/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 \"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 \"Services\" --templates \"Services/Resources/Sourcery/Actionable.swifttemplate\" --output \"Services/Resources/Generated/Actionable+AutoConformance.swift\"\nfi"; }; 2DFF1D1F1E8C56C700B1AD70 /* SwiftGen */ = { isa = PBXShellScriptBuildPhase; @@ -1038,6 +1082,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 +1091,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/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift index ef40525..6c03b5a 100644 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift +++ b/PRODUCTNAME/app/PRODUCTNAME/Resources/Generated/Actionable+AutoConformance.swift @@ -3,14 +3,16 @@ -//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 +24,13 @@ 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 +42,13 @@ 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 +60,13 @@ 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 @@ -68,3 +76,4 @@ extension SignInCoordinator { } } + diff --git a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/actionable.swifttemplate b/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/actionable.swifttemplate deleted file mode 100644 index c1ba55e..0000000 --- a/PRODUCTNAME/app/PRODUCTNAME/Resources/Sourcery/actionable.swifttemplate +++ /dev/null @@ -1,60 +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 -} _%> -//swiftlint:disable:previous vertical_whitespace -<% for type in (types.implementing["Actionable"] ?? []) { %> -<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> -// MARK: - <%= type.name %> -protocol <%= type.name %>Delegate: class { - func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) -} - -extension <%= type.name %> { - - typealias ActionType = Action - typealias Delegate = <%= type.name %>Delegate - - func notify(_ action: ActionType) { - delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) - } - -} -<% } -%> 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..6f5765e --- /dev/null +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -0,0 +1,53 @@ +<%_ +func variableName(for type: Type) -> String { + let lookups = [ + "Cell": "cell", + "Coordinator": "coordinator", + "View": "view", + "ViewController": "vc", + "Service": "service"] + for (suffix, specialName) in lookups { + if type.name.hasSuffix(suffix) { + return specialName + } + } + return "component" +} + +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 +} + +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..ed7bad7 --- /dev/null +++ b/PRODUCTNAME/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -0,0 +1,25 @@ +<%- include("Actionable+Helpers") %> +<%_ 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 <%= delegate %>: class { + + func <%= lowerFirstTypeName %>(_ <%= variableName(for: type) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) + +} + +<%= type.accessLevel %> extension <%= type.name %> { + + typealias ActionType = Action + typealias Delegate = <%= delegate %> + + func notify(_ action: ActionType) { + delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) + } + +} +<%_ +} +_%> 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..6f5765e --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable+Helpers.swifttemplate @@ -0,0 +1,53 @@ +<%_ +func variableName(for type: Type) -> String { + let lookups = [ + "Cell": "cell", + "Coordinator": "coordinator", + "View": "view", + "ViewController": "vc", + "Service": "service"] + for (suffix, specialName) in lookups { + if type.name.hasSuffix(suffix) { + return specialName + } + } + return "component" +} + +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 +} + +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..ed7bad7 --- /dev/null +++ b/{{ cookiecutter.project_name | replace(' ', '') }}/app/Services/Resources/Sourcery/Actionable.swifttemplate @@ -0,0 +1,25 @@ +<%- include("Actionable+Helpers") %> +<%_ 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 <%= delegate %>: class { + + func <%= lowerFirstTypeName %>(_ <%= variableName(for: type) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) + +} + +<%= type.accessLevel %> extension <%= type.name %> { + + typealias ActionType = Action + typealias Delegate = <%= 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..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,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 */; }; 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 */; }; + 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,15 @@ 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 = ""; }; + 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 +242,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 = ""; }; @@ -284,14 +292,6 @@ path = Protocols; sourceTree = ""; }; - 209BE2522051C7BB004CF0FF /* Sourcery */ = { - isa = PBXGroup; - children = ( - 209BE2552051C90C004CF0FF /* actionable.swifttemplate */, - ); - path = Sourcery; - sourceTree = ""; - }; 2D4FA8F31E8574D2006C38ED /* Coordinators */ = { isa = PBXGroup; children = ( @@ -305,6 +305,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 +436,7 @@ 86A65AEF1FA0EA2400705C14 /* Services */ = { isa = PBXGroup; children = ( + 2DE7DAA620B4682D00CB51F2 /* Resources */, 86A65AFC1FA0EB0600705C14 /* API */, 86A65B131FA0F22B00705C14 /* Utilities */, 86A65B1C1FA0F2C900705C14 /* BuildType.swift */, @@ -529,7 +557,6 @@ isa = PBXGroup; children = ( ABF84F8E1DC99D33002DB24D /* Generated */, - 209BE2522051C7BB004CF0FF /* Sourcery */, ABC778CD1DC92BC200815FB9 /* xcconfig */, ABC778DC1DC94EE500815FB9 /* Acknowledgements.plist */, ABC7787F1DC90B7A00815FB9 /* Assets.xcassets */, @@ -643,7 +670,6 @@ children = ( CD09C94920741B24006D3501 /* SnapshotHelper.swift */, ); - name = Helpers; path = Helpers; sourceTree = ""; }; @@ -666,6 +692,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 +714,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 +831,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DE7DAAD20B4687F00CB51F2 /* Actionable+Helpers.swifttemplate in Resources */, + 2DE7DAAB20B4686000CB51F2 /* Actionable.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -813,10 +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 */, + 2D1D91A620C06932007D7808 /* Actionable+Helpers.swifttemplate in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -865,19 +895,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 \"Services/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 +1082,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 +1091,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..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 @@ -3,14 +3,16 @@ -//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 +24,13 @@ 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 +42,13 @@ 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 +60,13 @@ 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 @@ -68,3 +76,4 @@ extension SignInCoordinator { } } + 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 c1ba55e..0000000 --- a/{{ cookiecutter.project_name | replace(' ', '') }}/app/{{ cookiecutter.project_name | replace(' ', '') }}/Resources/Sourcery/actionable.swifttemplate +++ /dev/null @@ -1,60 +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 -} _%> -//swiftlint:disable:previous vertical_whitespace -<% for type in (types.implementing["Actionable"] ?? []) { %> -<% let lowerFirstTypeName = lowerFirstCamelCaseGroup(type.name) -%> -// MARK: - <%= type.name %> -protocol <%= type.name %>Delegate: class { - func <%= lowerFirstTypeName %>(_ <%= variableName(fromTypeName: type.name) %>: <%= type.name %>, didNotify action: <%= type.name %>.Action) -} - -extension <%= type.name %> { - - typealias ActionType = Action - typealias Delegate = <%= type.name %>Delegate - - func notify(_ action: ActionType) { - delegate?.<%= lowerFirstTypeName %>(self, didNotify: action) - } - -} -<% } -%>