├── .gitignore ├── Flow.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── Flow.xcscheme ├── Flow.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── Flow ├── ApplicationLayer │ ├── AppDelegate.swift │ ├── Coordinator │ │ └── ApplicationCoordinator.swift │ └── Utilities │ │ ├── AppAppearance │ │ └── AppAppearance.swift │ │ ├── Enums │ │ └── Storyboards.swift │ │ ├── Extensions │ │ ├── UIColorExtension.swift │ │ ├── UIFontExtension.swift │ │ └── UIViewControllerExtension.swift │ │ └── Protocols │ │ ├── BaseCoordinator.swift │ │ ├── Coordinator.swift │ │ ├── DeepLinkOption.swift │ │ └── Presentable.swift ├── BusinessLogicLayer │ ├── Factories │ │ ├── CoordinatorFactory │ │ │ ├── CoordinatorFactory.swift │ │ │ └── CoordinatorFactoryImp.swift │ │ └── FlowFactory │ │ │ ├── AuthorizationFlowFactory.swift │ │ │ ├── FeedFlowFactory.swift │ │ │ ├── FlowFactoryImp.swift │ │ │ ├── OnboardingFlowFactory.swift │ │ │ └── ProfileFlowFactory.swift │ └── Routing │ │ ├── Router.swift │ │ └── RouterImp.swift ├── Model │ ├── Product.swift │ └── User.swift ├── PresentationLayer │ ├── Flows │ │ ├── AuthorizationFlow │ │ │ ├── Coordinator │ │ │ │ ├── AuthorizationCoordinator.swift │ │ │ │ └── AuthorizationCoordinatorOutput.swift │ │ │ ├── Module │ │ │ │ ├── PasswordRecovery │ │ │ │ │ ├── Configurator │ │ │ │ │ │ ├── PasswordRecoveryConfigurator.swift │ │ │ │ │ │ └── PasswordRecoveryInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ │ ├── PasswordRecoveryInteractor.swift │ │ │ │ │ │ ├── PasswordRecoveryInteractorInput.swift │ │ │ │ │ │ └── PasswordRecoveryInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ │ ├── PasswordRecoveryModuleInput.swift │ │ │ │ │ │ ├── PasswordRecoveryModuleOutput.swift │ │ │ │ │ │ └── PasswordRecoveryPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ │ ├── PasswordRecoveryViewController.swift │ │ │ │ │ │ ├── PasswordRecoveryViewCoordinatorOutput.swift │ │ │ │ │ │ ├── PasswordRecoveryViewInput.swift │ │ │ │ │ │ └── PasswordRecoveryViewOutput.swift │ │ │ │ ├── SingIn │ │ │ │ │ ├── Configurator │ │ │ │ │ │ ├── SingInConfigurator.swift │ │ │ │ │ │ └── SingInInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ │ ├── SingInInteractor.swift │ │ │ │ │ │ ├── SingInInteractorInput.swift │ │ │ │ │ │ └── SingInInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ │ ├── SingInModuleInput.swift │ │ │ │ │ │ ├── SingInModuleOutput.swift │ │ │ │ │ │ └── SingInPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ │ ├── SingInViewController.swift │ │ │ │ │ │ ├── SingInViewCoordinatorOutput.swift │ │ │ │ │ │ ├── SingInViewInput.swift │ │ │ │ │ │ └── SingInViewOutput.swift │ │ │ │ ├── SingUp │ │ │ │ │ ├── Configurator │ │ │ │ │ │ ├── SingUpConfigurator.swift │ │ │ │ │ │ └── SingUpInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ │ ├── SingUpInteractor.swift │ │ │ │ │ │ ├── SingUpInteractorInput.swift │ │ │ │ │ │ └── SingUpInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ │ ├── SingUpModuleInput.swift │ │ │ │ │ │ ├── SingUpModuleOutput.swift │ │ │ │ │ │ └── SingUpPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ │ ├── SingUpViewController.swift │ │ │ │ │ │ ├── SingUpViewCoordinatorOutput.swift │ │ │ │ │ │ ├── SingUpViewInput.swift │ │ │ │ │ │ └── SingUpViewOutput.swift │ │ │ │ └── Terms │ │ │ │ │ ├── Configurator │ │ │ │ │ ├── TermsConfigurator.swift │ │ │ │ │ └── TermsInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ ├── TermsInteractor.swift │ │ │ │ │ ├── TermsInteractorInput.swift │ │ │ │ │ └── TermsInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ ├── TermsModuleInput.swift │ │ │ │ │ ├── TermsModuleOutput.swift │ │ │ │ │ └── TermsPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ ├── TermsViewController.swift │ │ │ │ │ ├── TermsViewCoordinatorOutput.swift │ │ │ │ │ ├── TermsViewInput.swift │ │ │ │ │ └── TermsViewOutput.swift │ │ │ └── Storyboard │ │ │ │ └── AuthorizationFlow.storyboard │ │ ├── FeedFlow │ │ │ ├── Coordinator │ │ │ │ ├── FeedCoordinator.swift │ │ │ │ └── FeedCoordinatorOutput.swift │ │ │ ├── Module │ │ │ │ ├── Cart │ │ │ │ │ ├── Configurator │ │ │ │ │ │ ├── CartConfigurator.swift │ │ │ │ │ │ └── CartInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ │ ├── CartInteractor.swift │ │ │ │ │ │ ├── CartInteractorInput.swift │ │ │ │ │ │ └── CartInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ │ ├── CartModuleInput.swift │ │ │ │ │ │ ├── CartModuleOutput.swift │ │ │ │ │ │ └── CartPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ │ ├── CartCell.swift │ │ │ │ │ │ ├── CartViewController.swift │ │ │ │ │ │ ├── CartViewCoordinatorOutput.swift │ │ │ │ │ │ ├── CartViewInput.swift │ │ │ │ │ │ └── CartViewOutput.swift │ │ │ │ ├── Feed │ │ │ │ │ ├── Configurator │ │ │ │ │ │ ├── FeedConfigurator.swift │ │ │ │ │ │ └── FeedInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ │ ├── FeedInteractor.swift │ │ │ │ │ │ ├── FeedInteractorInput.swift │ │ │ │ │ │ └── FeedInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ │ ├── FeedModuleInput.swift │ │ │ │ │ │ ├── FeedModuleOutput.swift │ │ │ │ │ │ └── FeedPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ │ ├── FeedCell.swift │ │ │ │ │ │ ├── FeedViewController.swift │ │ │ │ │ │ ├── FeedViewCoordinatorOutput.swift │ │ │ │ │ │ ├── FeedViewInput.swift │ │ │ │ │ │ └── FeedViewOutput.swift │ │ │ │ └── ProductPage │ │ │ │ │ ├── Configurator │ │ │ │ │ ├── ProductPageConfigurator.swift │ │ │ │ │ └── ProductPageInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ ├── ProductPageInteractor.swift │ │ │ │ │ ├── ProductPageInteractorInput.swift │ │ │ │ │ └── ProductPageInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ ├── ProductPageModuleInput.swift │ │ │ │ │ ├── ProductPageModuleOutput.swift │ │ │ │ │ └── ProductPagePresenter.swift │ │ │ │ │ └── View │ │ │ │ │ ├── ProductPageViewController.swift │ │ │ │ │ ├── ProductPageViewCoordinatorOutput.swift │ │ │ │ │ ├── ProductPageViewInput.swift │ │ │ │ │ ├── ProductPageViewOutput.swift │ │ │ │ │ └── ProfileCell.swift │ │ │ └── Storyboard │ │ │ │ └── FeedFlow.storyboard │ │ ├── OnboardingFlow │ │ │ ├── Coordinator │ │ │ │ ├── OnboardingCoordinator.swift │ │ │ │ └── OnboardingCoordinatorOutput.swift │ │ │ ├── Module │ │ │ │ └── Onboarding │ │ │ │ │ ├── Configurator │ │ │ │ │ ├── OnboardingConfigurator.swift │ │ │ │ │ └── OnboardingInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ ├── OnboardingInteractor.swift │ │ │ │ │ ├── OnboardingInteractorInput.swift │ │ │ │ │ └── OnboardingInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ ├── OnboardingModuleInput.swift │ │ │ │ │ ├── OnboardingModuleOutput.swift │ │ │ │ │ └── OnboardingPresenter.swift │ │ │ │ │ └── View │ │ │ │ │ ├── OnboardingViewController.swift │ │ │ │ │ ├── OnboardingViewCoordinatorOutput.swift │ │ │ │ │ ├── OnboardingViewInput.swift │ │ │ │ │ └── OnboardingViewOutput.swift │ │ │ └── Storyboard │ │ │ │ └── OnboardingFlow.storyboard │ │ ├── ProfileFlow │ │ │ ├── Coordinator │ │ │ │ ├── ProfileCoordinator.swift │ │ │ │ └── ProfileCoordinatorOutput.swift │ │ │ ├── Module │ │ │ │ └── Profile │ │ │ │ │ ├── Configurator │ │ │ │ │ ├── ProfileConfigurator.swift │ │ │ │ │ └── ProfileInitializer.swift │ │ │ │ │ ├── Interactor │ │ │ │ │ ├── ProfileInteractor.swift │ │ │ │ │ ├── ProfileInteractorInput.swift │ │ │ │ │ └── ProfileInteractorOutput.swift │ │ │ │ │ ├── Presenter │ │ │ │ │ ├── ProfileModuleInput.swift │ │ │ │ │ ├── ProfileModuleOutput.swift │ │ │ │ │ └── ProfilePresenter.swift │ │ │ │ │ └── View │ │ │ │ │ ├── ProfileViewController.swift │ │ │ │ │ ├── ProfileViewCoordinatorOutput.swift │ │ │ │ │ ├── ProfileViewInput.swift │ │ │ │ │ └── ProfileViewOutput.swift │ │ │ └── Storyboard │ │ │ │ └── ProfileFlow.storyboard │ │ └── TabbarFlow │ │ │ ├── Coordinator │ │ │ ├── TabbarCoordinator.swift │ │ │ └── TabbarCoordinatorOutput.swift │ │ │ ├── Module │ │ │ └── FlowTabbarController │ │ │ │ ├── FlowTabbar.swift │ │ │ │ ├── FlowTabbarController.swift │ │ │ │ └── FlowTabbarCoordinatorOutput.swift │ │ │ └── Storyboard │ │ │ └── TabbarFlow.storyboard │ └── ReuseableComponents │ │ └── FlowNavigationController │ │ ├── FlowNavigationController.storyboard │ │ └── FlowNavigationController.swift ├── Resources │ └── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ ├── App_Store_iOS_1024.png │ │ ├── Apple_Watch_App_Store_1024.png │ │ ├── Contents.json │ │ ├── icon_Apple_Watch_29@2x.png │ │ ├── icon_Apple_Watch_29@3x.png │ │ ├── icon_Apple_Watch_40@2x.png │ │ ├── icon_Apple_Watch_44.png │ │ ├── icon_Apple_Watch_86.png │ │ ├── icon_Apple_Watch_98.png │ │ ├── icon_Apple_Watch_Notification_Center_24@2x.png │ │ ├── icon_Apple_Watch_Notification_Center_27.5@2x.png │ │ ├── icon_CarPay_60@2x.png │ │ ├── icon_CarPay_60@3x.png │ │ ├── icon_iPad_29.png │ │ ├── icon_iPad_29@2x.png │ │ ├── icon_iPad_40.png │ │ ├── icon_iPad_40@2x.png │ │ ├── icon_iPad_76.png │ │ ├── icon_iPad_76@2x.png │ │ ├── icon_iPad_Notifications_20.png │ │ ├── icon_iPad_Notifications_20@2x.png │ │ ├── icon_iPad_Pro_83.5@2x.png │ │ ├── icon_iPhone_29@2x.png │ │ ├── icon_iPhone_29@3x.png │ │ ├── icon_iPhone_40@2x.png │ │ ├── icon_iPhone_40@3x.png │ │ ├── icon_iPhone_60@2x.png │ │ ├── icon_iPhone_60@3x.png │ │ ├── icon_iPhone_Notification_20@2x.png │ │ └── icon_iPhone_Notification_20@3x.png │ │ ├── Contents.json │ │ ├── oval.imageset │ │ ├── Contents.json │ │ ├── selectedOval.png │ │ ├── selectedOval@2x.png │ │ └── selectedOval@3x.png │ │ ├── page.imageset │ │ ├── Contents.json │ │ ├── page.png │ │ ├── page@2x.png │ │ └── page@3x.png │ │ ├── photo.imageset │ │ ├── Contents.json │ │ ├── photo.png │ │ ├── photo@2x.png │ │ └── photo@3x.png │ │ ├── selecedPage.imageset │ │ ├── Contents.json │ │ ├── selecedPage.png │ │ ├── selecedPage@2x.png │ │ └── selecedPage@3x.png │ │ └── selectedOval.imageset │ │ ├── Contents.json │ │ ├── oval.png │ │ ├── oval@2x.png │ │ └── oval@3x.png └── Supporting Files │ ├── Base.lproj │ └── LaunchScreen.storyboard │ └── Info.plist ├── FlowTests ├── Cart │ ├── Configurator │ │ └── CartConfiguratorTests.swift │ ├── Coordinator │ │ └── CartCoordinatorTests.swift │ ├── Interactor │ │ └── CartInteractorTests.swift │ ├── Presenter │ │ └── CartPresenterTests.swift │ └── View │ │ └── CartViewTests.swift ├── Feed │ ├── Configurator │ │ └── FeedConfiguratorTests.swift │ ├── Coordinator │ │ └── FeedCoordinatorTests.swift │ ├── Interactor │ │ └── FeedInteractorTests.swift │ ├── Presenter │ │ └── FeedPresenterTests.swift │ └── View │ │ └── FeedViewTests.swift ├── FlowTests.swift ├── Info.plist ├── Onboarding │ ├── Configurator │ │ └── OnboardingConfiguratorTests.swift │ ├── Coordinator │ │ └── OnboardingCoordinatorTests.swift │ ├── Interactor │ │ └── OnboardingInteractorTests.swift │ ├── Presenter │ │ └── OnboardingPresenterTests.swift │ └── View │ │ └── OnboardingViewTests.swift ├── PasswordRecovery │ ├── Configurator │ │ └── PasswordRecoveryConfiguratorTests.swift │ ├── Coordinator │ │ └── PasswordRecoveryCoordinatorTests.swift │ ├── Interactor │ │ └── PasswordRecoveryInteractorTests.swift │ ├── Presenter │ │ └── PasswordRecoveryPresenterTests.swift │ └── View │ │ └── PasswordRecoveryViewTests.swift ├── ProductPage │ ├── Configurator │ │ └── ProductPageConfiguratorTests.swift │ ├── Coordinator │ │ └── ProductPageCoordinatorTests.swift │ ├── Interactor │ │ └── ProductPageInteractorTests.swift │ ├── Presenter │ │ └── ProductPagePresenterTests.swift │ └── View │ │ └── ProductPageViewTests.swift ├── Profile │ ├── Configurator │ │ └── ProfileConfiguratorTests.swift │ ├── Coordinator │ │ └── ProfileCoordinatorTests.swift │ ├── Interactor │ │ └── ProfileInteractorTests.swift │ ├── Presenter │ │ └── ProfilePresenterTests.swift │ └── View │ │ └── ProfileViewTests.swift ├── SingIn │ ├── Configurator │ │ └── SingInConfiguratorTests.swift │ ├── Coordinator │ │ └── SingInCoordinatorTests.swift │ ├── Interactor │ │ └── SingInInteractorTests.swift │ ├── Presenter │ │ └── SingInPresenterTests.swift │ └── View │ │ └── SingInViewTests.swift ├── SingUp │ ├── Configurator │ │ └── SingUpConfiguratorTests.swift │ ├── Coordinator │ │ └── SingUpCoordinatorTests.swift │ ├── Interactor │ │ └── SingUpInteractorTests.swift │ ├── Presenter │ │ └── SingUpPresenterTests.swift │ └── View │ │ └── SingUpViewTests.swift └── Terms │ ├── Configurator │ └── TermsConfiguratorTests.swift │ ├── Coordinator │ └── TermsCoordinatorTests.swift │ ├── Interactor │ └── TermsInteractorTests.swift │ ├── Presenter │ └── TermsPresenterTests.swift │ └── View │ └── TermsViewTests.swift ├── FlowUITests ├── FlowUITests.swift └── Info.plist ├── Gemfile ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── FSPagerView │ ├── LICENSE │ ├── README-OBJECTIVE-C.md │ └── Sources │ │ ├── FSPageControl.swift │ │ ├── FSPageViewLayout.swift │ │ ├── FSPageViewTransformer.swift │ │ ├── FSPagerCollectionView.swift │ │ ├── FSPagerView.swift │ │ ├── FSPagerViewCell.swift │ │ └── FSPagerViewLayoutAttributes.swift ├── Local Podspecs │ ├── FSPagerView.podspec.json │ └── PWSwitch.podspec.json ├── Manifest.lock ├── PWSwitch │ ├── LICENSE │ ├── PWSwitch │ │ └── Classes │ │ │ └── PWSwitch.swift │ └── README.md ├── Pods.xcodeproj │ └── project.pbxproj └── Target Support Files │ ├── FSPagerView │ ├── FSPagerView-Info.plist │ ├── FSPagerView-dummy.m │ ├── FSPagerView-prefix.pch │ ├── FSPagerView-umbrella.h │ ├── FSPagerView.modulemap │ ├── FSPagerView.xcconfig │ └── Info.plist │ ├── PWSwitch │ ├── Info.plist │ ├── PWSwitch-Info.plist │ ├── PWSwitch-dummy.m │ ├── PWSwitch-prefix.pch │ ├── PWSwitch-umbrella.h │ ├── PWSwitch.modulemap │ └── PWSwitch.xcconfig │ └── Pods-Flow │ ├── Info.plist │ ├── Pods-Flow-Info.plist │ ├── Pods-Flow-acknowledgements.markdown │ ├── Pods-Flow-acknowledgements.plist │ ├── Pods-Flow-dummy.m │ ├── Pods-Flow-frameworks.sh │ ├── Pods-Flow-resources.sh │ ├── Pods-Flow-umbrella.h │ ├── Pods-Flow.debug.xcconfig │ ├── Pods-Flow.modulemap │ └── Pods-Flow.release.xcconfig ├── README.md ├── Rambafile └── fastlane ├── Appfile ├── Fastfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /Flow.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Flow.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Flow.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Flow.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Flow.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 25.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | var rootController: UINavigationController { 16 | return self.window!.rootViewController as! UINavigationController 17 | } 18 | private lazy var applicationCoordinator: Coordinator = self.produceApplicationCoordinator() 19 | 20 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 21 | applicationCoordinator.start() 22 | return true 23 | } 24 | 25 | private func produceApplicationCoordinator() -> Coordinator { 26 | let router = RouterImp(rootController: self.rootController) 27 | let coordinatorFactory = CoordinatorFactoryImp() 28 | let flowCoordinator = FlowFactoryImp() 29 | 30 | return ApplicationCoordinator(router: router, 31 | coordinatorFactory: coordinatorFactory, 32 | flowFactory: flowCoordinator) 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Coordinator/ApplicationCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationCoordinator.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | final class ApplicationCoordinator: BaseCoordinator { 12 | 13 | private let flowFactory: FlowFactoryImp 14 | private let coordinatorFactory: CoordinatorFactory 15 | private let router: Router 16 | 17 | init(router: Router, 18 | coordinatorFactory: CoordinatorFactory, 19 | flowFactory: FlowFactoryImp) { 20 | 21 | self.router = router 22 | self.coordinatorFactory = coordinatorFactory 23 | self.flowFactory = flowFactory 24 | } 25 | 26 | override func start() { 27 | runAuthorizationFlow() 28 | } 29 | 30 | private func runAuthorizationFlow() { 31 | 32 | let coordinator = coordinatorFactory.produceAuthorizationCoordinator(router: router, flowFactory: flowFactory) 33 | 34 | coordinator.finishFlow = { [weak self, weak coordinator] in 35 | 36 | self?.runOnboardingFlow() 37 | self?.removeDependency(coordinator) 38 | } 39 | 40 | addDependency(coordinator) 41 | coordinator.start() 42 | } 43 | 44 | private func runOnboardingFlow() { 45 | 46 | let coordinator = coordinatorFactory.produceOnboardingCoordinator(router: router, flowFactory: flowFactory) 47 | 48 | coordinator.finishFlow = { [weak self, weak coordinator] in 49 | 50 | self?.runTabbarFlow() 51 | self?.removeDependency(coordinator) 52 | } 53 | 54 | addDependency(coordinator) 55 | coordinator.start() 56 | } 57 | 58 | private func runTabbarFlow() { 59 | 60 | let (coordinator, module) = coordinatorFactory.produceTabbarCoordinator(coordinatorFactory: coordinatorFactory) 61 | 62 | coordinator.finishFlow = { [weak self] in 63 | self?.start() 64 | } 65 | addDependency(coordinator) 66 | router.setRootModule(module, hideBar: true) 67 | coordinator.start() 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/AppAppearance/AppAppearance.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppAppearance.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 27.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class AppAppearance { 12 | 13 | enum UI { 14 | 15 | case Button(tag: Int) 16 | case Label(tag: Int) 17 | case Filed 18 | case Image 19 | 20 | var radius: CGFloat { 21 | 22 | switch self { 23 | case .Button: return 25 24 | case .Label: return 5 25 | case .Filed: return 20 26 | case .Image: return 30 27 | } 28 | } 29 | 30 | var color: UIColor { 31 | 32 | switch self { 33 | case let .Button(tag) : 34 | 35 | switch tag { 36 | case 0: return .lightRed 37 | case 1: return .lightOrange 38 | case 2: return .smoothPurple 39 | default: return UIColor.black 40 | } 41 | 42 | case let .Label(tag): 43 | 44 | switch tag { 45 | case 0: return .smoothPurple 46 | case 1: return .transparentPurple 47 | case 2: return .smoothGray 48 | case 3: return .lightRed 49 | case 4: return .lightOrange 50 | case 5: return .lightRed 51 | case 6: return .transparentRed 52 | default: return UIColor.black 53 | } 54 | case .Filed, .Image: return .smoothGray 55 | } 56 | } 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Enums/Storyboards.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Storyboards.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum Storyboards: String { 12 | 13 | case FlowNavigationController 14 | case AuthorizationFlow 15 | case OnboardingFlow 16 | case TabbarFlow 17 | case FeedFlow 18 | case ProfileFlow 19 | } 20 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Extensions/UIColorExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColorExtension.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 28.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit.UIColor 10 | 11 | extension UIColor { 12 | 13 | static let lightRed = UIColor(red: 229/255, green: 98/255, blue: 92/255, alpha: 1) 14 | static let transparentRed = UIColor(red: 229/255, green: 98/255, blue: 92/255, alpha: 0.5) 15 | static let lightOrange = UIColor(red: 249/255, green: 191/255, blue: 118/255, alpha: 1) 16 | static let transparentOrange = UIColor(red: 249/255, green: 191/255, blue: 118/255, alpha: 0.5) 17 | static let smoothGray = UIColor(red: 241/255, green: 241/255, blue: 241/255, alpha: 1) 18 | static let smoothPurple = UIColor(red: 97/255, green: 83/255, blue: 117/255, alpha: 1) 19 | static let transparentPurple = UIColor(red: 97/255, green: 83/255, blue: 117/255, alpha: 0.5) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Extensions/UIFontExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIFontExtension.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit.UIFont 10 | 11 | extension UIFont { 12 | 13 | static func avertaCY(style: FontStyle, size: CGFloat) -> UIFont { 14 | 15 | let fontStyle = style.rawValue 16 | let font = UIFont(name: "AvertaCY-\(fontStyle)", size: size) ?? UIFont.systemFont(ofSize: size) 17 | return font 18 | } 19 | 20 | enum FontStyle: String { 21 | 22 | case regular 23 | case semibold 24 | case bold 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Extensions/UIViewControllerExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewControllerExtension.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit.UIViewController 10 | 11 | extension UIViewController { 12 | 13 | private class func instantiateControllerInStoryboard(_ storyboard: UIStoryboard, identifier: String) -> T { 14 | return storyboard.instantiateViewController(withIdentifier: identifier) as! T 15 | } 16 | 17 | class func fromStoryboard(_ storyboard: UIStoryboard, identifier: String) -> Self { 18 | return instantiateControllerInStoryboard(storyboard, identifier: identifier) 19 | } 20 | 21 | class func fromStoryboard(_ storyboard: UIStoryboard) -> Self { 22 | return fromStoryboard(storyboard, identifier: nameOfClass) 23 | } 24 | 25 | class func fromStoryboard(_ storyboard: Storyboards) -> Self { 26 | return fromStoryboard(UIStoryboard(name: storyboard.rawValue, bundle: nil), identifier: nameOfClass) 27 | } 28 | } 29 | 30 | extension NSObject { 31 | 32 | class var nameOfClass: String { 33 | return NSStringFromClass(self).components(separatedBy: ".").last! 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Protocols/BaseCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseCoordinator.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class BaseCoordinator: Coordinator { 12 | 13 | var childCoordinators: [Coordinator] = [] 14 | 15 | func start() { 16 | start(with: nil) 17 | } 18 | 19 | func start(with option: DeepLinkOption?) { } 20 | 21 | func addDependency(_ coordinator: Coordinator) { 22 | for element in childCoordinators { 23 | if element === coordinator { return } 24 | } 25 | childCoordinators.append(coordinator) 26 | } 27 | 28 | func removeDependency(_ coordinator: Coordinator?) { 29 | guard 30 | childCoordinators.isEmpty == false, 31 | let coordinator = coordinator 32 | else { return } 33 | 34 | for (index, element) in childCoordinators.enumerated() { 35 | if element === coordinator { 36 | childCoordinators.remove(at: index) 37 | break 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Protocols/Coordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Coordinator.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 26.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol Coordinator: class { 10 | func start() 11 | func start(with option: DeepLinkOption?) 12 | } 13 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Protocols/DeepLinkOption.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeepLinkOption.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 26.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum DeepLinkOption { 12 | case feed 13 | 14 | static func build(with userActivity: NSUserActivity) -> DeepLinkOption? { 15 | if userActivity.activityType == NSUserActivityTypeBrowsingWeb, 16 | let url = userActivity.webpageURL, 17 | let _ = URLComponents(url: url, resolvingAgainstBaseURL: true) { 18 | //TODO: extract string and match with DeepLinkURLConstants 19 | } 20 | return nil 21 | } 22 | 23 | static func build(with dict: [String : AnyObject]?) -> DeepLinkOption? { 24 | return .feed 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Flow/ApplicationLayer/Utilities/Protocols/Presentable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Presentable.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 26.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit.UIViewController 10 | 11 | protocol Presentable: class { 12 | 13 | func toPresent() -> UIViewController? 14 | } 15 | 16 | extension UIViewController: Presentable { 17 | 18 | func toPresent() -> UIViewController? { 19 | return self 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Factories/CoordinatorFactory/CoordinatorFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoordinatorFactory.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 26.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | import UIKit.UINavigationController 9 | 10 | protocol CoordinatorFactory { 11 | 12 | func produceAuthorizationCoordinator(router: Router, flowFactory: AuthorizationFlowFactory) -> Coordinator & AuthorizationCoordinatorOutput 13 | 14 | func produceOnboardingCoordinator(router: Router, flowFactory: OnboardingFlowFactory) -> Coordinator & OnboardingCoordinatorOutput 15 | 16 | func produceTabbarCoordinator(coordinatorFactory: CoordinatorFactory) -> (configurator: Coordinator & TabbarCoordinatorOutput, toPresent: Presentable?) 17 | 18 | func produceFeedCoordinator(flowFactory: FeedFlowFactory) -> Coordinator 19 | func produceFeedCoordinator(navigationController: UINavigationController?, flowFactory: FeedFlowFactory) -> Coordinator 20 | func produceFeedCoordinator(router: Router, flowFactory: FeedFlowFactory) -> Coordinator & FeedCoordinatorOutput 21 | 22 | func produceProfileCoordinator(flowFactory: ProfileFlowFactory) -> Coordinator 23 | func produceProfileCoordinator(navigationController: UINavigationController?, flowFactory: ProfileFlowFactory) -> Coordinator & ProfileCoordinatorOutput 24 | func produceProfileCoordinator(router: Router, flowFactory: ProfileFlowFactory) -> Coordinator & ProfileCoordinatorOutput 25 | } 26 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Factories/FlowFactory/AuthorizationFlowFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthorizationFlowFactory.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol AuthorizationFlowFactory { 12 | 13 | func produceSingInOutput() -> SingInViewCoordinatorOutput 14 | func produceSignUpOutput() -> SingUpViewCoordinatorOutput 15 | func producePasswordRecoveryOutput() -> PasswordRecoveryViewCoordinatorOutput 16 | func produceTermsOutput() -> TermsViewCoordinatorOutput 17 | } 18 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Factories/FlowFactory/FeedFlowFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedFlowFactory.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 07.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol FeedFlowFactory { 10 | 11 | func produceFeedOutput() -> FeedViewCoordinatorOutput 12 | func produceProductPageOutput() -> ProductPageViewCoordinatorOutput 13 | func produceCartOutput() -> CartViewCoordinatorOutput 14 | } 15 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Factories/FlowFactory/FlowFactoryImp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowFactoryImp.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit.UIViewController 10 | 11 | class FlowFactoryImp: AuthorizationFlowFactory, OnboardingFlowFactory, FeedFlowFactory, ProfileFlowFactory { 12 | 13 | func produceSingInOutput() -> SingInViewCoordinatorOutput { 14 | return SingInViewController.fromStoryboard(.AuthorizationFlow) 15 | } 16 | 17 | func produceSignUpOutput() -> SingUpViewCoordinatorOutput { 18 | return SingUpViewController.fromStoryboard(.AuthorizationFlow) 19 | } 20 | 21 | func producePasswordRecoveryOutput() -> PasswordRecoveryViewCoordinatorOutput { 22 | return PasswordRecoveryViewController.fromStoryboard(.AuthorizationFlow) 23 | } 24 | 25 | func produceTermsOutput() -> TermsViewCoordinatorOutput { 26 | return TermsViewController.fromStoryboard(.AuthorizationFlow) 27 | } 28 | 29 | func produceOnboardingOutput() -> OnboardingViewCoordinatorOutput { 30 | return OnboardingViewController.fromStoryboard(.OnboardingFlow) 31 | } 32 | 33 | func produceFeedOutput() -> FeedViewCoordinatorOutput { 34 | return FeedViewController.fromStoryboard(.FeedFlow) 35 | } 36 | 37 | func produceProductPageOutput() -> ProductPageViewCoordinatorOutput { 38 | return ProductPageViewController.fromStoryboard(.FeedFlow) 39 | } 40 | 41 | func produceCartOutput() -> CartViewCoordinatorOutput { 42 | return CartViewController.fromStoryboard(.FeedFlow) 43 | } 44 | 45 | func produceProfileOutput() -> ProfileViewCoordinatorOutput { 46 | return ProfileViewController.fromStoryboard(.ProfileFlow) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Factories/FlowFactory/OnboardingFlowFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingFlowFactory.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 02.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol OnboardingFlowFactory { 10 | 11 | func produceOnboardingOutput() -> OnboardingViewCoordinatorOutput 12 | } 13 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Factories/FlowFactory/ProfileFlowFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileFlowFactory.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 09.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ProfileFlowFactory { 12 | func produceProfileOutput() -> ProfileViewCoordinatorOutput 13 | } 14 | -------------------------------------------------------------------------------- /Flow/BusinessLogicLayer/Routing/Router.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Router.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol Router: Presentable { 12 | 13 | func present(_ module: Presentable?) 14 | func present(_ module: Presentable?, animated: Bool) 15 | 16 | func push(_ module: Presentable?) 17 | func push(_ module: Presentable?, animated: Bool) 18 | func push(_ module: Presentable?, animated: Bool, completion: (() -> Void)?) 19 | 20 | func popModule() 21 | func popModule(animated: Bool) 22 | 23 | func dismissModule() 24 | func dismissModule(animated: Bool, completion: (() -> Void)?) 25 | 26 | func setRootModule(_ module: Presentable?) 27 | func setRootModule(_ module: Presentable?, hideBar: Bool) 28 | 29 | func popToRootModule(animated: Bool) 30 | } 31 | -------------------------------------------------------------------------------- /Flow/Model/Product.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Product.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Product { 12 | let id: Int 13 | let name: String 14 | } 15 | -------------------------------------------------------------------------------- /Flow/Model/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct User { 12 | let id: Int 13 | let name: String 14 | let token: String 15 | } 16 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Coordinator/AuthorizationCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthorizationCoordinator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class AuthorizationCoordinator: BaseCoordinator , AuthorizationCoordinatorOutput { 10 | 11 | // MARK: - AuthorizationCoordinatorOutput 12 | 13 | var finishFlow: (() -> Void)? 14 | 15 | private let factory: AuthorizationFlowFactory 16 | private let router: Router 17 | 18 | init(router: Router, factory: AuthorizationFlowFactory) { 19 | 20 | self.factory = factory 21 | self.router = router 22 | } 23 | 24 | // MARK: - BaseCoordinator 25 | 26 | override func start() { 27 | showSingIn() 28 | } 29 | 30 | // MARK: - Flow's controllers 31 | 32 | private func showSingIn() { 33 | 34 | let singInOutput = factory.produceSingInOutput() 35 | singInOutput.onSignIn = { [weak self] in 36 | self?.finishFlow?() 37 | } 38 | 39 | singInOutput.onSignUp = { [weak self] in 40 | self?.showSingUp() 41 | } 42 | 43 | singInOutput.onPasswordRecovery = { [weak self] in 44 | self?.showPasswordRecovery() 45 | } 46 | 47 | router.setRootModule(singInOutput, hideBar: true) 48 | } 49 | 50 | private func showSingUp() { 51 | 52 | let singUpOutput = factory.produceSignUpOutput() 53 | singUpOutput.onSignUp = { [weak self] in 54 | self?.finishFlow?() 55 | } 56 | 57 | singUpOutput.onTerms = { [weak self] in 58 | self?.showTerms() 59 | } 60 | 61 | singUpOutput.onSignIn = { [weak self] in 62 | self?.router.popModule() 63 | } 64 | 65 | router.push(singUpOutput) 66 | } 67 | 68 | private func showPasswordRecovery() { 69 | 70 | let passwordRecoveryOutput = factory.producePasswordRecoveryOutput() 71 | passwordRecoveryOutput.onSend = { [weak self] in 72 | self?.router.dismissModule() 73 | } 74 | 75 | router.present(passwordRecoveryOutput) 76 | } 77 | 78 | private func showTerms() { 79 | 80 | let termsOutput = factory.produceTermsOutput() 81 | termsOutput.onAccept = { [weak self] in 82 | self?.router.popModule() 83 | } 84 | 85 | router.push(termsOutput) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Coordinator/AuthorizationCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthorizationCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol AuthorizationCoordinatorOutput: class { 10 | 11 | var finishFlow: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Configurator/PasswordRecoveryConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PasswordRecoveryModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? PasswordRecoveryViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: PasswordRecoveryViewController) { 21 | 22 | let presenter = PasswordRecoveryPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = PasswordRecoveryInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Configurator/PasswordRecoveryInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PasswordRecoveryModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var passwordrecoveryViewController: PasswordRecoveryViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = PasswordRecoveryModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: passwordrecoveryViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Interactor/PasswordRecoveryInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class PasswordRecoveryInteractor: PasswordRecoveryInteractorInput { 10 | 11 | weak var output: PasswordRecoveryInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Interactor/PasswordRecoveryInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol PasswordRecoveryInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Interactor/PasswordRecoveryInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol PasswordRecoveryInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Presenter/PasswordRecoveryModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol PasswordRecoveryModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Presenter/PasswordRecoveryModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol PasswordRecoveryModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/Presenter/PasswordRecoveryPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class PasswordRecoveryPresenter: PasswordRecoveryModuleInput, PasswordRecoveryViewOutput, PasswordRecoveryInteractorOutput { 10 | 11 | weak var view: PasswordRecoveryViewInput! 12 | weak var coordinator: PasswordRecoveryViewCoordinatorOutput! 13 | var interactor: PasswordRecoveryInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func onSendTap() { 20 | coordinator.onSend?() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/View/PasswordRecoveryViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryViewController.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PasswordRecoveryViewController: UIViewController, PasswordRecoveryViewInput, PasswordRecoveryViewCoordinatorOutput { 12 | 13 | // MARK: - Properties 14 | 15 | var output: PasswordRecoveryViewOutput! 16 | 17 | // MARK: - IBOutlets 18 | 19 | @IBOutlet weak var field: UITextField! 20 | @IBOutlet var labels: [UILabel]! 21 | @IBOutlet weak var button: UIButton! 22 | 23 | // MARK: - Life cycle 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | output.viewDidLoad() 29 | } 30 | 31 | 32 | // MARK: - PasswordRecoveryViewInput 33 | 34 | func setupInitialState() { 35 | 36 | fieldAppearance() 37 | labelsAppearance() 38 | buttonAppearance() 39 | } 40 | 41 | // MARK: - PasswordRecoveryViewCoordinatorOutput 42 | 43 | var onSend: (() -> Void)? 44 | 45 | // MARK: - Appearance 46 | 47 | private func fieldAppearance() { 48 | 49 | field.backgroundColor = AppAppearance.UI.Filed.color 50 | field.layer.cornerRadius = AppAppearance.UI.Filed.radius 51 | field.layer.masksToBounds = true 52 | field.textAlignment = .center 53 | field.isEnabled = false 54 | } 55 | 56 | private func labelsAppearance() { 57 | 58 | labels.forEach { (label) in 59 | 60 | label.backgroundColor = AppAppearance.UI.Label(tag: label.tag).color 61 | label.layer.cornerRadius = AppAppearance.UI.Label(tag: label.tag).radius 62 | label.layer.masksToBounds = true 63 | label.textAlignment = .left 64 | } 65 | } 66 | 67 | private func buttonAppearance() { 68 | 69 | button.layer.cornerRadius = AppAppearance.UI.Button(tag: button.tag).radius 70 | button.layer.masksToBounds = true 71 | button.setTitleColor(.white, for: .normal) 72 | button.backgroundColor = AppAppearance.UI.Button(tag: button.tag).color 73 | button.setTitle("Send", for: .normal) 74 | button.titleLabel?.font = UIFont.avertaCY(style: .semibold, size: 13) 75 | 76 | } 77 | 78 | // MARK: - Actions 79 | 80 | @IBAction func send(_ sender: UIButton) { 81 | 82 | output.onSendTap() 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/View/PasswordRecoveryViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol PasswordRecoveryViewCoordinatorOutput: Presentable { 10 | 11 | var onSend: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/View/PasswordRecoveryViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol PasswordRecoveryViewInput: class { 10 | 11 | func setupInitialState() 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/PasswordRecovery/View/PasswordRecoveryViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol PasswordRecoveryViewOutput { 10 | 11 | func viewDidLoad() 12 | func onSendTap() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Configurator/SingInConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SingInModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? SingInViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: SingInViewController) { 21 | 22 | let presenter = SingInPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = SingInInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Configurator/SingInInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SingInModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var singinViewController: SingInViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = SingInModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: singinViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Interactor/SingInInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class SingInInteractor: SingInInteractorInput { 10 | 11 | weak var output: SingInInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Interactor/SingInInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol SingInInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Interactor/SingInInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol SingInInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Presenter/SingInModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingInModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Presenter/SingInModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingInModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/Presenter/SingInPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | final class SingInPresenter: SingInModuleInput, SingInViewOutput, SingInInteractorOutput { 10 | 11 | // MARK: - Properties 12 | 13 | weak var coordinator: SingInViewCoordinatorOutput! 14 | weak var view: SingInViewInput! 15 | var interactor: SingInInteractorInput! 16 | 17 | // MARK: - SingInViewOutput 18 | 19 | func viewDidLoad() { 20 | view.setupInitialState() 21 | } 22 | 23 | func onSungInTap() { 24 | coordinator.onSignIn?() 25 | } 26 | 27 | func onSungUnTap() { 28 | coordinator.onSignUp?() 29 | } 30 | 31 | func onPasswordRecoveryTap() { 32 | coordinator.onPasswordRecovery?() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/View/SingInViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol SingInViewCoordinatorOutput: Presentable { 10 | 11 | var onSignIn: (() -> Void)? { get set } 12 | var onSignUp: (() -> Void)? { get set } 13 | var onPasswordRecovery: (() -> Void)? { get set } 14 | } 15 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/View/SingInViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingInViewInput: class { 10 | 11 | 12 | func setupInitialState() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingIn/View/SingInViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingInViewOutput { 10 | 11 | func viewDidLoad() 12 | func onSungInTap() 13 | func onSungUnTap() 14 | func onPasswordRecoveryTap() 15 | } 16 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Configurator/SingUpConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SingUpModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? SingUpViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: SingUpViewController) { 21 | 22 | let presenter = SingUpPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = SingUpInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Configurator/SingUpInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SingUpModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var singupViewController: SingUpViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = SingUpModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: singupViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Interactor/SingUpInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class SingUpInteractor: SingUpInteractorInput { 10 | 11 | weak var output: SingUpInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Interactor/SingUpInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol SingUpInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Interactor/SingUpInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol SingUpInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Presenter/SingUpModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingUpModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Presenter/SingUpModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingUpModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/Presenter/SingUpPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class SingUpPresenter: SingUpModuleInput, SingUpViewOutput, SingUpInteractorOutput { 10 | 11 | weak var view: SingUpViewInput! 12 | weak var coordinator: SingUpViewCoordinatorOutput! 13 | var interactor: SingUpInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func onSingInTap() { 20 | coordinator.onSignIn?() 21 | } 22 | 23 | func onSingUpTap() { 24 | coordinator.onSignUp?() 25 | } 26 | 27 | func onTermsTap() { 28 | coordinator.onTerms?() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/View/SingUpViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol SingUpViewCoordinatorOutput: Presentable { 10 | 11 | var onSignIn: (() -> Void)? { get set } 12 | var onSignUp: (() -> Void)? { get set } 13 | var onTerms: (() -> Void)? { get set } 14 | 15 | var confirmed: Bool { get set } 16 | func conformTermsAgreement(_ agree: Bool) 17 | } 18 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/View/SingUpViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingUpViewInput: class { 10 | 11 | func setupInitialState() 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/SingUp/View/SingUpViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol SingUpViewOutput { 10 | 11 | func viewDidLoad() 12 | func onSingInTap() 13 | func onSingUpTap() 14 | func onTermsTap() 15 | } 16 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Configurator/TermsConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TermsModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? TermsViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: TermsViewController) { 21 | 22 | let presenter = TermsPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = TermsInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Configurator/TermsInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TermsModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var termsViewController: TermsViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = TermsModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: termsViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Interactor/TermsInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class TermsInteractor: TermsInteractorInput { 10 | 11 | weak var output: TermsInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Interactor/TermsInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol TermsInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Interactor/TermsInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol TermsInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Presenter/TermsModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol TermsModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Presenter/TermsModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol TermsModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/Presenter/TermsPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class TermsPresenter: TermsModuleInput, TermsViewOutput, TermsInteractorOutput { 10 | 11 | weak var view: TermsViewInput! 12 | weak var coordinator: TermsViewCoordinatorOutput! 13 | var interactor: TermsInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func onAcceptTap() { 20 | coordinator.onAccept?() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/View/TermsViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol TermsViewCoordinatorOutput: Presentable { 10 | 11 | var onAccept: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/View/TermsViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol TermsViewInput: class { 10 | 11 | func setupInitialState() 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/AuthorizationFlow/Module/Terms/View/TermsViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol TermsViewOutput { 10 | 11 | func viewDidLoad() 12 | func onAcceptTap() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Coordinator/FeedCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedCoordinator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class FeedCoordinator: BaseCoordinator, FeedCoordinatorOutput { 10 | 11 | private let factory: FeedFlowFactory 12 | private let router: Router 13 | 14 | init(router: Router, factory: FeedFlowFactory) { 15 | 16 | self.factory = factory 17 | self.router = router 18 | } 19 | 20 | // MARK: - BaseCoordinator 21 | 22 | override func start() { 23 | showFeed() 24 | } 25 | 26 | private func showFeed() { 27 | 28 | let feedOutput = factory.produceFeedOutput() 29 | feedOutput.onItemSelected = { [weak self] in 30 | self?.showProductPage() 31 | } 32 | 33 | router.setRootModule(feedOutput, hideBar: true) 34 | } 35 | 36 | private func showProductPage() { 37 | 38 | let productPageOutput = factory.produceProductPageOutput() 39 | productPageOutput.onCart = { [weak self] in 40 | self?.showCart() 41 | } 42 | 43 | productPageOutput.onBack = { [weak self] in 44 | self?.router.popModule() 45 | } 46 | 47 | router.push(productPageOutput) 48 | } 49 | 50 | private func showCart() { 51 | 52 | let cartOutput = factory.produceCartOutput() 53 | cartOutput.onBay = { [weak self] in 54 | self?.router.popToRootModule(animated: true) 55 | } 56 | router.push(cartOutput) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Coordinator/FeedCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol FeedCoordinatorOutput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Configurator/CartConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CartModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? CartViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: CartViewController) { 21 | 22 | let presenter = CartPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = CartInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Configurator/CartInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CartModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var cartViewController: CartViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = CartModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: cartViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Interactor/CartInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class CartInteractor: CartInteractorInput { 10 | 11 | weak var output: CartInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Interactor/CartInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol CartInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Interactor/CartInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol CartInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Presenter/CartModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol CartModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Presenter/CartModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol CartModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/Presenter/CartPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class CartPresenter: CartModuleInput, CartViewOutput, CartInteractorOutput { 10 | 11 | weak var view: CartViewInput! 12 | weak var coordinator: CartViewCoordinatorOutput! 13 | var interactor: CartInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func bay() { 20 | coordinator.onBay?() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/View/CartCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartCell.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 30.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CartCell: UITableViewCell { 12 | 13 | // MARK: - IBOutlets 14 | 15 | @IBOutlet var labels: [UILabel]! 16 | @IBOutlet weak var photo: UIImageView! 17 | 18 | // MARK: - Life cycle 19 | 20 | override func awakeFromNib() { 21 | super.awakeFromNib() 22 | 23 | selectionStyle = .none 24 | 25 | labelsAppearance() 26 | photoAppearance() 27 | } 28 | 29 | // MARK: - Appearance 30 | 31 | private func labelsAppearance() { 32 | 33 | labels.forEach { (label) in 34 | label.backgroundColor = AppAppearance.UI.Label(tag: label.tag).color 35 | label.layer.cornerRadius = AppAppearance.UI.Label(tag: label.tag).radius 36 | label.layer.masksToBounds = true 37 | label.textAlignment = .left 38 | } 39 | } 40 | 41 | private func photoAppearance() { 42 | 43 | photo.image = #imageLiteral(resourceName: "photo").withRenderingMode(.alwaysTemplate) 44 | photo.tintColor = .lightRed 45 | photo.contentMode = .center 46 | photo.backgroundColor = AppAppearance.UI.Image.color 47 | photo.layer.cornerRadius = AppAppearance.UI.Image.radius 48 | photo.layer.masksToBounds = true 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/View/CartViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartViewController.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CartViewController: UIViewController, CartViewInput, CartViewCoordinatorOutput { 12 | 13 | // MARK: - Properties 14 | 15 | var output: CartViewOutput! 16 | 17 | // MARK: - IBOutlets 18 | 19 | @IBOutlet weak var label: UILabel! 20 | @IBOutlet weak var tableView: UITableView! 21 | @IBOutlet weak var button: UIButton! 22 | 23 | // MARK: - Life cycle 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | output.viewDidLoad() 28 | } 29 | 30 | 31 | // MARK: - CartViewInput 32 | 33 | func setupInitialState() { 34 | 35 | labelsAppearance() 36 | buttonAppearance() 37 | setupTableView() 38 | } 39 | 40 | // MARK: - CartViewCoordinatorOutput 41 | 42 | var onBay: (() -> Void)? 43 | 44 | // MARK: - Helpers 45 | 46 | private func setupTableView() { 47 | 48 | tableView.delegate = self 49 | tableView.dataSource = self 50 | tableView.tableFooterView = UIView(frame: .zero) 51 | tableView.separatorStyle = .none 52 | } 53 | 54 | // MARK: - Actions 55 | 56 | @IBAction func bay(_ sender: UIButton) { 57 | output.bay() 58 | } 59 | 60 | // MARK: - Appearance 61 | 62 | private func labelsAppearance() { 63 | 64 | label.backgroundColor = AppAppearance.UI.Label(tag: label.tag).color 65 | label.layer.cornerRadius = AppAppearance.UI.Label(tag: label.tag).radius 66 | label.layer.masksToBounds = true 67 | label.textAlignment = .left 68 | } 69 | 70 | private func buttonAppearance() { 71 | 72 | button.layer.cornerRadius = AppAppearance.UI.Button(tag: button.tag).radius 73 | button.layer.masksToBounds = true 74 | button.setTitleColor(.white, for: .normal) 75 | button.backgroundColor = AppAppearance.UI.Button(tag: button.tag).color 76 | button.setTitle("Bay", for: .normal) 77 | button.titleLabel?.font = UIFont.avertaCY(style: .semibold, size: 13) 78 | } 79 | } 80 | 81 | extension CartViewController: UITableViewDataSource { 82 | 83 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 84 | return 3 85 | } 86 | 87 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 88 | return tableView.dequeueReusableCell(withIdentifier: String(describing: CartCell.self), for: indexPath) 89 | } 90 | } 91 | 92 | extension CartViewController: UITableViewDelegate { 93 | 94 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 95 | return UITableViewAutomaticDimension 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/View/CartViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 09.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol CartViewCoordinatorOutput: Presentable { 10 | 11 | var onBay: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/View/CartViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol CartViewInput: class { 10 | 11 | /** 12 | @author Beslan Tularov 13 | Setup initial state of the view 14 | */ 15 | 16 | func setupInitialState() 17 | } 18 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Cart/View/CartViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol CartViewOutput { 10 | 11 | func viewDidLoad() 12 | func bay() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Configurator/FeedConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FeedModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? FeedViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: FeedViewController) { 21 | 22 | let presenter = FeedPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = FeedInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Configurator/FeedInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FeedModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var feedViewController: FeedViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = FeedModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: feedViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Interactor/FeedInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class FeedInteractor: FeedInteractorInput { 10 | 11 | weak var output: FeedInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Interactor/FeedInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol FeedInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Interactor/FeedInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol FeedInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Presenter/FeedModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol FeedModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Presenter/FeedModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol FeedModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/Presenter/FeedPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class FeedPresenter: FeedModuleInput, FeedViewOutput, FeedInteractorOutput { 10 | 11 | // MARK: - Properties 12 | 13 | weak var view: FeedViewInput! 14 | weak var coordinator: FeedViewCoordinatorOutput! 15 | var interactor: FeedInteractorInput! 16 | 17 | // MARK: - FeedInteractorOutput 18 | 19 | func viewDidLoad() { 20 | view.setupInitialState() 21 | } 22 | 23 | func didSelectItem() { 24 | coordinator.onItemSelected?() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/View/FeedCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedCell.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FeedCell: UICollectionViewCell { 12 | 13 | // MARK: - IBOutlets 14 | 15 | @IBOutlet weak var label: UILabel! 16 | @IBOutlet weak var photo: UIImageView! 17 | 18 | // MARK: - Life cycle 19 | 20 | override func awakeFromNib() { 21 | super.awakeFromNib() 22 | 23 | labelAppearance() 24 | photoAppearance() 25 | } 26 | 27 | // MARK: - Appearance 28 | 29 | private func labelAppearance() { 30 | 31 | label.backgroundColor = AppAppearance.UI.Label(tag: label.tag).color 32 | label.layer.cornerRadius = AppAppearance.UI.Label(tag: label.tag).radius 33 | label.layer.masksToBounds = true 34 | label.textAlignment = .left 35 | } 36 | 37 | private func photoAppearance() { 38 | 39 | photo.image = #imageLiteral(resourceName: "photo").withRenderingMode(.alwaysTemplate) 40 | photo.tintColor = .lightRed 41 | photo.contentMode = .center 42 | photo.backgroundColor = AppAppearance.UI.Image.color 43 | photo.layer.cornerRadius = AppAppearance.UI.Image.radius 44 | photo.layer.masksToBounds = true 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/View/FeedViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 07.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol FeedViewCoordinatorOutput: Presentable { 10 | 11 | var onItemSelected: ( () -> Void )? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/View/FeedViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol FeedViewInput: class { 10 | 11 | func setupInitialState() 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/Feed/View/FeedViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol FeedViewOutput { 10 | 11 | func viewDidLoad() 12 | func didSelectItem() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Configurator/ProductPageConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ProductPageModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? ProductPageViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: ProductPageViewController) { 21 | 22 | let presenter = ProductPagePresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = ProductPageInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Configurator/ProductPageInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ProductPageModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var productpageViewController: ProductPageViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = ProductPageModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: productpageViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Interactor/ProductPageInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class ProductPageInteractor: ProductPageInteractorInput { 10 | 11 | weak var output: ProductPageInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Interactor/ProductPageInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ProductPageInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Interactor/ProductPageInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ProductPageInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Presenter/ProductPageModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProductPageModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Presenter/ProductPageModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProductPageModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/Presenter/ProductPagePresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPagePresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class ProductPagePresenter: ProductPageModuleInput, ProductPageViewOutput, ProductPageInteractorOutput { 10 | 11 | weak var view: ProductPageViewInput! 12 | weak var coordinator: ProductPageViewCoordinatorOutput! 13 | var interactor: ProductPageInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func addToCart() { 20 | coordinator.onCart?() 21 | } 22 | 23 | func back() { 24 | coordinator.onBack?() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/View/ProductPageViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 07.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol ProductPageViewCoordinatorOutput: Presentable { 10 | 11 | var onCart: (() -> Void)? { get set } 12 | var onBack: (() -> Void)? { get set } 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/View/ProductPageViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProductPageViewInput: class { 10 | 11 | /** 12 | @author Beslan Tularov 13 | Setup initial state of the view 14 | */ 15 | 16 | func setupInitialState() 17 | } 18 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/View/ProductPageViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProductPageViewOutput { 10 | 11 | func viewDidLoad() 12 | func addToCart() 13 | func back() 14 | } 15 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/FeedFlow/Module/ProductPage/View/ProfileCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileCell.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 31.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ProfileCell: UITableViewCell { 12 | 13 | // MARK: - IBOutlets 14 | 15 | @IBOutlet var labels: [UILabel]! 16 | @IBOutlet weak var photo: UIImageView! 17 | @IBOutlet weak var field: UITextField! 18 | 19 | // MARK: - Life cycle 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | 24 | selectionStyle = .none 25 | 26 | photoAppearance() 27 | labelsAppearance() 28 | fieldsAppearance() 29 | } 30 | 31 | // MARK: - Appearance 32 | 33 | private func labelsAppearance() { 34 | 35 | labels.forEach { (label) in 36 | label.backgroundColor = AppAppearance.UI.Label(tag: label.tag).color 37 | label.layer.cornerRadius = AppAppearance.UI.Label(tag: label.tag).radius 38 | label.layer.masksToBounds = true 39 | label.textAlignment = .left 40 | } 41 | } 42 | 43 | private func fieldsAppearance() { 44 | 45 | field.backgroundColor = AppAppearance.UI.Filed.color 46 | field.layer.cornerRadius = AppAppearance.UI.Filed.radius 47 | field.layer.masksToBounds = true 48 | field.textAlignment = .center 49 | field.isEnabled = false 50 | } 51 | 52 | private func photoAppearance() { 53 | 54 | photo.image = #imageLiteral(resourceName: "photo").withRenderingMode(.alwaysTemplate) 55 | photo.tintColor = .lightRed 56 | photo.contentMode = .center 57 | photo.backgroundColor = AppAppearance.UI.Image.color 58 | photo.layer.cornerRadius = AppAppearance.UI.Image.radius 59 | photo.layer.masksToBounds = true 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Coordinator/OnboardingCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingCoordinator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class OnboardingCoordinator: BaseCoordinator, OnboardingCoordinatorOutput { 10 | 11 | // MARK: - OnboardingCoordinatorOutput 12 | 13 | var finishFlow: (() -> Void)? 14 | 15 | private let factory: OnboardingFlowFactory 16 | private let router: Router 17 | 18 | init(router: Router, factory: OnboardingFlowFactory) { 19 | 20 | self.factory = factory 21 | self.router = router 22 | } 23 | 24 | // MARK: - BaseCoordinator 25 | 26 | override func start() { 27 | showOnboarding() 28 | } 29 | 30 | // MARK: - Flow's controllers 31 | 32 | private func showOnboarding() { 33 | let onboardingOutput = factory.produceOnboardingOutput() 34 | onboardingOutput.onNext = { [weak self] in 35 | 36 | self?.finishFlow?() 37 | } 38 | 39 | router.setRootModule(onboardingOutput, hideBar: true) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Coordinator/OnboardingCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol OnboardingCoordinatorOutput: class { 10 | 11 | var finishFlow: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Configurator/OnboardingConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class OnboardingModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? OnboardingViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: OnboardingViewController) { 21 | 22 | let presenter = OnboardingPresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = OnboardingInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Configurator/OnboardingInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class OnboardingModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var onboardingViewController: OnboardingViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = OnboardingModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: onboardingViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Interactor/OnboardingInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class OnboardingInteractor: OnboardingInteractorInput { 10 | 11 | weak var output: OnboardingInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Interactor/OnboardingInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol OnboardingInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Interactor/OnboardingInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol OnboardingInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Presenter/OnboardingModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol OnboardingModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Presenter/OnboardingModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol OnboardingModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/Presenter/OnboardingPresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingPresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class OnboardingPresenter: OnboardingModuleInput, OnboardingViewOutput, OnboardingInteractorOutput { 10 | 11 | weak var view: OnboardingViewInput! 12 | weak var coordinator: OnboardingViewCoordinatorOutput! 13 | var interactor: OnboardingInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func onNextTap() { 20 | coordinator.onNext?() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/View/OnboardingViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 02.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol OnboardingViewCoordinatorOutput: Presentable { 10 | 11 | var onNext: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/View/OnboardingViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol OnboardingViewInput: class { 10 | 11 | func setupInitialState() 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/OnboardingFlow/Module/Onboarding/View/OnboardingViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol OnboardingViewOutput { 10 | 11 | func viewDidLoad() 12 | func onNextTap() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Coordinator/ProfileCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileCoordinator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class ProfileCoordinator: BaseCoordinator, ProfileCoordinatorOutput { 10 | 11 | private let factory: ProfileFlowFactory 12 | private let router: Router 13 | 14 | init(router: Router, factory: ProfileFlowFactory) { 15 | 16 | self.factory = factory 17 | self.router = router 18 | } 19 | 20 | // MARK: - BaseCoordinator 21 | 22 | override func start() { 23 | showProfile() 24 | } 25 | 26 | // MARK: - ProfileCoordinatorOutput 27 | 28 | var finishFlow: (() -> Void)? 29 | 30 | private func showProfile() { 31 | 32 | let profileOutput = factory.produceProfileOutput() 33 | profileOutput.onExit = { [weak self] in 34 | self?.finishFlow?() 35 | } 36 | router.setRootModule(profileOutput, hideBar: true) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Coordinator/ProfileCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ProfileCoordinatorOutput { 12 | 13 | var finishFlow: (() -> Void)? { get set } 14 | } 15 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Configurator/ProfileConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileConfigurator.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ProfileModuleConfigurator { 12 | 13 | func configureModuleForViewInput(viewInput: UIViewController) { 14 | 15 | if let viewController = viewInput as? ProfileViewController { 16 | configure(viewController: viewController) 17 | } 18 | } 19 | 20 | private func configure(viewController: ProfileViewController) { 21 | 22 | let presenter = ProfilePresenter() 23 | presenter.view = viewController 24 | presenter.coordinator = viewController 25 | 26 | let interactor = ProfileInteractor() 27 | interactor.output = presenter 28 | 29 | presenter.interactor = interactor 30 | viewController.output = presenter 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Configurator/ProfileInitializer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileInitializer.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ProfileModuleInitializer: NSObject { 12 | 13 | //Connect with object on storyboard 14 | @IBOutlet weak var profileViewController: ProfileViewController! 15 | 16 | override func awakeFromNib() { 17 | 18 | let configurator = ProfileModuleConfigurator() 19 | configurator.configureModuleForViewInput(viewInput: profileViewController) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Interactor/ProfileInteractor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileInteractor.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class ProfileInteractor: ProfileInteractorInput { 10 | 11 | weak var output: ProfileInteractorOutput! 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Interactor/ProfileInteractorInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileInteractorInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ProfileInteractorInput { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Interactor/ProfileInteractorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileInteractorOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol ProfileInteractorOutput: class { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Presenter/ProfileModuleInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileModuleInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProfileModuleInput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Presenter/ProfileModuleOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileModuleOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProfileModuleOutput: class { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/Presenter/ProfilePresenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfilePresenter.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | class ProfilePresenter: ProfileModuleInput, ProfileViewOutput, ProfileInteractorOutput { 10 | 11 | weak var view: ProfileViewInput! 12 | weak var coordinator: ProfileViewCoordinatorOutput! 13 | var interactor: ProfileInteractorInput! 14 | 15 | func viewDidLoad() { 16 | view.setupInitialState() 17 | } 18 | 19 | func exit() { 20 | coordinator.onExit?() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/View/ProfileViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileViewController.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ProfileViewController: UIViewController, ProfileViewInput, ProfileViewCoordinatorOutput { 12 | 13 | // MARK: - Properties 14 | 15 | var output: ProfileViewOutput! 16 | 17 | // MARK: - IBOutlets 18 | 19 | @IBOutlet weak var photo: UIImageView! 20 | @IBOutlet weak var field: UITextField! 21 | @IBOutlet weak var button: UIButton! 22 | @IBOutlet var labels: [UILabel]! 23 | 24 | // MARK: - Life cycle 25 | 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | 29 | output.viewDidLoad() 30 | } 31 | 32 | 33 | // MARK: - ProfileViewInput 34 | 35 | func setupInitialState() { 36 | 37 | photoAppearance() 38 | fieldAppearance() 39 | labelsAppearance() 40 | buttonAppearance() 41 | } 42 | 43 | // MARK: - ProfileViewCoordinatorOutput 44 | 45 | var onExit: (() -> Void)? 46 | 47 | // MARK: - Appearance 48 | 49 | private func photoAppearance() { 50 | 51 | photo.image = #imageLiteral(resourceName: "photo") 52 | photo.contentMode = .center 53 | photo.backgroundColor = AppAppearance.UI.Image.color 54 | photo.layer.cornerRadius = photo.frame.width / 2 55 | photo.layer.masksToBounds = true 56 | } 57 | 58 | private func fieldAppearance() { 59 | 60 | field.backgroundColor = AppAppearance.UI.Filed.color 61 | field.layer.cornerRadius = AppAppearance.UI.Filed.radius 62 | field.layer.masksToBounds = true 63 | field.textAlignment = .center 64 | field.isEnabled = false 65 | } 66 | 67 | private func labelsAppearance() { 68 | 69 | labels.forEach { (label) in 70 | 71 | label.backgroundColor = AppAppearance.UI.Label(tag: label.tag).color 72 | label.layer.cornerRadius = AppAppearance.UI.Label(tag: label.tag).radius 73 | label.layer.masksToBounds = true 74 | label.textAlignment = .left 75 | } 76 | } 77 | 78 | private func buttonAppearance() { 79 | 80 | button.layer.cornerRadius = AppAppearance.UI.Button(tag: button.tag).radius 81 | button.layer.masksToBounds = true 82 | button.setTitleColor(.white, for: .normal) 83 | button.backgroundColor = AppAppearance.UI.Button(tag: button.tag).color 84 | button.setTitle("Exit", for: .normal) 85 | button.titleLabel?.font = UIFont.avertaCY(style: .semibold, size: 13) 86 | } 87 | 88 | // MARK: - Actions 89 | 90 | @IBAction func exit(_ sender: UIButton) { 91 | output.exit() 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/View/ProfileViewCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileViewCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 09.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol ProfileViewCoordinatorOutput: Presentable { 10 | 11 | var onExit: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/View/ProfileViewInput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileViewInput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProfileViewInput: class { 10 | 11 | /** 12 | @author Beslan Tularov 13 | Setup initial state of the view 14 | */ 15 | 16 | func setupInitialState() 17 | } 18 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/ProfileFlow/Module/Profile/View/ProfileViewOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileViewOutput.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | protocol ProfileViewOutput { 10 | 11 | func viewDidLoad() 12 | func exit() 13 | } 14 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/TabbarFlow/Coordinator/TabbarCoordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarCoordinator.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 07.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TabbarCoordinator: BaseCoordinator, TabbarCoordinatorOutput { 12 | 13 | var finishFlow: (() -> Void)? 14 | 15 | private let tabbarOutput: FlowTabbarCoordinatorOutput 16 | private let coordinatorFactory: CoordinatorFactory 17 | 18 | init(tabbarOutput: FlowTabbarCoordinatorOutput, coordinatorFactory: CoordinatorFactory) { 19 | 20 | self.tabbarOutput = tabbarOutput 21 | self.coordinatorFactory = coordinatorFactory 22 | } 23 | 24 | override func start() { 25 | 26 | tabbarOutput.onFeedFlow = runFeedFlow() 27 | tabbarOutput.onProfileFlow = runProfileFlow() 28 | } 29 | 30 | private func runFeedFlow() -> ((UINavigationController) -> ()) { 31 | 32 | return { navigationController in 33 | 34 | let feedCoordinator = self.coordinatorFactory.produceFeedCoordinator(navigationController: navigationController, flowFactory: FlowFactoryImp()) 35 | feedCoordinator.start() 36 | self.addDependency(feedCoordinator) 37 | } 38 | } 39 | 40 | private func runProfileFlow() -> ((UINavigationController) -> ()) { 41 | 42 | return { navigationController in 43 | 44 | var profileCoordinator = self.coordinatorFactory.produceProfileCoordinator(navigationController: navigationController, flowFactory: FlowFactoryImp()) 45 | profileCoordinator.finishFlow = { [weak self] in 46 | 47 | self?.finishFlow?() 48 | } 49 | profileCoordinator.start() 50 | self.addDependency(profileCoordinator) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/TabbarFlow/Coordinator/TabbarCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 10.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | protocol TabbarCoordinatorOutput: class { 10 | 11 | var finishFlow: (() -> Void)? { get set } 12 | } 13 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/TabbarFlow/Module/FlowTabbarController/FlowTabbar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowTabbar.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 08.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FlowTabbar: UITabBar { 12 | 13 | required init?(coder aDecoder: NSCoder) { 14 | super.init(coder: aDecoder) 15 | 16 | isTranslucent = false 17 | shadowImage = UIImage() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/TabbarFlow/Module/FlowTabbarController/FlowTabbarController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowTabbarController.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 07.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FlowTabbarController: UITabBarController , UITabBarControllerDelegate, FlowTabbarCoordinatorOutput { 12 | 13 | var onFeedFlow: ((UINavigationController) -> ())? 14 | var onProfileFlow: ((UINavigationController) -> ())? 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | startRootFlows() 19 | } 20 | 21 | func startRootFlows() { 22 | 23 | if let controller = viewControllers?[0] as? UINavigationController { 24 | onFeedFlow?(controller) 25 | } 26 | 27 | if let controller = viewControllers?[1] as? UINavigationController { 28 | onProfileFlow?(controller) 29 | } 30 | } 31 | 32 | override func viewDidLayoutSubviews() { 33 | super.viewDidLayoutSubviews() 34 | setItemsImage() 35 | removeTabbarItemsText() 36 | } 37 | 38 | private func removeTabbarItemsText() { 39 | 40 | tabBar.items?.forEach { 41 | 42 | $0.title = "" 43 | $0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) 44 | } 45 | } 46 | 47 | private func setItemsImage() { 48 | 49 | tabBar.items?.forEach({ (item) in 50 | item.image = #imageLiteral(resourceName: "oval") 51 | item.selectedImage = #imageLiteral(resourceName: "selectedOval") 52 | }) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/Flows/TabbarFlow/Module/FlowTabbarController/FlowTabbarCoordinatorOutput.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowTabbarCoordinatorOutput.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 07.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit.UINavigationController 10 | 11 | protocol FlowTabbarCoordinatorOutput: class { 12 | 13 | var onFeedFlow: ((UINavigationController) -> ())? { get set } 14 | var onProfileFlow: ((UINavigationController) -> ())? { get set } 15 | } 16 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/ReuseableComponents/FlowNavigationController/FlowNavigationController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Flow/PresentationLayer/ReuseableComponents/FlowNavigationController/FlowNavigationController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowNavigationController.swift 3 | // Flow 4 | // 5 | // Created by workmachine on 01.08.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FlowNavigationController: UINavigationController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | navigationBar.isTranslucent = false 16 | navigationBar.shadowImage = UIImage() 17 | } 18 | 19 | override func popViewController(animated: Bool) -> UIViewController? { 20 | if #available(iOS 10.0, *) { 21 | let generator = UIImpactFeedbackGenerator(style: .light) 22 | generator.impactOccurred() 23 | } 24 | let popViewController = super.popViewController(animated: animated) 25 | return popViewController 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/App_Store_iOS_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/App_Store_iOS_1024.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/Apple_Watch_App_Store_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/Apple_Watch_App_Store_1024.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_29@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_29@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_40@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_44.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_86.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_98.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_98.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_Notification_Center_24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_Notification_Center_24@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_Notification_Center_27.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_Apple_Watch_Notification_Center_27.5@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_CarPay_60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_CarPay_60@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_CarPay_60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_CarPay_60@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_29.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_29@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_40.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_40@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_76.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_76@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_Notifications_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_Notifications_20.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_Notifications_20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_Notifications_20@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_Pro_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPad_Pro_83.5@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_29@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_29@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_40@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_40@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_60@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_60@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_Notification_20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_Notification_20@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_Notification_20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/AppIcon.appiconset/icon_iPhone_Notification_20@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/oval.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "selectedOval.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "selectedOval@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "selectedOval@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/oval.imageset/selectedOval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/oval.imageset/selectedOval.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/oval.imageset/selectedOval@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/oval.imageset/selectedOval@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/oval.imageset/selectedOval@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/oval.imageset/selectedOval@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/page.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "page.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "page@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "page@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/page.imageset/page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/page.imageset/page.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/page.imageset/page@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/page.imageset/page@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/page.imageset/page@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/page.imageset/page@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/photo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "photo.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "photo@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "photo@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/photo.imageset/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/photo.imageset/photo.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/photo.imageset/photo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/photo.imageset/photo@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/photo.imageset/photo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/photo.imageset/photo@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selecedPage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "selecedPage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "selecedPage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "selecedPage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selecedPage.imageset/selecedPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/selecedPage.imageset/selecedPage.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selecedPage.imageset/selecedPage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/selecedPage.imageset/selecedPage@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selecedPage.imageset/selecedPage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/selecedPage.imageset/selecedPage@3x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selectedOval.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "oval.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "oval@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "oval@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "original" 25 | } 26 | } -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selectedOval.imageset/oval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/selectedOval.imageset/oval.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selectedOval.imageset/oval@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/selectedOval.imageset/oval@2x.png -------------------------------------------------------------------------------- /Flow/Resources/Assets.xcassets/selectedOval.imageset/oval@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tularovbeslan/Flow/ea55ee1e680e0d9d1bccff8f64e49d72310d52eb/Flow/Resources/Assets.xcassets/selectedOval.imageset/oval@3x.png -------------------------------------------------------------------------------- /Flow/Supporting Files/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Flow/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | FlowNavigationController 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /FlowTests/Cart/Configurator/CartConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CartModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = CartViewControllerMock() 27 | let configurator = CartModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "CartViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is CartPresenter, "output is not CartPresenter") 35 | 36 | let presenter: CartPresenter = viewController.output as! CartPresenter 37 | XCTAssertNotNil(presenter.view, "view in CartPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in CartPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is CartRouter, "router is not CartRouter") 40 | 41 | let interactor: CartInteractor = presenter.interactor as! CartInteractor 42 | XCTAssertNotNil(interactor.output, "output in CartInteractor is nil after configuration") 43 | } 44 | 45 | class CartViewControllerMock: CartViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/Cart/Coordinator/CartCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CartCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/Cart/Interactor/CartInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CartInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: CartInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/Cart/Presenter/CartPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CartPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: CartInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: CartRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: CartViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/Cart/View/CartViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CartViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class CartViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/Feed/Configurator/FeedConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FeedModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = FeedViewControllerMock() 27 | let configurator = FeedModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "FeedViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is FeedPresenter, "output is not FeedPresenter") 35 | 36 | let presenter: FeedPresenter = viewController.output as! FeedPresenter 37 | XCTAssertNotNil(presenter.view, "view in FeedPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in FeedPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is FeedRouter, "router is not FeedRouter") 40 | 41 | let interactor: FeedInteractor = presenter.interactor as! FeedInteractor 42 | XCTAssertNotNil(interactor.output, "output in FeedInteractor is nil after configuration") 43 | } 44 | 45 | class FeedViewControllerMock: FeedViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/Feed/Coordinator/FeedCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FeedCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/Feed/Interactor/FeedInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FeedInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: FeedInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/Feed/Presenter/FeedPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FeedPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: FeedInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: FeedRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: FeedViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/Feed/View/FeedViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeedViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FeedViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/FlowTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowTests.swift 3 | // FlowTests 4 | // 5 | // Created by workmachine on 25.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Flow 11 | 12 | class FlowTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /FlowTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /FlowTests/Onboarding/Configurator/OnboardingConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class OnboardingModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = OnboardingViewControllerMock() 27 | let configurator = OnboardingModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "OnboardingViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is OnboardingPresenter, "output is not OnboardingPresenter") 35 | 36 | let presenter: OnboardingPresenter = viewController.output as! OnboardingPresenter 37 | XCTAssertNotNil(presenter.view, "view in OnboardingPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in OnboardingPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is OnboardingRouter, "router is not OnboardingRouter") 40 | 41 | let interactor: OnboardingInteractor = presenter.interactor as! OnboardingInteractor 42 | XCTAssertNotNil(interactor.output, "output in OnboardingInteractor is nil after configuration") 43 | } 44 | 45 | class OnboardingViewControllerMock: OnboardingViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/Onboarding/Coordinator/OnboardingCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class OnboardingCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/Onboarding/Interactor/OnboardingInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class OnboardingInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: OnboardingInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/Onboarding/Presenter/OnboardingPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class OnboardingPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: OnboardingInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: OnboardingRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: OnboardingViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/Onboarding/View/OnboardingViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class OnboardingViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/PasswordRecovery/Configurator/PasswordRecoveryConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PasswordRecoveryModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = PasswordRecoveryViewControllerMock() 27 | let configurator = PasswordRecoveryModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "PasswordRecoveryViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is PasswordRecoveryPresenter, "output is not PasswordRecoveryPresenter") 35 | 36 | let presenter: PasswordRecoveryPresenter = viewController.output as! PasswordRecoveryPresenter 37 | XCTAssertNotNil(presenter.view, "view in PasswordRecoveryPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in PasswordRecoveryPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is PasswordRecoveryRouter, "router is not PasswordRecoveryRouter") 40 | 41 | let interactor: PasswordRecoveryInteractor = presenter.interactor as! PasswordRecoveryInteractor 42 | XCTAssertNotNil(interactor.output, "output in PasswordRecoveryInteractor is nil after configuration") 43 | } 44 | 45 | class PasswordRecoveryViewControllerMock: PasswordRecoveryViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/PasswordRecovery/Coordinator/PasswordRecoveryCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PasswordRecoveryCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/PasswordRecovery/Interactor/PasswordRecoveryInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PasswordRecoveryInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: PasswordRecoveryInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/PasswordRecovery/Presenter/PasswordRecoveryPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PasswordRecoveryPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: PasswordRecoveryInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: PasswordRecoveryRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: PasswordRecoveryViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/PasswordRecovery/View/PasswordRecoveryViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRecoveryViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PasswordRecoveryViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/ProductPage/Configurator/ProductPageConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProductPageModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = ProductPageViewControllerMock() 27 | let configurator = ProductPageModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "ProductPageViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is ProductPagePresenter, "output is not ProductPagePresenter") 35 | 36 | let presenter: ProductPagePresenter = viewController.output as! ProductPagePresenter 37 | XCTAssertNotNil(presenter.view, "view in ProductPagePresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in ProductPagePresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is ProductPageRouter, "router is not ProductPageRouter") 40 | 41 | let interactor: ProductPageInteractor = presenter.interactor as! ProductPageInteractor 42 | XCTAssertNotNil(interactor.output, "output in ProductPageInteractor is nil after configuration") 43 | } 44 | 45 | class ProductPageViewControllerMock: ProductPageViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/ProductPage/Coordinator/ProductPageCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProductPageCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/ProductPage/Interactor/ProductPageInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProductPageInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: ProductPageInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/ProductPage/Presenter/ProductPagePresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPagePresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProductPagePresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: ProductPageInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: ProductPageRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: ProductPageViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/ProductPage/View/ProductPageViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductPageViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProductPageViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/Profile/Configurator/ProfileConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProfileModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = ProfileViewControllerMock() 27 | let configurator = ProfileModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "ProfileViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is ProfilePresenter, "output is not ProfilePresenter") 35 | 36 | let presenter: ProfilePresenter = viewController.output as! ProfilePresenter 37 | XCTAssertNotNil(presenter.view, "view in ProfilePresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in ProfilePresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is ProfileRouter, "router is not ProfileRouter") 40 | 41 | let interactor: ProfileInteractor = presenter.interactor as! ProfileInteractor 42 | XCTAssertNotNil(interactor.output, "output in ProfileInteractor is nil after configuration") 43 | } 44 | 45 | class ProfileViewControllerMock: ProfileViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/Profile/Coordinator/ProfileCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProfileCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/Profile/Interactor/ProfileInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProfileInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: ProfileInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/Profile/Presenter/ProfilePresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfilePresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProfilePresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: ProfileInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: ProfileRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: ProfileViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/Profile/View/ProfileViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ProfileViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/SingIn/Configurator/SingInConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingInModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = SingInViewControllerMock() 27 | let configurator = SingInModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "SingInViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is SingInPresenter, "output is not SingInPresenter") 35 | 36 | let presenter: SingInPresenter = viewController.output as! SingInPresenter 37 | XCTAssertNotNil(presenter.view, "view in SingInPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in SingInPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is SingInRouter, "router is not SingInRouter") 40 | 41 | let interactor: SingInInteractor = presenter.interactor as! SingInInteractor 42 | XCTAssertNotNil(interactor.output, "output in SingInInteractor is nil after configuration") 43 | } 44 | 45 | class SingInViewControllerMock: SingInViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/SingIn/Coordinator/SingInCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingInCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/SingIn/Interactor/SingInInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingInInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: SingInInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/SingIn/Presenter/SingInPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingInPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: SingInInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: SingInRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: SingInViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/SingIn/View/SingInViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingInViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingInViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/SingUp/Configurator/SingUpConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingUpModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = SingUpViewControllerMock() 27 | let configurator = SingUpModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "SingUpViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is SingUpPresenter, "output is not SingUpPresenter") 35 | 36 | let presenter: SingUpPresenter = viewController.output as! SingUpPresenter 37 | XCTAssertNotNil(presenter.view, "view in SingUpPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in SingUpPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is SingUpRouter, "router is not SingUpRouter") 40 | 41 | let interactor: SingUpInteractor = presenter.interactor as! SingUpInteractor 42 | XCTAssertNotNil(interactor.output, "output in SingUpInteractor is nil after configuration") 43 | } 44 | 45 | class SingUpViewControllerMock: SingUpViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/SingUp/Coordinator/SingUpCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingUpCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/SingUp/Interactor/SingUpInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingUpInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: SingUpInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/SingUp/Presenter/SingUpPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingUpPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: SingUpInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: SingUpRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: SingUpViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/SingUp/View/SingUpViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingUpViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SingUpViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowTests/Terms/Configurator/TermsConfiguratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsConfiguratorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TermsModuleConfiguratorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testConfigureModuleForViewController() { 24 | 25 | //given 26 | let viewController = TermsViewControllerMock() 27 | let configurator = TermsModuleConfigurator() 28 | 29 | //when 30 | configurator.configureModuleForViewInput(viewInput: viewController) 31 | 32 | //then 33 | XCTAssertNotNil(viewController.output, "TermsViewController is nil after configuration") 34 | XCTAssertTrue(viewController.output is TermsPresenter, "output is not TermsPresenter") 35 | 36 | let presenter: TermsPresenter = viewController.output as! TermsPresenter 37 | XCTAssertNotNil(presenter.view, "view in TermsPresenter is nil after configuration") 38 | XCTAssertNotNil(presenter.router, "router in TermsPresenter is nil after configuration") 39 | XCTAssertTrue(presenter.router is TermsRouter, "router is not TermsRouter") 40 | 41 | let interactor: TermsInteractor = presenter.interactor as! TermsInteractor 42 | XCTAssertNotNil(interactor.output, "output in TermsInteractor is nil after configuration") 43 | } 44 | 45 | class TermsViewControllerMock: TermsViewController { 46 | 47 | var setupInitialStateDidCall = false 48 | 49 | override func setupInitialState() { 50 | setupInitialStateDidCall = true 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /FlowTests/Terms/Coordinator/TermsCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsCoordinatorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TermsCoordinatorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlowTests/Terms/Interactor/TermsInteractorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsInteractorTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TermsInteractorTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockPresenter: TermsInteractorOutput { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FlowTests/Terms/Presenter/TermsPresenterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsPresenterTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TermsPresenterTest: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | class MockInteractor: TermsInteractorInput { 24 | 25 | } 26 | 27 | class MockRouter: TermsRouterInput { 28 | 29 | } 30 | 31 | class MockViewController: TermsViewInput { 32 | 33 | func setupInitialState() { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FlowTests/Terms/View/TermsViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TermsViewTests.swift 3 | // Flow 4 | // 5 | // Created by Beslan Tularov on 27/07/2018. 6 | // Copyright © 2018 Flow. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class TermsViewTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /FlowUITests/FlowUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FlowUITests.swift 3 | // FlowUITests 4 | // 5 | // Created by workmachine on 25.07.2018. 6 | // Copyright © 2018 Beslan Tularov Ramazanovich. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class FlowUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /FlowUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Beslan Tularov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | 2 | use_frameworks! 3 | 4 | target 'Flow' do 5 | pod 'FSPagerView', :git => 'https://github.com/tularovbeslan/FSPagerView' 6 | pod 'PWSwitch', :git => 'https://github.com/tularovbeslan/PWSwitch.git' 7 | end 8 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FSPagerView (0.7.1) 3 | - PWSwitch (1.1.0) 4 | 5 | DEPENDENCIES: 6 | - FSPagerView (from `https://github.com/tularovbeslan/FSPagerView`) 7 | - PWSwitch (from `https://github.com/tularovbeslan/PWSwitch.git`) 8 | 9 | EXTERNAL SOURCES: 10 | FSPagerView: 11 | :git: https://github.com/tularovbeslan/FSPagerView 12 | PWSwitch: 13 | :git: https://github.com/tularovbeslan/PWSwitch.git 14 | 15 | CHECKOUT OPTIONS: 16 | FSPagerView: 17 | :commit: 4a50191fccde27fcca60087845b935d98f2a7e80 18 | :git: https://github.com/tularovbeslan/FSPagerView 19 | PWSwitch: 20 | :commit: c4fcae6f79aacda382fc1a98b7256dbc9e4f17db 21 | :git: https://github.com/tularovbeslan/PWSwitch.git 22 | 23 | SPEC CHECKSUMS: 24 | FSPagerView: 92ccac76ce3886f3936d8b02ad10f1185584b38b 25 | PWSwitch: aadea992acf22aee2408ee8eddad3b3260b1f2d4 26 | 27 | PODFILE CHECKSUM: 94baba5a386f02375b99132761e2b5b89eb3f9bd 28 | 29 | COCOAPODS: 1.6.0.beta.2 30 | -------------------------------------------------------------------------------- /Pods/FSPagerView/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 FSPagerView (https://github.com/WenchaoD/FSPagerView) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/FSPagerView/Sources/FSPagerCollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FSPagerViewCollectionView.swift 3 | // FSPagerView 4 | // 5 | // Created by Wenchao Ding on 24/12/2016. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | // 1. Reject -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] 9 | // 2. Group initialized features 10 | 11 | import UIKit 12 | 13 | class FSPagerViewCollectionView: UICollectionView { 14 | 15 | fileprivate var pagerView: FSPagerView? { 16 | return self.superview?.superview as? FSPagerView 17 | } 18 | 19 | #if !os(tvOS) 20 | override var scrollsToTop: Bool { 21 | set { 22 | super.scrollsToTop = false 23 | } 24 | get { 25 | return false 26 | } 27 | } 28 | #endif 29 | 30 | override var contentInset: UIEdgeInsets { 31 | set { 32 | super.contentInset = .zero 33 | if (newValue.top > 0) { 34 | let contentOffset = CGPoint(x:self.contentOffset.x, y:self.contentOffset.y+newValue.top); 35 | self.contentOffset = contentOffset 36 | } 37 | } 38 | get { 39 | return super.contentInset 40 | } 41 | } 42 | 43 | override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { 44 | super.init(frame: frame, collectionViewLayout: layout) 45 | self.commonInit() 46 | } 47 | 48 | required init?(coder aDecoder: NSCoder) { 49 | super.init(coder: aDecoder) 50 | self.commonInit() 51 | } 52 | 53 | fileprivate func commonInit() { 54 | self.contentInset = .zero 55 | self.decelerationRate = UIScrollViewDecelerationRateFast 56 | self.showsVerticalScrollIndicator = false 57 | self.showsHorizontalScrollIndicator = false 58 | if #available(iOS 10.0, *) { 59 | self.isPrefetchingEnabled = false 60 | } 61 | if #available(iOS 11.0, *) { 62 | self.contentInsetAdjustmentBehavior = .never 63 | } 64 | #if !os(tvOS) 65 | self.scrollsToTop = false 66 | self.isPagingEnabled = false 67 | #endif 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Pods/FSPagerView/Sources/FSPagerViewLayoutAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FSPagerViewLayoutAttributes.swift 3 | // FSPagerViewExample 4 | // 5 | // Created by Wenchao Ding on 26/02/2017. 6 | // Copyright © 2017 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class FSPagerViewLayoutAttributes: UICollectionViewLayoutAttributes { 12 | 13 | open var position: CGFloat = 0 14 | 15 | open override func isEqual(_ object: Any?) -> Bool { 16 | guard let object = object as? FSPagerViewLayoutAttributes else { 17 | return false 18 | } 19 | var isEqual = super.isEqual(object) 20 | isEqual = isEqual && (self.position == object.position) 21 | return isEqual 22 | } 23 | 24 | open override func copy(with zone: NSZone? = nil) -> Any { 25 | let copy = super.copy(with: zone) as! FSPagerViewLayoutAttributes 26 | copy.position = self.position 27 | return copy 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Pods/Local Podspecs/FSPagerView.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FSPagerView", 3 | "version": "0.7.1", 4 | "summary": "FSPagerView is an elegant Screen Slide Library for making Banner、Product Show、Welcome/Guide Pages、Screen/ViewController Sliders.", 5 | "homepage": "https://github.com/WenchaoD/FSPagerView", 6 | "screenshots": "https://cloud.githubusercontent.com/assets/5186464/22686432/19b567f8-ed5f-11e6-885d-bd660c98b507.gif", 7 | "license": "MIT", 8 | "authors": { 9 | "Wenchao Ding": "f33chobits@gmail.com" 10 | }, 11 | "source": { 12 | "git": "https://github.com/WenchaoD/FSPagerView.git", 13 | "tag": "0.7.1" 14 | }, 15 | "platforms": { 16 | "ios": "8.0" 17 | }, 18 | "requires_arc": true, 19 | "frameworks": "UIKit", 20 | "source_files": "Sources/*.swift" 21 | } 22 | -------------------------------------------------------------------------------- /Pods/Local Podspecs/PWSwitch.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PWSwitch", 3 | "version": "1.1.0", 4 | "summary": "Highly customizable UISwitch built with CALayers and CAAnimations", 5 | "description": "Custom UISwitch implementation designed for those who want more control over the looks of the component. Built with CALayers and CAAnimations for finer control and nice interaction visual effects.", 6 | "homepage": "https://github.com/Shaninnik/PWSwitch", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Nikita Shanin": "shaninnik@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/Shaninnik/PWSwitch.git", 16 | "tag": "1.1.0" 17 | }, 18 | "platforms": { 19 | "ios": "8.0" 20 | }, 21 | "source_files": "PWSwitch/Classes/**/*" 22 | } 23 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FSPagerView (0.7.1) 3 | - PWSwitch (1.1.0) 4 | 5 | DEPENDENCIES: 6 | - FSPagerView (from `https://github.com/tularovbeslan/FSPagerView`) 7 | - PWSwitch (from `https://github.com/tularovbeslan/PWSwitch.git`) 8 | 9 | EXTERNAL SOURCES: 10 | FSPagerView: 11 | :git: https://github.com/tularovbeslan/FSPagerView 12 | PWSwitch: 13 | :git: https://github.com/tularovbeslan/PWSwitch.git 14 | 15 | CHECKOUT OPTIONS: 16 | FSPagerView: 17 | :commit: 4a50191fccde27fcca60087845b935d98f2a7e80 18 | :git: https://github.com/tularovbeslan/FSPagerView 19 | PWSwitch: 20 | :commit: c4fcae6f79aacda382fc1a98b7256dbc9e4f17db 21 | :git: https://github.com/tularovbeslan/PWSwitch.git 22 | 23 | SPEC CHECKSUMS: 24 | FSPagerView: 92ccac76ce3886f3936d8b02ad10f1185584b38b 25 | PWSwitch: aadea992acf22aee2408ee8eddad3b3260b1f2d4 26 | 27 | PODFILE CHECKSUM: 94baba5a386f02375b99132761e2b5b89eb3f9bd 28 | 29 | COCOAPODS: 1.6.0.beta.2 30 | -------------------------------------------------------------------------------- /Pods/PWSwitch/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Nikita Shanin 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/FSPagerView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.7.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/FSPagerView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FSPagerView : NSObject 3 | @end 4 | @implementation PodsDummy_FSPagerView 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/FSPagerView-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/FSPagerView-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double FSPagerViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char FSPagerViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/FSPagerView.modulemap: -------------------------------------------------------------------------------- 1 | framework module FSPagerView { 2 | umbrella header "FSPagerView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/FSPagerView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FSPagerView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "UIKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FSPagerView 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FSPagerView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.7.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/PWSwitch-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/PWSwitch-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_PWSwitch : NSObject 3 | @end 4 | @implementation PodsDummy_PWSwitch 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/PWSwitch-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/PWSwitch-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double PWSwitchVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char PWSwitchVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/PWSwitch.modulemap: -------------------------------------------------------------------------------- 1 | framework module PWSwitch { 2 | umbrella header "PWSwitch-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/PWSwitch/PWSwitch.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PWSwitch 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/PWSwitch 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FSPagerView 5 | 6 | Copyright (c) 2017 FSPagerView (https://github.com/WenchaoD/FSPagerView) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | 27 | ## PWSwitch 28 | 29 | Copyright (c) 2016 Nikita Shanin 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | 49 | Generated by CocoaPods - https://cocoapods.org 50 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Flow : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Flow 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_FlowVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_FlowVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSPagerView" "${PODS_CONFIGURATION_BUILD_DIR}/PWSwitch" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSPagerView/FSPagerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PWSwitch/PWSwitch.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "FSPagerView" -framework "PWSwitch" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Flow { 2 | umbrella header "Pods-Flow-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Flow/Pods-Flow.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSPagerView" "${PODS_CONFIGURATION_BUILD_DIR}/PWSwitch" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSPagerView/FSPagerView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PWSwitch/PWSwitch.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "FSPagerView" -framework "PWSwitch" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Rambafile: -------------------------------------------------------------------------------- 1 | ### Headers settings 2 | company: Flow 3 | 4 | ### Xcode project settings 5 | project_name: Flow 6 | xcodeproj_path: Flow.xcodeproj 7 | 8 | ### Code generation settings section 9 | # The main project target name 10 | project_target: Flow 11 | 12 | # The file path for new modules 13 | project_file_path: Flow/PresentationLayer/ 14 | 15 | # The Xcode group path to new modules 16 | project_group_path: Flow/PresentationLayer/ 17 | 18 | ### Tests generation settings section 19 | # The tests target name 20 | test_target: FlowTests 21 | 22 | # The file path for new tests 23 | test_file_path: FlowTests/ 24 | 25 | # The Xcode group path to new tests 26 | test_group_path: FlowTests/ 27 | 28 | ### Dependencies settings section 29 | podfile_path: 30 | 31 | ### Templates 32 | templates: 33 | - {name: coordinator_viper, git: 'https://github.com/tularovbeslan/coordinator_viper.git'} 34 | 35 | ### Create a reusable module in the specified directory 36 | #generamba gen [Module Name] swifty_viper --module_path 'Flow/PresentationLayer/ReusableComponents' 37 | 38 | ### Create a specific module in the specified directory 39 | #generamba gen [Module Name] swifty_viper --module_path 'Flow/PresentationLayer/Flows' 40 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier("BTR.Flow") # The bundle identifier of your app 2 | apple_id("tularovbeslan@gmail.com") # Your Apple email address 3 | 4 | itc_team_id("102254830") # App Store Connect Team ID 5 | team_id("MTVD7A69KL") # Developer Portal Team ID 6 | itc_team_id("102254830") # App Store Connect Team ID 7 | team_id("MTVD7A69KL") # Developer Portal Team ID 8 | 9 | # For more information about the Appfile, see: 10 | # https://docs.fastlane.tools/advanced/#appfile 11 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:ios) 17 | 18 | platform :ios do 19 | desc "Push a new beta build to TestFlight" 20 | lane :beta do 21 | build_app(workspace: "Flow.xcworkspace", scheme: "Flow") 22 | upload_to_testflight 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew cask install fastlane` 16 | 17 | # Available Actions 18 | ## iOS 19 | ### ios beta 20 | ``` 21 | fastlane ios beta 22 | ``` 23 | Push a new beta build to TestFlight 24 | 25 | ---- 26 | 27 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 28 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 29 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 30 | --------------------------------------------------------------------------------