Merge pull request #118 from TouchInstinct/feature/text_field_view_model
text field view model with bindings
This commit is contained in:
commit
1a34bebe69
44
CHANGELOG.md
44
CHANGELOG.md
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 */,
|
||||
|
|
|
|||
2
Podfile
2
Podfile
|
|
@ -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!
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@ SPEC CHECKSUMS:
|
|||
TableKit: 61880e4c13ac0ba396a308fcb1ae48f6dec8b458
|
||||
UIScrollView-InfiniteScroll: c132d6d5851daff229ab4a1060ccf70a05a051c9
|
||||
|
||||
PODFILE CHECKSUM: 3adf387a63bf042042b4d0cc87828bef873efd2d
|
||||
PODFILE CHECKSUM: ab838edfaeaa5ec185764a2fa042a9b61be1da2a
|
||||
|
||||
COCOAPODS: 1.4.0
|
||||
|
|
|
|||
|
|
@ -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]>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -70,3 +70,12 @@ public extension PaginationWrapperDelegate {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public extension PaginationWrapperDelegate
|
||||
where DataSourceType: ResettableRxDataSourceCursor,
|
||||
DataSourceType.ResultType == [DataSourceType.Element] {
|
||||
|
||||
/// Convenient typealias.
|
||||
typealias PaginationWrapperType = PaginationWrapper<DataSourceType, Self>
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 }
|
||||
|
||||
}
|
||||
|
|
@ -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 }
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue