Merge pull request #118 from TouchInstinct/feature/text_field_view_model

text field view model with bindings
This commit is contained in:
Ivan Smolin 2018-03-27 19:35:36 +03:00 committed by GitHub
commit 1a34bebe69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 688 additions and 24 deletions

View File

@ -1,5 +1,19 @@
# Changelog
## 0.7.0
- **Add**: `TotalCountCursor` for total count based pagination and related stuff.
- **[Breaking Change]**: `PaginationTableViewWrapper` and `PaginationTableViewWrapperDelegate` was renamed to `PaginationWrapper` and `PaginationWrapperDelegate `. Also there is significant changes in api
- **Add**: `GeneralDataLoadingModel` and `PaginationDataLoadingModel` for regular and paginated data loading with state handling.
- **Add**: `GeneralDataLoadingViewModel` and `GeneralDataLoadingController` for regular data loading and state handling in UI.
- **Add**: `ConfigurableNetworkService` - replacement of `DefaultNetworkService` from LeadKitAdditions.
- **Add**: `NumberFormattingService` and `NumberFormat` protocols with default implementation for creating per-project number formatters.
- **Add**: Very flexible in configuration `TextFieldViewModel` with build-in two-side data model binding.
- **Add**: `SingleLoadCursorConfiguration` as a replacement of `SingleLoadCursor`.
- **Add**: `UIApplication` extensions for making phone calls.
- **Add**: `NSAttributedString` extensions for appending attributed strings using `+` operator.
- **Change**: Lots of fixes and enhancements.
- **Update**: Update dependecies versions.
### 0.6.7
- **Add**: UITableView extension to add colored background for tableview bounce area.
@ -16,13 +30,13 @@
- **Fix**: SpinnerView bug(no animation) in Swift 4.
## 0.6.3
### 0.6.3
- **Fix**: SeparatorCell updates constraints after setting separator insets
## 0.6.2
### 0.6.2
- **Fix**: AlamofireManager extension no longer performs requests with default manager
## 0.6.1
### 0.6.1
- **New**: `RequestError`. Represents general api request errors
- **Change**: All api methods now throws `RequestError` when fails.
@ -38,60 +52,60 @@
- **Remove**: `Observable` creation for `ImmutableMappable`
- **Remove**: `UIView` and `UsedDefaults` extensions, `EstimatedViewHeightProtocol`, `StaticEstimatedViewHeightProtocol`, `StoryboardIdentifierProtocol`
## 0.5.18
### 0.5.18
- **Fix**: EmptyCell first appearance setup fix
## 0.5.17
### 0.5.17
- **Fix**: EmptyCell reusing appearance fix
- **Fix**: SeparatorCell reusing separators fix
## 0.5.16
### 0.5.16
- **Change**: Rename `AppearanceProtocol` to `AppearanceConfigurable`
- **Add**: `subscript(safe:)` subscript to `Array` extension for safe access to element by index
## 0.5.15
### 0.5.15
- **Add**: `AppearanceProtocol` which ensures that specific type can apply appearance to itself
- **Add**: `with(appearance:)`, `set(appearance:)` methods to TableRow extension
- **Add**: `Appearance` to `EmptyCell`
- **Remove**: `SeparatorCellViewModel`.
## 0.5.13
### 0.5.13
- **Change**: Remove type erasure behavior from `AnyBaseTableRow`
- **Change**: Rename `AnyBaseTableRow` class to `SeparatorRowBox`
- **Change**: Move `anyRow` property from `EmptyCellRow` to `TableRow` extension and rename it to `separatorRowBox`.
- **Change**: Move `configure(extreme: middle:)` method from `TableDirector` extension to `Array` extension and rename it to `configureSeparators(extreme: middle:)`
## 0.5.12
### 0.5.12
- **Fix**: Update type of `viewModel` in `ConfigurableController` to `ImplicitlyUwrappedOptional<ViewModelT>` instead of `ViewModelT`
## 0.5.11
### 0.5.11
- **[Breaking Change]**: rename initializer from `init(initialFrom:)` to `init(resetFrom:)` in `ResettableType`
- **Add**: `SeparatorCell` with `SeparatorCellViewModel`
- **Add**: `AnyBaseTableRow` for type-erasure
- **Add**: `EmptyCellRow` for empty cell with static height
## 0.5.10
### 0.5.10
- **Fix**: `Public` modifier for `SpinnerView`
## 0.5.9
### 0.5.9
- **Fix**: One-two-many fixed for values more than 99
## 0.5.8
### 0.5.8
- **Fix**: Synchronization over `NSRecursiveLock` for request count tracker in NetworkService
## 0.5.7
### 0.5.7
- **Add**: String extension `localizedComponent(value:stringOne:stringTwo:stringMany:)`
## 0.5.6
### 0.5.6
- **Fix**: Clear tableview if placeholder is shown

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "LeadKit"
s.version = "0.6.7"
s.version = "0.7.0"
s.summary = "iOS framework with a bunch of tools for rapid development"
s.homepage = "https://github.com/TouchInstinct/LeadKit"
s.license = "Apache License, Version 2.0"
@ -61,6 +61,7 @@ Pod::Spec.new do |s|
"Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift",
"Sources/Extensions/UIActivityIndicatorView/*",
"Sources/Extensions/UIAlertcontroller/*",
"Sources/Extensions/UIApplication/*",
"Sources/Extensions/UICollectionView/*",
"Sources/Extensions/UIDevice/*",
"Sources/Extensions/UIImage/*",
@ -87,6 +88,8 @@ Pod::Spec.new do |s|
"Sources/Extensions/DataLoading/PaginationDataLoading/*",
"Sources/Extensions/Support/UIScrollView+Support.swift",
"Sources/Extensions/TableDirector/*",
"Sources/Extensions/UIApplication/UIApplication+OpenUrlSupport.swift",
"Sources/Extensions/UIApplication/UIApplication+Cellular.swift",
"Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift",
"Sources/Protocols/DataLoading/PaginationDataLoading/PaginationWrappable.swift",
"Sources/Structures/DataLoading/PaginationDataLoading/*"
@ -112,7 +115,7 @@ Pod::Spec.new do |s|
"Sources/Classes/Views/SeparatorCell/*",
"Sources/Classes/Views/EmptyCell/*",
"Sources/Classes/DataLoading/PaginationDataLoading/PaginationWrapper.swift",
"Sources/Extensions/NetworkService/NetworkService+ActivityIndicator.swift",
"Sources/Extensions/NetworkService/NetworkService+ActivityIndicator-UIApplication.swift",
"Sources/Extensions/DataLoading/PaginationDataLoading/*",
"Sources/Extensions/TableDirector/*",
"Sources/Extensions/Array/Array+SeparatorRowBoxExtensions.swift"

