├── .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 |
--------------------------------------------------------------------------------