View File

@ -276,6 +276,18 @@
671463CF1EB34B1E00EAB194 /* TestView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 671463B71EB34B1E00EAB194 /* TestView.xib */; };
67186B311EB248F100CFAFFB /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67186B281EB248F100CFAFFB /* LeadKit.framework */; };
67186B3F1EB24A1900CFAFFB /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 67186B201EB247A200CFAFFB /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
671AD25C206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; };
671AD25D206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; };
671AD25E206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; };
671AD25F206A343300EAF887 /* VoidBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD25B206A343300EAF887 /* VoidBlock.swift */; };
671AD262206A35EC00EAF887 /* UIApplication+Cellular.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD261206A35EC00EAF887 /* UIApplication+Cellular.swift */; };
671AD265206A35EC00EAF887 /* UIApplication+Cellular.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD261206A35EC00EAF887 /* UIApplication+Cellular.swift */; };
671AD267206A365100EAF887 /* UIApplication+OpenUrlSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD266206A365100EAF887 /* UIApplication+OpenUrlSupport.swift */; };
671AD269206A365100EAF887 /* UIApplication+OpenUrlSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD266206A365100EAF887 /* UIApplication+OpenUrlSupport.swift */; };
671AD26C206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; };
671AD26D206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; };
671AD26E206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; };
671AD26F206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */; };
673564F12068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673564F02068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift */; };
673564F22068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673564F02068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift */; };
673564F32068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673564F02068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift */; };
@ -314,6 +326,10 @@
675C1FB41F97CA32007D5249 /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; };
675C1FB51F97CA33007D5249 /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; };
675C1FB61F97CA33007D5249 /* AppearanceConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */; };
676B22A2206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
676B22A3206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
676B22A4206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
676B22A5206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */; };
6771DFD81EE99EBA002DCDAE /* DateFormattingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6771DFD71EE99EBA002DCDAE /* DateFormattingService.swift */; };
6771DFD91EE99EBA002DCDAE /* DateFormattingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6771DFD71EE99EBA002DCDAE /* DateFormattingService.swift */; };
6771DFDA1EE99EBA002DCDAE /* DateFormattingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6771DFD71EE99EBA002DCDAE /* DateFormattingService.swift */; };
@ -337,7 +353,6 @@
6774526D206249E30024EEEF /* UICollectionView+PaginationWrappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774526B206249E30024EEEF /* UICollectionView+PaginationWrappable.swift */; };
6774526E206249E30024EEEF /* UICollectionView+PaginationWrappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774526B206249E30024EEEF /* UICollectionView+PaginationWrappable.swift */; };
6774527020624A2A0024EEEF /* PaginationWrapperDelegate+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774526F20624A2A0024EEEF /* PaginationWrapperDelegate+DefaultImplementation.swift */; };
6774527120624A2A0024EEEF /* PaginationWrapperDelegate+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774526F20624A2A0024EEEF /* PaginationWrapperDelegate+DefaultImplementation.swift */; };
6774527420624E820024EEEF /* DataLoadingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774527320624E820024EEEF /* DataLoadingModel.swift */; };
6774527520624E820024EEEF /* DataLoadingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774527320624E820024EEEF /* DataLoadingModel.swift */; };
6774527620624E820024EEEF /* DataLoadingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6774527320624E820024EEEF /* DataLoadingModel.swift */; };
@ -382,6 +397,18 @@
677452B720627FE00024EEEF /* PaginationWrappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67EB7FF7206175F700BDD9FB /* PaginationWrappable.swift */; };
677452B820627FE00024EEEF /* PaginationWrappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67EB7FF7206175F700BDD9FB /* PaginationWrappable.swift */; };
6782BBA91EB31D5A0086E0B8 /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6782BBA01EB31D590086E0B8 /* LeadKit.framework */; };
678D267920691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; };
678D267A20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; };
678D267B20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; };
678D267C20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D267820691D8200B05B93 /* DataModelFieldBinding.swift */; };
678D26A020692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */; };
678D26A120692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */; };
678D26A220692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */; };
678D26A320692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */; };
678D26A420692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269F20692BFF00B05B93 /* TextFieldViewModelEvents.swift */; };
678D26A520692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269F20692BFF00B05B93 /* TextFieldViewModelEvents.swift */; };
678D26A620692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269F20692BFF00B05B93 /* TextFieldViewModelEvents.swift */; };
678D26A720692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D269F20692BFF00B05B93 /* TextFieldViewModelEvents.swift */; };
67952C3C1EB3266100B3BA1A /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 67186B201EB247A200CFAFFB /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
67952C3D1EB3266200B3BA1A /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 67186B201EB247A200CFAFFB /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
67952DCE1EB327B500B3BA1A /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67952DC51EB327B400B3BA1A /* LeadKit.framework */; };
@ -407,6 +434,10 @@
67CAF8B720651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8B520651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift */; };
67CAF8B820651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8B520651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift */; };
67CAF8B920651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8B520651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift */; };
67CAF8C620652E2A00527085 /* TextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8C520652E2A00527085 /* TextFieldViewModel.swift */; };
67CAF8C720652E2A00527085 /* TextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8C520652E2A00527085 /* TextFieldViewModel.swift */; };
67CAF8C820652E2A00527085 /* TextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8C520652E2A00527085 /* TextFieldViewModel.swift */; };
67CAF8C920652E2A00527085 /* TextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CAF8C520652E2A00527085 /* TextFieldViewModel.swift */; };
67CDEE401EB369BF00895905 /* ConfigurableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671462241EB3396E00EAB194 /* ConfigurableController.swift */; };
67E6C2351EBB32F5007842A6 /* SingleLoadCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6C2341EBB32F5007842A6 /* SingleLoadCursor.swift */; };
67E6C2361EBB32F5007842A6 /* SingleLoadCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6C2341EBB32F5007842A6 /* SingleLoadCursor.swift */; };
@ -626,6 +657,10 @@
67186B301EB248F100CFAFFB /* LeadKit iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LeadKit iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
67186B411EB24AA000CFAFFB /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
67186C1A1EB24B7800CFAFFB /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = "<group>"; };
671AD25B206A343300EAF887 /* VoidBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoidBlock.swift; sourceTree = "<group>"; };
671AD261206A35EC00EAF887 /* UIApplication+Cellular.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Cellular.swift"; sourceTree = "<group>"; };
671AD266206A365100EAF887 /* UIApplication+OpenUrlSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+OpenUrlSupport.swift"; sourceTree = "<group>"; };
671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+TotalCountCursorListingResult.swift"; sourceTree = "<group>"; };
673564F02068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NumberFormattingService+DefaultImplementation.swift"; sourceTree = "<group>"; };
673564F52068C68D00F0CBED /* NumberFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberFormat.swift; sourceTree = "<group>"; };
673CF40A2063AB7C00C329F6 /* GeneralDataLoadingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralDataLoadingViewModel.swift; sourceTree = "<group>"; };
@ -636,6 +671,7 @@
673CF4332063E29B00C329F6 /* TextWithButtonPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextWithButtonPlaceholder.swift; sourceTree = "<group>"; };
673CF4372063E7CE00C329F6 /* GeneralDataLoadingController+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GeneralDataLoadingController+DefaultImplementation.swift"; sourceTree = "<group>"; };
674AF55B1EC45B1600038A8F /* UIActivityIndicatorView+LoadingIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIActivityIndicatorView+LoadingIndicator.swift"; sourceTree = "<group>"; };
676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Extensions.swift"; sourceTree = "<group>"; };
6771DFD71EE99EBA002DCDAE /* DateFormattingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateFormattingService.swift; sourceTree = "<group>"; };
6771DFDD1EE99F6F002DCDAE /* DateFormattingArguments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateFormattingArguments.swift; sourceTree = "<group>"; };
6771DFE31EE9A00A002DCDAE /* DateFormattingArguments+DateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormattingArguments+DateFormatter.swift"; sourceTree = "<group>"; };
@ -658,6 +694,9 @@
6782BBA01EB31D590086E0B8 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6782BBA81EB31D5A0086E0B8 /* LeadKit tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LeadKit tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
6782BBB91EB31DD90086E0B8 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = "<group>"; };
678D267820691D8200B05B93 /* DataModelFieldBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataModelFieldBinding.swift; sourceTree = "<group>"; };
678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldViewEvents.swift; sourceTree = "<group>"; };
678D269F20692BFF00B05B93 /* TextFieldViewModelEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldViewModelEvents.swift; sourceTree = "<group>"; };
67952C391EB3203F00B3BA1A /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = "<group>"; };
67952C3A1EB3205D00B3BA1A /* Info-watchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = "<group>"; };
67952C3B1EB3208000B3BA1A /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = "<group>"; };
@ -673,6 +712,7 @@
67CAF8AB2065189C00527085 /* NetworkService+ActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkService+ActivityIndicator.swift"; sourceTree = "<group>"; };
67CAF8B020651E1E00527085 /* ConfigurableNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurableNetworkService.swift; sourceTree = "<group>"; };
67CAF8B520651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConfigurableNetworkService+DefaultImplementation.swift"; sourceTree = "<group>"; };
67CAF8C520652E2A00527085 /* TextFieldViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldViewModel.swift; sourceTree = "<group>"; };
67E6C2341EBB32F5007842A6 /* SingleLoadCursor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleLoadCursor.swift; sourceTree = "<group>"; };
67EB7FBF206140E600BDD9FB /* TotalCountCursor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalCountCursor.swift; sourceTree = "<group>"; };
67EB7FC6206148D000BDD9FB /* TotalCountCursorListingResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalCountCursorListingResult.swift; sourceTree = "<group>"; };
@ -843,6 +883,7 @@
671461D41EB3396E00EAB194 /* Views */ = {
isa = PBXGroup;
children = (
677A4AC9206510FA00753C74 /* TextField */,
673CF42A2063DE3A00C329F6 /* DefaultPlaceholders */,
A6AF3B381F8B957400CDB971 /* SeparatorRowBox */,
A66428A41F8A651700C6308D /* SeparatorCell */,
@ -867,7 +908,6 @@
671461DA1EB3396E00EAB194 /* Extensions */ = {
isa = PBXGroup;
children = (
673564EF2068C29100F0CBED /* NumberFormattingService */,
671461DB1EB3396E00EAB194 /* Alamofire */,
EFBE57CE1EC35ED90040E00A /* Array */,
67A1FF921EBCA64A00D6C89F /* CABasicAnimation */,
@ -881,6 +921,8 @@
6771DFE81EEA7C8F002DCDAE /* DateFormattingService */,
671461EA1EB3396E00EAB194 /* Double */,
6714639C1EB33AC200EAB194 /* NetworkService */,
676B22A0206A6249002E9F8A /* NSAttributedString */,
673564EF2068C29100F0CBED /* NumberFormattingService */,
671461F01EB3396E00EAB194 /* Observable */,
671461F51EB3396E00EAB194 /* Sequence */,
82F8BB161F5DDED100C1061B /* Single */,
@ -890,6 +932,7 @@
671462021EB3396E00EAB194 /* TimeInterval */,
674AF55A1EC45B1600038A8F /* UIActivityIndicatorView */,
679C77D51F98F7A60094BE10 /* UIAlertController */,
671AD260206A35C500EAF887 /* UIApplication */,
671462081EB3396E00EAB194 /* UIColor */,
6714620C1EB3396E00EAB194 /* UIImage */,
36DAAF4F2007CC330090BE0D /* UITableView */,
@ -1066,6 +1109,7 @@
children = (
A676AE4C1F9810C1001F9214 /* Any+Cast.swift */,
671462211EB3396E00EAB194 /* Any+TypeName.swift */,
671AD25B206A343300EAF887 /* VoidBlock.swift */,
);
path = Functions;
sourceTree = "<group>";
@ -1073,10 +1117,11 @@
671462221EB3396E00EAB194 /* Protocols */ = {
isa = PBXGroup;
children = (
67C7B1772068BADA00C9EDA3 /* NumberFormattingService */,
67EB7FC5206148C400BDD9FB /* DataLoading */,
67CAF8AF20651E0F00527085 /* NetworkService */,
67C7B1772068BADA00C9EDA3 /* NumberFormattingService */,
673CF4202063D8EB00C329F6 /* Rx */,
678D269C20692BFF00B05B93 /* Views */,
679C77D41F98F78E0094BE10 /* AlertRepresentable.swift */,
671463A11EB33FF600EAB194 /* Animatable.swift */,
40F118461F8FEF97004AADAF /* AppearanceConfigurable.swift */,
@ -1210,6 +1255,15 @@
path = Tests;
sourceTree = "<group>";
};
671AD260206A35C500EAF887 /* UIApplication */ = {
isa = PBXGroup;
children = (
671AD261206A35EC00EAF887 /* UIApplication+Cellular.swift */,
671AD266206A365100EAF887 /* UIApplication+OpenUrlSupport.swift */,
);
path = UIApplication;
sourceTree = "<group>";
};
673564EF2068C29100F0CBED /* NumberFormattingService */ = {
isa = PBXGroup;
children = (
@ -1260,6 +1314,14 @@
path = UIActivityIndicatorView;
sourceTree = "<group>";
};
676B22A0206A6249002E9F8A /* NSAttributedString */ = {
isa = PBXGroup;
children = (
676B22A1206A626D002E9F8A /* NSAttributedString+Extensions.swift */,
);
path = NSAttributedString;
sourceTree = "<group>";
};
6771DFDC1EE99F52002DCDAE /* DateFormatting */ = {
isa = PBXGroup;
children = (
@ -1370,6 +1432,32 @@
path = PaginationDataLoading;
sourceTree = "<group>";
};
677A4AC9206510FA00753C74 /* TextField */ = {
isa = PBXGroup;
children = (
67CAF8C520652E2A00527085 /* TextFieldViewModel.swift */,
678D267820691D8200B05B93 /* DataModelFieldBinding.swift */,
);
path = TextField;
sourceTree = "<group>";
};
678D269C20692BFF00B05B93 /* Views */ = {
isa = PBXGroup;
children = (
678D269D20692BFF00B05B93 /* TextField */,
);
path = Views;
sourceTree = "<group>";
};
678D269D20692BFF00B05B93 /* TextField */ = {
isa = PBXGroup;
children = (
678D269E20692BFF00B05B93 /* TextFieldViewEvents.swift */,
678D269F20692BFF00B05B93 /* TextFieldViewModelEvents.swift */,
);
path = TextField;
sourceTree = "<group>";
};
679C77D51F98F7A60094BE10 /* UIAlertController */ = {
isa = PBXGroup;
children = (
@ -1592,6 +1680,7 @@
children = (
EFBE57CF1EC35EF20040E00A /* Array+Extensions.swift */,
A658E54F1F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift */,
671AD26B206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift */,
);
path = Array;
sourceTree = "<group>";
@ -2358,6 +2447,8 @@
67EB8001206177D600BDD9FB /* PaginationWrapperDelegate.swift in Sources */,
671462CC1EB3396E00EAB194 /* String+SizeCalculation.swift in Sources */,
6774529A20625E5B0024EEEF /* PaginationDataLoadingState.swift in Sources */,
678D26A020692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */,
678D26A420692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */,
671462801EB3396E00EAB194 /* AlamofireRequest+Extensions.swift in Sources */,
67EB7FF8206175F700BDD9FB /* PaginationWrappable.swift in Sources */,
671463541EB3396E00EAB194 /* StaticViewHeightProtocol.swift in Sources */,
@ -2371,6 +2462,7 @@
A6E0DDEF1F8A6C57002CA74E /* CellSeparatorType.swift in Sources */,
6714634C1EB3396E00EAB194 /* ReuseIdentifierProtocol.swift in Sources */,
671462F01EB3396E00EAB194 /* UIImage+SupportExtensions.swift in Sources */,
67CAF8C620652E2A00527085 /* TextFieldViewModel.swift in Sources */,
6771DFDE1EE99F6F002DCDAE /* DateFormattingArguments.swift in Sources */,
671462681EB3396E00EAB194 /* NetworkService.swift in Sources */,
671463101EB3396E00EAB194 /* UIViewController+DefaultXibName.swift in Sources */,
@ -2403,6 +2495,7 @@
A6D10EAB1F8A9278003E69DD /* Comparable+Extensions.swift in Sources */,
671463801EB3396E00EAB194 /* PaddingDrawingOperation.swift in Sources */,
671463281EB3396E00EAB194 /* BaseViewModel.swift in Sources */,
671AD25C206A343300EAF887 /* VoidBlock.swift in Sources */,
A6E0DDDF1F8A696F002CA74E /* SeparatorCell.swift in Sources */,
671462AC1EB3396E00EAB194 /* Observable+DeferredJust.swift in Sources */,
671463001EB3396E00EAB194 /* UIView+LoadFromNib.swift in Sources */,
@ -2420,13 +2513,16 @@
6774527420624E820024EEEF /* DataLoadingModel.swift in Sources */,
40F118491F8FF223004AADAF /* TableRow+AppearanceExtension.swift in Sources */,
671463701EB3396E00EAB194 /* ApiRequestParameters.swift in Sources */,
676B22A2206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */,
A658E5501F8CD9350093527A /* Array+SeparatorRowBoxExtensions.swift in Sources */,
673564F12068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */,
671462EC1EB3396E00EAB194 /* UIImage+Extensions.swift in Sources */,
677452AE206274630024EEEF /* PaginationWrapper.swift in Sources */,
A6E0DDF11F8A6C80002CA74E /* SeparatorConfiguration.swift in Sources */,
67EB7FEB2061667900BDD9FB /* DefaultTotalCountCursorListingResult.swift in Sources */,
671AD26C206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */,
673CF4382063E7CE00C329F6 /* GeneralDataLoadingController+DefaultImplementation.swift in Sources */,
671AD267206A365100EAF887 /* UIApplication+OpenUrlSupport.swift in Sources */,
673CF40B2063AB7C00C329F6 /* GeneralDataLoadingViewModel.swift in Sources */,
6714636C1EB3396E00EAB194 /* XibNameProtocol.swift in Sources */,
6771DFEA1EEA7CB8002DCDAE /* DateFormattingService+MappingTransform.swift in Sources */,
@ -2466,6 +2562,7 @@
6714628C1EB3396E00EAB194 /* CGImage+Alpha.swift in Sources */,
671462741EB3396E00EAB194 /* LeadKitError.swift in Sources */,
677452A420625FA90024EEEF /* RxDataSource.swift in Sources */,
671AD262206A35EC00EAF887 /* UIApplication+Cellular.swift in Sources */,
671462D81EB3396E00EAB194 /* TimeInterval+DateComponents.swift in Sources */,
6714638C1EB3396E00EAB194 /* SolidFillDrawingOperation.swift in Sources */,
6774526C206249E30024EEEF /* UICollectionView+PaginationWrappable.swift in Sources */,
@ -2478,6 +2575,7 @@
67EB7FD420615D1700BDD9FB /* ResettableCursorType.swift in Sources */,
6714629C1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */,
6774529F20625EEE0024EEEF /* PaginationDataLoadingModel.swift in Sources */,
678D267920691D8200B05B93 /* DataModelFieldBinding.swift in Sources */,
673CF4342063E29B00C329F6 /* TextWithButtonPlaceholder.swift in Sources */,
673CF4222063D90600C329F6 /* DisposeBagHolder.swift in Sources */,
671463681EB3396E00EAB194 /* ConfigurableView.swift in Sources */,
@ -2526,10 +2624,12 @@
6771DFE01EE99F6F002DCDAE /* DateFormattingArguments.swift in Sources */,
671463621EB3396E00EAB194 /* SupportProtocol.swift in Sources */,
6771DFEC1EEA7CB8002DCDAE /* DateFormattingService+MappingTransform.swift in Sources */,
678D26A220692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */,
671462861EB3396E00EAB194 /* CGContext+Initializers.swift in Sources */,
6774527B206252020024EEEF /* DataLoadingState.swift in Sources */,
6714634E1EB3396E00EAB194 /* ReuseIdentifierProtocol.swift in Sources */,
6714626A1EB3396E00EAB194 /* NetworkService.swift in Sources */,
671AD26E206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */,
673CF4132063ABD100C329F6 /* GeneralDataLoadingState+Extensions.swift in Sources */,
671463421EB3396E00EAB194 /* ModuleConfigurator.swift in Sources */,
671462921EB3396E00EAB194 /* CGImage+Crop.swift in Sources */,
@ -2556,11 +2656,13 @@
67EB7FD620615D1700BDD9FB /* ResettableCursorType.swift in Sources */,
6714625A1EB3396E00EAB194 /* Log.swift in Sources */,
6714627A1EB3396E00EAB194 /* ResizeMode.swift in Sources */,
67CAF8C820652E2A00527085 /* TextFieldViewModel.swift in Sources */,
671463A41EB33FF600EAB194 /* Animatable.swift in Sources */,
671463721EB3396E00EAB194 /* ApiRequestParameters.swift in Sources */,
6714636E1EB3396E00EAB194 /* XibNameProtocol.swift in Sources */,
67CDEE401EB369BF00895905 /* ConfigurableController.swift in Sources */,
67CAF8AD2065189C00527085 /* NetworkService+ActivityIndicator.swift in Sources */,
678D26A620692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */,
A676AE481F97D28A001F9214 /* String+Extensions.swift in Sources */,
673CF4242063D90600C329F6 /* DisposeBagHolder.swift in Sources */,
67C7B17B2068BB1C00C9EDA3 /* NumberFormattingService.swift in Sources */,
@ -2570,10 +2672,12 @@
67EB7FED2061667900BDD9FB /* DefaultTotalCountCursorListingResult.swift in Sources */,
6714637E1EB3396E00EAB194 /* ImageDrawingOperation.swift in Sources */,
671463361EB3396E00EAB194 /* DrawingOperation.swift in Sources */,
676B22A4206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */,
671462721EB3396E00EAB194 /* CursorError.swift in Sources */,
671462961EB3396E00EAB194 /* CGSize+CGContextSize.swift in Sources */,
671463661EB3396E00EAB194 /* ViewHeightProtocol.swift in Sources */,
67EB7FD120615B8900BDD9FB /* TotalCountCursorConfiguration.swift in Sources */,
678D267B20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */,
673CF40D2063AB7C00C329F6 /* GeneralDataLoadingViewModel.swift in Sources */,
67EB7FC9206148D000BDD9FB /* TotalCountCursorListingResult.swift in Sources */,
6774527620624E820024EEEF /* DataLoadingModel.swift in Sources */,
@ -2593,6 +2697,7 @@
6714638E1EB3396E00EAB194 /* SolidFillDrawingOperation.swift in Sources */,
6774529420625D170024EEEF /* GeneralDataLoadingModel.swift in Sources */,
67FDC2611FA310EA00C76A77 /* RequestError.swift in Sources */,
671AD25E206A343300EAF887 /* VoidBlock.swift in Sources */,
671462521EB3396E00EAB194 /* StaticCursor.swift in Sources */,
6714629E1EB3396E00EAB194 /* CursorType+Slice.swift in Sources */,
6714636A1EB3396E00EAB194 /* ConfigurableView.swift in Sources */,
@ -2609,6 +2714,7 @@
671462831EB3396E00EAB194 /* AlamofireRequest+Extensions.swift in Sources */,
677452B820627FE00024EEEF /* PaginationWrappable.swift in Sources */,
673CF40E2063AB7C00C329F6 /* GeneralDataLoadingViewModel.swift in Sources */,
678D26A320692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */,
67745283206256A20024EEEF /* RxDataLoadingModel.swift in Sources */,
67EB8003206177D600BDD9FB /* PaginationWrapperDelegate.swift in Sources */,
671463571EB3396E00EAB194 /* StaticViewHeightProtocol.swift in Sources */,
@ -2629,11 +2735,13 @@
671463931EB3396E00EAB194 /* TemplateDrawingOperation.swift in Sources */,
674AF55E1EC45B1600038A8F /* UIActivityIndicatorView+LoadingIndicator.swift in Sources */,
671463A51EB33FF600EAB194 /* Animatable.swift in Sources */,
67CAF8C920652E2A00527085 /* TextFieldViewModel.swift in Sources */,
6714629B1EB3396E00EAB194 /* CGSize+Resize.swift in Sources */,
671463331EB3396E00EAB194 /* CursorType.swift in Sources */,
6714624F1EB3396E00EAB194 /* MapCursor.swift in Sources */,
671463271EB3396E00EAB194 /* Any+TypeName.swift in Sources */,
67EB7FD220615B8900BDD9FB /* TotalCountCursorConfiguration.swift in Sources */,
671AD26F206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */,
EFBE57D31EC35EF20040E00A /* Array+Extensions.swift in Sources */,
67CAF8AE2065189C00527085 /* NetworkService+ActivityIndicator.swift in Sources */,
6714638B1EB3396E00EAB194 /* RoundDrawingOperation.swift in Sources */,
@ -2663,9 +2771,12 @@
A676AE581F981131001F9214 /* ObservableMappable.swift in Sources */,
671463731EB3396E00EAB194 /* ApiRequestParameters.swift in Sources */,
671462EF1EB3396E00EAB194 /* UIImage+Extensions.swift in Sources */,
671AD269206A365100EAF887 /* UIApplication+OpenUrlSupport.swift in Sources */,
671AD25F206A343300EAF887 /* VoidBlock.swift in Sources */,
6774526A206249360024EEEF /* UITableView+PaginationWrappable.swift in Sources */,
6714636F1EB3396E00EAB194 /* XibNameProtocol.swift in Sources */,
EFBE57DE1EC361620040E00A /* UIView+Layout.swift in Sources */,
671AD265206A35EC00EAF887 /* UIApplication+Cellular.swift in Sources */,
67A1FF971EBCA65E00D6C89F /* CABasicAnimation+Rotation.swift in Sources */,
671462A31EB3396E00EAB194 /* Double+Rounding.swift in Sources */,
6714625F1EB3396E00EAB194 /* LogFormatter.swift in Sources */,
@ -2680,9 +2791,11 @@
67EB7FDD20615D5B00BDD9FB /* ResettableRxCursorDataSource.swift in Sources */,
677452A720625FA90024EEEF /* RxDataSource.swift in Sources */,
6774527720624E820024EEEF /* DataLoadingModel.swift in Sources */,
678D267C20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */,
6714639B1EB3396E00EAB194 /* AnyLoadingIndicator.swift in Sources */,
6771DFE11EE99F6F002DCDAE /* DateFormattingArguments.swift in Sources */,
671463171EB3396E00EAB194 /* UIViewController+TopVisibleViewController.swift in Sources */,
678D26A720692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */,
67EB7FCA206148D000BDD9FB /* TotalCountCursorListingResult.swift in Sources */,
6714628B1EB3396E00EAB194 /* CGFloat+Pixels.swift in Sources */,
671462971EB3396E00EAB194 /* CGSize+CGContextSize.swift in Sources */,
@ -2708,6 +2821,7 @@
6714628F1EB3396E00EAB194 /* CGImage+Alpha.swift in Sources */,
67051ADD1EBC7C36008EADC0 /* SpinnerView.swift in Sources */,
671462771EB3396E00EAB194 /* LeadKitError.swift in Sources */,
676B22A5206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */,
673CF4142063ABD100C329F6 /* GeneralDataLoadingState+Extensions.swift in Sources */,
671462DB1EB3396E00EAB194 /* TimeInterval+DateComponents.swift in Sources */,
6774529020625C9E0024EEEF /* GeneralDataLoadingState.swift in Sources */,
@ -2740,12 +2854,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
678D267A20691D8200B05B93 /* DataModelFieldBinding.swift in Sources */,
67EB7FE520615DE000BDD9FB /* DataSource.swift in Sources */,
671463491EB3396E00EAB194 /* ResettableType.swift in Sources */,
A676AE491F97D28A001F9214 /* String+Extensions.swift in Sources */,
671462E51EB3396E00EAB194 /* UIColor+Hex.swift in Sources */,
67EB7FFE206176C900BDD9FB /* AnyPaginationWrappable.swift in Sources */,
671462CD1EB3396E00EAB194 /* String+SizeCalculation.swift in Sources */,
678D26A520692BFF00B05B93 /* TextFieldViewModelEvents.swift in Sources */,
677452B720627FE00024EEEF /* PaginationWrappable.swift in Sources */,
67EB7FC1206140E600BDD9FB /* TotalCountCursor.swift in Sources */,
6771DFDF1EE99F6F002DCDAE /* DateFormattingArguments.swift in Sources */,
@ -2756,6 +2872,7 @@
671463551EB3396E00EAB194 /* StaticViewHeightProtocol.swift in Sources */,
671463611EB3396E00EAB194 /* SupportProtocol.swift in Sources */,
671462851EB3396E00EAB194 /* CGContext+Initializers.swift in Sources */,
67CAF8C720652E2A00527085 /* TextFieldViewModel.swift in Sources */,
6714634D1EB3396E00EAB194 /* ReuseIdentifierProtocol.swift in Sources */,
67745281206256A20024EEEF /* RxDataLoadingModel.swift in Sources */,
671462F11EB3396E00EAB194 /* UIImage+SupportExtensions.swift in Sources */,
@ -2769,6 +2886,8 @@
671463851EB3396E00EAB194 /* ResizeDrawingOperation.swift in Sources */,
673564F22068C2AD00F0CBED /* NumberFormattingService+DefaultImplementation.swift in Sources */,
671462D11EB3396E00EAB194 /* UIScrollView+Support.swift in Sources */,
671AD25D206A343300EAF887 /* VoidBlock.swift in Sources */,
671AD26D206A3E8500EAF887 /* Array+TotalCountCursorListingResult.swift in Sources */,
6774528E20625C9E0024EEEF /* GeneralDataLoadingState.swift in Sources */,
671463911EB3396E00EAB194 /* TemplateDrawingOperation.swift in Sources */,
67EB7FEC2061667900BDD9FB /* DefaultTotalCountCursorListingResult.swift in Sources */,
@ -2789,7 +2908,6 @@
6714627D1EB3396E00EAB194 /* AlamofireManager+Extensions.swift in Sources */,
671462591EB3396E00EAB194 /* Log.swift in Sources */,
673CF4352063E29B00C329F6 /* TextWithButtonPlaceholder.swift in Sources */,
6774527120624A2A0024EEEF /* PaginationWrapperDelegate+DefaultImplementation.swift in Sources */,
67EB8002206177D600BDD9FB /* PaginationWrapperDelegate.swift in Sources */,
673CF4232063D90600C329F6 /* DisposeBagHolder.swift in Sources */,
677452AA206263360024EEEF /* CursorType+RxDataSourceDefaultImplementation.swift in Sources */,
@ -2848,9 +2966,11 @@
67EB7FC8206148D000BDD9FB /* TotalCountCursorListingResult.swift in Sources */,
671462751EB3396E00EAB194 /* LeadKitError.swift in Sources */,
EFBE57D11EC35EF20040E00A /* Array+Extensions.swift in Sources */,
676B22A3206A626D002E9F8A /* NSAttributedString+Extensions.swift in Sources */,
671462D91EB3396E00EAB194 /* TimeInterval+DateComponents.swift in Sources */,
6714638D1EB3396E00EAB194 /* SolidFillDrawingOperation.swift in Sources */,
671463A31EB33FF600EAB194 /* Animatable.swift in Sources */,
678D26A120692BFF00B05B93 /* TextFieldViewEvents.swift in Sources */,
6771DFE51EE9A00A002DCDAE /* DateFormattingArguments+DateFormatter.swift in Sources */,
671462511EB3396E00EAB194 /* StaticCursor.swift in Sources */,
67CAF8B720651E4F00527085 /* ConfigurableNetworkService+DefaultImplementation.swift in Sources */,

View File

@ -4,7 +4,7 @@ abstract_target 'LeadKit' do
pod "RxCocoa", '~> 4.1'
pod "RxAlamofire", '~> 4.1'
pod "ObjectMapper", '~> 3.0'
pod 'SwiftLint', '~> 0.25'
pod "SwiftLint", '~> 0.25'
inhibit_all_warnings!

View File

@ -37,6 +37,6 @@ SPEC CHECKSUMS:
TableKit: 61880e4c13ac0ba396a308fcb1ae48f6dec8b458
UIScrollView-InfiniteScroll: c132d6d5851daff229ab4a1060ccf70a05a051c9
PODFILE CHECKSUM: 3adf387a63bf042042b4d0cc87828bef873efd2d
PODFILE CHECKSUM: ab838edfaeaa5ec185764a2fa042a9b61be1da2a
COCOAPODS: 1.4.0

View File

@ -22,7 +22,32 @@
import RxSwift
/// Single load cursor configuration for single load operation
public final class SingleLoadCursorConfiguration<Element>: TotalCountCursorConfiguration {
public typealias ResultType = [Element]
private let loadingSingle: Single<ResultType>
/// Initializer for Single with array result type.
///
/// - Parameter loadingSingle: Single that will emit array of result type.
public init(loadingSingle: Single<ResultType>) {
self.loadingSingle = loadingSingle
}
public func resultSingle() -> Single<ResultType> {
return loadingSingle
}
public init(resetFrom other: SingleLoadCursorConfiguration) {
self.loadingSingle = other.loadingSingle
}
}
/// Cursor implementation for single load operation
@available(*, deprecated, message: "Use SingleLoadCursorConfiguration with TotalCountCursor.")
public class SingleLoadCursor<Element>: ResettableCursorType {
private let loadingObservable: Single<[Element]>

View File

@ -84,7 +84,10 @@ open class NetworkService {
/// Shows network activity indicator when requests in executed. Works only on iOS.
public func bindToApplicationActivityIndicator() {
bindActivityIndicator()?.disposed(by: disposeBag)
// Fatal error: `drive*` family of methods can be only called from `MainThread`
DispatchQueue.main.async {
self.bindActivityIndicator()?.disposed(by: self.disposeBag)
}
}
/// Disable showing network activity indicator.

View File

@ -0,0 +1,134 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import RxSwift
import RxCocoa
/// Class that maps data model field to String and vise-versa.
public final class DataModelFieldBinding<T> {
public typealias GetFieldClosure = (T) -> String?
public typealias MergeFieldClosure = (T, String?) -> T
private let modelVariable: Variable<T>
private let modelDriver: Driver<T>
private let getFieldClosure: DataModelFieldBinding<T>.GetFieldClosure
private let mergeFieldClosure: DataModelFieldBinding<T>.MergeFieldClosure
/// Memberwise initializer.
///
/// - Parameters:
/// - modelVariable: Variable that contains data model.
/// - modelDriver: Driver that emits new data models.
/// - getFieldClosure: Closure for getting field string reprerentation from data model.
/// - mergeFieldClosure: Closure for merging new field value into data model.
public init(modelVariable: Variable<T>,
modelDriver: Driver<T>,
getFieldClosure: @escaping GetFieldClosure,
mergeFieldClosure: @escaping MergeFieldClosure) {
self.modelVariable = modelVariable
self.modelDriver = modelDriver
self.getFieldClosure = getFieldClosure
self.mergeFieldClosure = mergeFieldClosure
}
/// Method that merges new field values with data model.
///
/// - Parameter textDriver: Driver that emits new text values.
/// - Returns: Disposable object that can be used to unsubscribe the observer from the variable.
public func mergeStringToModel(from textDriver: Driver<String?>) -> Disposable {
return textDriver.map { [modelVariable, mergeFieldClosure] in
mergeFieldClosure(modelVariable.value, $0)
}
.drive(modelVariable)
}
/// A Driver that will emit current field value.
public var fieldDriver: Driver<String?> {
return modelDriver.map(getFieldClosure)
}
}
public extension DataModelFieldBinding {
/// Convenience initializer without modelDriver, which will be obtained from modelVariable.
///
/// - Parameters:
/// - modelVariable: Variable that contains data model.
/// - getFieldClosure: Closure for getting field string reprerentation from data model.
/// - mergeFieldClosure: Closure for merging new field value into data model.
convenience init(modelVariable: Variable<T>,
getFieldClosure: @escaping GetFieldClosure,
mergeFieldClosure: @escaping MergeFieldClosure) {
self.init(modelVariable: modelVariable,
modelDriver: modelVariable.asDriver(),
getFieldClosure: getFieldClosure,
mergeFieldClosure: mergeFieldClosure)
}
}
public extension DataModelFieldBinding where T == String? {
/// Convenience initializer for data model of string.
///
/// - Parameter modelVariable: Variable that contains data model.
convenience init(modelVariable: Variable<T>) {
self.init(modelVariable: modelVariable,
modelDriver: modelVariable.asDriver(),
getFieldClosure: { $0 },
mergeFieldClosure: { $1 })
}
}
public extension Variable {
/// Creates DataModelFieldBinding configured with given closures and variable itself.
///
/// - Parameters:
/// - getFieldClosure: Closure for getting field string reprerentation from data model.
/// - mergeFieldClosure: Closure for merging new field value into data model.
/// - Returns: DataModelFieldBinding instance.
func fieldBinding(getFieldClosure: @escaping DataModelFieldBinding<E>.GetFieldClosure,
mergeFieldClosure: @escaping DataModelFieldBinding<E>.MergeFieldClosure) -> DataModelFieldBinding<E> {
return DataModelFieldBinding(modelVariable: self,
getFieldClosure: getFieldClosure,
mergeFieldClosure: mergeFieldClosure)
}
}
public extension Variable where Element == String? {
/// Creates DataModelFieldBinding configured with variable itself.
///
/// - Returns: DataModelFieldBinding instance.
func fieldBinding() -> DataModelFieldBinding<E> {
return DataModelFieldBinding(modelVariable: self)
}
}

View File

@ -0,0 +1,91 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import RxSwift
import RxCocoa
/// Class that used for binding text field with upper level view model.
open class TextFieldViewModel<ViewEvents: TextFieldViewEvents,
ViewModelEvents: TextFieldViewModelEvents> {
/// Events that can be emitted by view model.
public let viewModelEvents: ViewModelEvents
private let viewEventsVariable = Variable<ViewEvents?>(nil)
private(set) public var disposeBag = DisposeBag()
/// Initializer with view model events.
///
/// - Parameter viewModelEvents: Events that can be emitted by view model.
public init(viewModelEvents: ViewModelEvents) {
self.viewModelEvents = viewModelEvents
}
/// View events driver that will emit view events structure
/// when view will bind itself to the view model.
public var viewEventsDriver: Driver<ViewEvents> {
return viewEventsVariable
.asDriver()
.flatMap { viewEvents -> Driver<ViewEvents> in
guard let viewEvents = viewEvents else {
return .empty()
}
return .just(viewEvents)
}
}
/// Method that performs binding view events to view model.
///
/// - Parameter viewEvents: View events structure.
public func bind(viewEvents: ViewEvents) {
viewEventsVariable.value = viewEvents
}
/// Unbinds view from view model.
public func unbindView() {
disposeBag = DisposeBag()
}
}
public extension TextFieldViewModel {
typealias MapViewEventsClosure = (ViewEvents) -> Disposable
/// Convenient method for binding to the current view events structure.
///
/// - Parameter closure: Closure that takes a view events parameter and returns Disposable.
/// - Returns: Disposable object that can be used to unsubscribe the observer from the binding.
func mapViewEvents(_ closure: @escaping MapViewEventsClosure) -> Disposable {
return viewEventsDriver
.map { [weak self] in
guard let strongSelf = self else {
return
}
closure($0).disposed(by: strongSelf.disposeBag)
}
.drive()
}
}

View File

@ -0,0 +1,35 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
extension Array: TotalCountCursorListingResult {
public typealias ElementType = Element
public var results: [Element] {
return self
}
public var totalCount: Int {
return count
}
}

View File

@ -70,3 +70,12 @@ public extension PaginationWrapperDelegate {
}
}
public extension PaginationWrapperDelegate
where DataSourceType: ResettableRxDataSourceCursor,
DataSourceType.ResultType == [DataSourceType.Element] {
/// Convenient typealias.
typealias PaginationWrapperType = PaginationWrapper<DataSourceType, Self>
}

View File

@ -0,0 +1,58 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Foundation.NSAttributedString
public extension NSAttributedString {
static func + (left: NSAttributedString, right: NSAttributedString) -> NSAttributedString {
let mutableAttributedString = left.mutable
mutableAttributedString += right
return mutableAttributedString.immutable
}
/// Mutable copy of attributed string.
var mutable: NSMutableAttributedString {
return NSMutableAttributedString(attributedString: self)
}
}
public extension NSMutableAttributedString {
static func + (left: NSMutableAttributedString, right: NSAttributedString) -> NSMutableAttributedString {
left.append(right)
return left
}
static func += (left: NSMutableAttributedString, right: NSAttributedString) {
left.append(right)
}
/// Immutable copy of attributed string.
var immutable: NSAttributedString {
return NSAttributedString(attributedString: self)
}
}

View File

@ -111,4 +111,9 @@ public extension TableDirector {
return replace(withSection: TableSection(rows: rows))
}
/// Clear table view and reload it within empty section
func safeClear() {
clear().append(section: TableSection()).reload()
}
}

View File

@ -0,0 +1,41 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import UIKit.UIApplication
public extension UIApplication {
/// Attempt to open telprompt with given phone number.
///
/// - Parameter phoneNumber: Phone number to use in URL.
func attemptPhoneCallWithPrompt(to phoneNumber: String) {
let characterSet = CharacterSet(charactersIn: "+0123456789")
let cleanPhoneNumber = phoneNumber.components(separatedBy: characterSet.inverted).joined(separator: "")
if let escapedPhoneNumber = cleanPhoneNumber.addingPercentEncoding(withAllowedCharacters: characterSet),
let phonePrompt = URL(string: "telprompt://\(escapedPhoneNumber)"),
canOpenURL(phonePrompt) {
support.open(phonePrompt)
}
}
}

View File

@ -0,0 +1,38 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import UIKit.UIApplication
public extension Support where Base: UIApplication {
/// Attempts to open the resource at the specified URL asynchronously.
///
/// - Parameter url: A URL.
func open(_ url: URL) {
if #available(iOS 10.0, tvOS 10.0, *) {
base.open(url)
} else {
base.openURL(url)
}
}
}

View File

@ -0,0 +1,26 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import Foundation
/// Closure that takes no arguments and return Void.
public typealias VoidBlock = () -> Void

View File

@ -0,0 +1,31 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import RxCocoa
/// Events generated by view itself (tap, text changed, etc.).
public protocol TextFieldViewEvents {
/// Emit event when text inside view was changed.
var textChangedDriver: Driver<String?> { get }
}

View File

@ -0,0 +1,31 @@
//
// Copyright (c) 2018 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import RxCocoa
/// Events generated by view model (change text, become first reponder, disable view).
public protocol TextFieldViewModelEvents {
/// Emit event with text that will be inserted inside view.
var setTextDriver: Driver<String?> { get }
}