Compare commits

..

5 Commits

Author SHA1 Message Date
Maxim Sorokin ee60c4730b added cartfile.resolved 2019-09-03 16:24:36 +03:00
Maxim Sorokin 8a920daa1f change cartfile for rebuild with swift 5.1 2019-09-03 02:43:28 +03:00
Maxim Sorokin 2627e464da Revert "setting"
This reverts commit a9fb83c85a.
2019-09-03 02:31:48 +03:00
Maxim Sorokin a9fb83c85a setting 2019-09-03 02:10:21 +03:00
Maxim Sorokin 1493dde3f2 change cartfile for rebuild with swift 5.1 2019-09-03 01:07:28 +03:00
31 changed files with 747 additions and 225 deletions

3
.gitignore vendored
View File

@ -63,6 +63,3 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
# Touch Instinct custom
Downloads/

View File

@ -1,19 +1,5 @@
# Changelog
### 0.4.0
- **Update**: update libraries to build with Xcode 13.1
### 0.3.15
- **Update**: update LeadKit dependency
### 0.3.14
- **Update**: remove Carthage binary dependencies, update build scripts.
### 0.3.13
- **[Breaking change]**: `LabelTableViewCell` moved to `LeadKit`.
- **[Breaking change]**: Removed `PinLayout` dependency.
### 0.3.12
- **Update**: Swift 5 support
@ -142,3 +128,4 @@
## 0.1.0
- **Add**: support for Swift 3.2 / 4

View File

@ -1,5 +1,12 @@
github "krzyzanowskim/CryptoSwift"
github "TouchInstinct/LeadKit"
github "petropavel13/SwiftValidator"
github "kishikawakatsumi/KeychainAccess"
github "layoutBox/PinLayout"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/SwiftDate/SwiftDate.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/LeadKit/LeadKit.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/Alamofire/Alamofire.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/RxAlamofire/RxAlamofire.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/KeychainAccess/KeychainAccess.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/CryptoSwift/CryptoSwift.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/SwiftValidator/SwiftValidator.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/PinLayout/PinLayout.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/TableKit/TableKit.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/RxSwift/RxSwift.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/UIScrollView_InfiniteScroll/UIScrollView_InfiniteScroll.json"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/SnapKit/SnapKit.json"

View File

@ -1,12 +1,12 @@
github "Alamofire/Alamofire" "4.9.1"
github "ReactiveX/RxSwift" "4.5.0"
github "RxSwiftCommunity/RxAlamofire" "4.5.0"
github "SnapKit/SnapKit" "4.2.0"
github "TouchInstinct/LeadKit" "0.9.29"
github "TouchInstinct/TableKit" "2.10008.1"
github "krzyzanowskim/CryptoSwift" "1.3.0"
github "malcommac/SwiftDate" "6.1.0"
github "petropavel13/SwiftValidator" "be856202cd70e6549ebc8c9d07ec47bbff784b07"
github "pronebird/UIScrollView-InfiniteScroll" "1.1.0"
github "kishikawakatsumi/KeychainAccess" "v3.2.0"
github "layoutBox/PinLayout" "1.8.6"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/Alamofire/Alamofire.json" "4.8.1"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/CryptoSwift/CryptoSwift.json" "0.14.0"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/KeychainAccess/KeychainAccess.json" "3.2.0"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/LeadKit/LeadKit.json" "0.9.26"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/PinLayout/PinLayout.json" "1.8.6"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/RxAlamofire/RxAlamofire.json" "4.3.0"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/RxSwift/RxSwift.json" "4.5.0"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/SnapKit/SnapKit.json" "4.2.0"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/SwiftDate/SwiftDate.json" "6.0.3"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/SwiftValidator/SwiftValidator.json" "5.0.0"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/TableKit/TableKit.json" "2.10008.1"
binary "https://raw.github.com/TouchInstinct/CarthageBinaries/rebuild_with_swift_5_1/UIScrollView_InfiniteScroll/UIScrollView_InfiniteScroll.json" "1.1.0"

View File

@ -1,21 +1,22 @@
Pod::Spec.new do |s|
s.name = "LeadKitAdditions"
s.version = "0.4.0"
s.version = "0.3.12"
s.summary = "iOS framework with a bunch of tools for rapid development"
s.homepage = "https://github.com/TouchInstinct/LeadKitAdditions"
s.license = "Apache License, Version 2.0"
s.author = "Touch Instinct"
s.platform = :ios, "10.0"
s.platform = :ios, "9.0"
s.source = { :git => "https://github.com/TouchInstinct/LeadKitAdditions.git", :tag => s.version }
s.subspec 'Core' do |ss|
ss.ios.deployment_target = '10.0'
ss.ios.deployment_target = '9.0'
ss.source_files = "Sources/**/*.swift"
ss.dependency "LeadKit", '~> 1.7.0'
ss.dependency "KeychainAccess", '~> 4.2.0'
ss.dependency "CryptoSwift", '~> 1.4.0'
ss.dependency "LeadKit", '~> 0.9.0'
ss.dependency "KeychainAccess", '3.1.0'
ss.dependency "CryptoSwift", '~> 0.9.0'
ss.dependency "SwiftValidator", '4.0.2'
ss.dependency "PinLayout", '~> 1.6'
end
s.default_subspec = 'Core'

View File

@ -7,12 +7,18 @@
objects = {
/* Begin PBXBuildFile section */
14E3AD49502B3D81264560DB /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EDEF7F6C22BB04CBB754C14 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */; };
6760AF1A207268EC00C2BB7E /* PinLayoutCell+DefaultImplementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6760AF19207268EC00C2BB7E /* PinLayoutCell+DefaultImplementation.swift */; };
67779CBC206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67779CBB206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift */; };
678D26AA206935B900B05B93 /* BiometricsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D26A9206935B900B05B93 /* BiometricsService.swift */; };
67B4E6F6206945DD00E233EA /* OnlineValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F5206945DC00E233EA /* OnlineValidationResult.swift */; };
67B4E6F9206945F900E233EA /* OnlineValidationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F8206945F900E233EA /* OnlineValidationState.swift */; };
67B4E6FB20694A4200E233EA /* BaseTextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F1206945D200E233EA /* BaseTextFieldViewModel.swift */; };
67C2A41620724BBA000A5682 /* SeparatorTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C2A41520724BBA000A5682 /* SeparatorTableViewCell.swift */; };
67C2A41820724EA0000A5682 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C2A41720724EA0000A5682 /* LabelTableViewCell.swift */; };
67C2A41B20724F40000A5682 /* LabelCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C2A41A20724F40000A5682 /* LabelCellViewModel.swift */; };
67C2A41D20725359000A5682 /* LabelTableViewCell+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C2A41C20725359000A5682 /* LabelTableViewCell+Extensions.swift */; };
67CF05AA206E9880009A2AB9 /* PinLayoutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CF05A9206E9880009A2AB9 /* PinLayoutCell.swift */; };
67CF05B0206E99DF009A2AB9 /* PinLayoutTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67CF05AF206E99DF009A2AB9 /* PinLayoutTableViewCell.swift */; };
67D6041821627600002DAF5B /* LegacyConfigurableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D6041721627600002DAF5B /* LegacyConfigurableController.swift */; };
786CBB2F220DD7A70017587F /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB22220DD7A70017587F /* RxSwift.framework */; };
786CBB30220DD7A70017587F /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB23220DD7A70017587F /* Alamofire.framework */; };
@ -20,11 +26,13 @@
786CBB32220DD7A70017587F /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB25220DD7A70017587F /* LeadKit.framework */; };
786CBB33220DD7A70017587F /* SwiftValidator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB26220DD7A70017587F /* SwiftValidator.framework */; };
786CBB34220DD7A70017587F /* UIScrollView_InfiniteScroll.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB27220DD7A70017587F /* UIScrollView_InfiniteScroll.framework */; };
786CBB35220DD7A70017587F /* RxAtomic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB28220DD7A70017587F /* RxAtomic.framework */; };
786CBB36220DD7A70017587F /* RxAlamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB29220DD7A70017587F /* RxAlamofire.framework */; };
786CBB37220DD7A70017587F /* SwiftDate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB2A220DD7A70017587F /* SwiftDate.framework */; };
786CBB38220DD7A70017587F /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB2B220DD7A70017587F /* RxCocoa.framework */; };
786CBB39220DD7A70017587F /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB2C220DD7A70017587F /* CryptoSwift.framework */; };
786CBB3A220DD7A70017587F /* KeychainAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB2D220DD7A70017587F /* KeychainAccess.framework */; };
786CBB3B220DD7A70017587F /* PinLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 786CBB2E220DD7A70017587F /* PinLayout.framework */; };
A6CFB8D91F5024A500A42CC2 /* Error+NetworkingExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6CFB8D81F5024A500A42CC2 /* Error+NetworkingExtensions.swift */; };
CAE698E81E968820000394B0 /* LeadKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE698E61E968820000394B0 /* LeadKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
ED0C34071F2906EC00FAE9FD /* LoadingBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33D51F2906EC00FAE9FD /* LoadingBarButton.swift */; };
@ -46,22 +54,27 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1AC235099AA10D83D608A253 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig"; path = "Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS/Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig"; sourceTree = "<group>"; };
3EDEF7F6C22BB04CBB754C14 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
67528BCE206E3CC6009F2525 /* iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = iOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
6760AF19207268EC00C2BB7E /* PinLayoutCell+DefaultImplementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PinLayoutCell+DefaultImplementation.swift"; sourceTree = "<group>"; };
67779CBB206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BaseTextFieldViewEvents+Extensions.swift"; sourceTree = "<group>"; };
678D26A9206935B900B05B93 /* BiometricsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BiometricsService.swift; sourceTree = "<group>"; };
67B4E6F1206945D200E233EA /* BaseTextFieldViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTextFieldViewModel.swift; sourceTree = "<group>"; };
67B4E6F5206945DC00E233EA /* OnlineValidationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnlineValidationResult.swift; sourceTree = "<group>"; };
67B4E6F8206945F900E233EA /* OnlineValidationState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnlineValidationState.swift; sourceTree = "<group>"; };
67C2A41520724BBA000A5682 /* SeparatorTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorTableViewCell.swift; sourceTree = "<group>"; };
67C2A41720724EA0000A5682 /* LabelTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelTableViewCell.swift; sourceTree = "<group>"; };
67C2A41A20724F40000A5682 /* LabelCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelCellViewModel.swift; sourceTree = "<group>"; };
67C2A41C20725359000A5682 /* LabelTableViewCell+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LabelTableViewCell+Extensions.swift"; sourceTree = "<group>"; };
67CF05A9206E9880009A2AB9 /* PinLayoutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinLayoutCell.swift; sourceTree = "<group>"; };
67CF05AF206E99DF009A2AB9 /* PinLayoutTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinLayoutTableViewCell.swift; sourceTree = "<group>"; };
67D6041721627600002DAF5B /* LegacyConfigurableController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyConfigurableController.swift; sourceTree = "<group>"; };
6FEE03727D0B955F00DE8429 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig"; path = "Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS/Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig"; sourceTree = "<group>"; };
786CBB22220DD7A70017587F /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = Carthage/Build/iOS/RxSwift.framework; sourceTree = "<group>"; };
786CBB23220DD7A70017587F /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = "<group>"; };
786CBB24220DD7A70017587F /* TableKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TableKit.framework; path = Carthage/Build/iOS/TableKit.framework; sourceTree = "<group>"; };
786CBB25220DD7A70017587F /* LeadKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LeadKit.framework; path = Carthage/Build/iOS/LeadKit.framework; sourceTree = "<group>"; };
786CBB26220DD7A70017587F /* SwiftValidator.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftValidator.framework; path = Carthage/Build/iOS/SwiftValidator.framework; sourceTree = "<group>"; };
786CBB27220DD7A70017587F /* UIScrollView_InfiniteScroll.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIScrollView_InfiniteScroll.framework; path = Carthage/Build/iOS/UIScrollView_InfiniteScroll.framework; sourceTree = "<group>"; };
786CBB28220DD7A70017587F /* RxAtomic.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxAtomic.framework; path = Carthage/Build/iOS/RxAtomic.framework; sourceTree = "<group>"; };
786CBB29220DD7A70017587F /* RxAlamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxAlamofire.framework; path = Carthage/Build/iOS/RxAlamofire.framework; sourceTree = "<group>"; };
786CBB2A220DD7A70017587F /* SwiftDate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftDate.framework; path = Carthage/Build/iOS/SwiftDate.framework; sourceTree = "<group>"; };
786CBB2B220DD7A70017587F /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = Carthage/Build/iOS/RxCocoa.framework; sourceTree = "<group>"; };
@ -102,18 +115,29 @@
786CBB32220DD7A70017587F /* LeadKit.framework in Frameworks */,
786CBB33220DD7A70017587F /* SwiftValidator.framework in Frameworks */,
786CBB34220DD7A70017587F /* UIScrollView_InfiniteScroll.framework in Frameworks */,
786CBB35220DD7A70017587F /* RxAtomic.framework in Frameworks */,
786CBB36220DD7A70017587F /* RxAlamofire.framework in Frameworks */,
786CBB37220DD7A70017587F /* SwiftDate.framework in Frameworks */,
786CBB38220DD7A70017587F /* RxCocoa.framework in Frameworks */,
786CBB39220DD7A70017587F /* CryptoSwift.framework in Frameworks */,
786CBB3A220DD7A70017587F /* KeychainAccess.framework in Frameworks */,
14E3AD49502B3D81264560DB /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework in Frameworks */,
786CBB3B220DD7A70017587F /* PinLayout.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
67528BCB206E3C12009F2525 /* Cells */ = {
isa = PBXGroup;
children = (
67C2A41920724F32000A5682 /* LabelTableViewCell */,
67CF05AF206E99DF009A2AB9 /* PinLayoutTableViewCell.swift */,
67C2A41520724BBA000A5682 /* SeparatorTableViewCell.swift */,
);
path = Cells;
sourceTree = "<group>";
};
67B4E6F0206945D200E233EA /* BaseTextFieldViewModel */ = {
isa = PBXGroup;
children = (
@ -130,6 +154,32 @@
path = ValidationService;
sourceTree = "<group>";
};
67C2A41920724F32000A5682 /* LabelTableViewCell */ = {
isa = PBXGroup;
children = (
67C2A41720724EA0000A5682 /* LabelTableViewCell.swift */,
67C2A41A20724F40000A5682 /* LabelCellViewModel.swift */,
);
path = LabelTableViewCell;
sourceTree = "<group>";
};
67CF05A8206E986A009A2AB9 /* Cells */ = {
isa = PBXGroup;
children = (
67CF05A9206E9880009A2AB9 /* PinLayoutCell.swift */,
);
path = Cells;
sourceTree = "<group>";
};
67CF05AC206E9931009A2AB9 /* Cells */ = {
isa = PBXGroup;
children = (
67C2A41C20725359000A5682 /* LabelTableViewCell+Extensions.swift */,
6760AF19207268EC00C2BB7E /* PinLayoutCell+DefaultImplementation.swift */,
);
path = Cells;
sourceTree = "<group>";
};
A3117951840B8B7D2E7A8A80 /* Frameworks */ = {
isa = PBXGroup;
children = (
@ -139,13 +189,13 @@
786CBB25220DD7A70017587F /* LeadKit.framework */,
786CBB2E220DD7A70017587F /* PinLayout.framework */,
786CBB29220DD7A70017587F /* RxAlamofire.framework */,
786CBB28220DD7A70017587F /* RxAtomic.framework */,
786CBB2B220DD7A70017587F /* RxCocoa.framework */,
786CBB22220DD7A70017587F /* RxSwift.framework */,
786CBB2A220DD7A70017587F /* SwiftDate.framework */,
786CBB26220DD7A70017587F /* SwiftValidator.framework */,
786CBB24220DD7A70017587F /* TableKit.framework */,
786CBB27220DD7A70017587F /* UIScrollView_InfiniteScroll.framework */,
3EDEF7F6C22BB04CBB754C14 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -157,7 +207,6 @@
CAE698E41E968820000394B0 /* Products */,
CAE698E51E968820000394B0 /* Sources */,
67528BCE206E3CC6009F2525 /* iOS.playground */,
FBC34E01DAB566B85ED77BAD /* Pods */,
);
sourceTree = "<group>";
};
@ -187,6 +236,7 @@
ED0C33D21F2906EC00FAE9FD /* Classes */ = {
isa = PBXGroup;
children = (
67528BCB206E3C12009F2525 /* Cells */,
67B4E6F0206945D200E233EA /* BaseTextFieldViewModel */,
ED0C33D51F2906EC00FAE9FD /* LoadingBarButton.swift */,
);
@ -243,6 +293,7 @@
ED0C33E61F2906EC00FAE9FD /* Extensions */ = {
isa = PBXGroup;
children = (
67CF05AC206E9931009A2AB9 /* Cells */,
ED0C33E81F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift */,
ED0C33E91F2906EC00FAE9FD /* UserDefaults+UserService.swift */,
A6CFB8D81F5024A500A42CC2 /* Error+NetworkingExtensions.swift */,
@ -254,6 +305,7 @@
ED0C33EA1F2906EC00FAE9FD /* Protocols */ = {
isa = PBXGroup;
children = (
67CF05A8206E986A009A2AB9 /* Cells */,
67B4E6F4206945DC00E233EA /* ValidationService */,
67D6041721627600002DAF5B /* LegacyConfigurableController.swift */,
);
@ -282,15 +334,6 @@
path = ValidationService;
sourceTree = "<group>";
};
FBC34E01DAB566B85ED77BAD /* Pods */ = {
isa = PBXGroup;
children = (
6FEE03727D0B955F00DE8429 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */,
1AC235099AA10D83D608A253 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -309,7 +352,6 @@
isa = PBXNativeTarget;
buildConfigurationList = CAE698EB1E968820000394B0 /* Build configuration list for PBXNativeTarget "LeadKitAdditions iOS" */;
buildPhases = (
DA96E76177E2633117FCBE55 /* [CP] Check Pods Manifest.lock */,
CAE698DE1E968820000394B0 /* Sources */,
CAE698DF1E968820000394B0 /* Frameworks */,
CAE698E01E968820000394B0 /* Headers */,
@ -382,29 +424,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = ". run_swiftlint.sh\n";
};
DA96E76177E2633117FCBE55 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-LeadKitAdditions-LeadKitAdditions iOS-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
shellScript = "CONFIG_PATH=${PROJECT_DIR}/build-scripts/xcode/.swiftlint.yml\n\nif which swiftlint >/dev/null; then\nswiftlint autocorrect --path Sources --config ${CONFIG_PATH} && swiftlint --path Sources --config ${CONFIG_PATH}\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@ -419,22 +439,29 @@
ED0C343F1F2906EC00FAE9FD /* ValidationError.swift in Sources */,
ED0C342F1F2906EC00FAE9FD /* BaseUserService.swift in Sources */,
678D26AA206935B900B05B93 /* BiometricsService.swift in Sources */,
67C2A41D20725359000A5682 /* LabelTableViewCell+Extensions.swift in Sources */,
ED0C34411F2906EC00FAE9FD /* ValidationItem.swift in Sources */,
ED0C341F1F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */,
67C2A41820724EA0000A5682 /* LabelTableViewCell.swift in Sources */,
ED0C34091F2906EC00FAE9FD /* PassCodeConfiguration.swift in Sources */,
EF5A43B1206E7A67003CED07 /* PassCodeDelayedDescription.swift in Sources */,
67CF05B0206E99DF009A2AB9 /* PinLayoutTableViewCell.swift in Sources */,
ED0C34131F2906EC00FAE9FD /* BasePassCodeViewController.swift in Sources */,
67C2A41620724BBA000A5682 /* SeparatorTableViewCell.swift in Sources */,
ED0C342D1F2906EC00FAE9FD /* BasePassCodeService.swift in Sources */,
67B4E6F9206945F900E233EA /* OnlineValidationState.swift in Sources */,
67779CBC206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift in Sources */,
ED0C340D1F2906EC00FAE9FD /* PassCodeHolder.swift in Sources */,
67CF05AA206E9880009A2AB9 /* PinLayoutCell.swift in Sources */,
A6CFB8D91F5024A500A42CC2 /* Error+NetworkingExtensions.swift in Sources */,
ED0C34071F2906EC00FAE9FD /* LoadingBarButton.swift in Sources */,
6760AF1A207268EC00C2BB7E /* PinLayoutCell+DefaultImplementation.swift in Sources */,
ED0C34211F2906EC00FAE9FD /* UserDefaults+UserService.swift in Sources */,
ED0C34111F2906EC00FAE9FD /* PassCodeValidationResult.swift in Sources */,
ED0C34431F2906EC00FAE9FD /* ValidationService.swift in Sources */,
ED0C340B1F2906EC00FAE9FD /* PassCodeError.swift in Sources */,
67B4E6F6206945DD00E233EA /* OnlineValidationResult.swift in Sources */,
67C2A41B20724F40000A5682 /* LabelCellViewModel.swift in Sources */,
ED0C34151F2906EC00FAE9FD /* BasePassCodeViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -563,7 +590,6 @@
};
CAE698EC1E968820000394B0 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6FEE03727D0B955F00DE8429 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
@ -573,9 +599,13 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "touchinstinct.LeadKitAdditions-iOS";
PRODUCT_NAME = LeadKitAdditions;
@ -588,7 +618,6 @@
};
CAE698ED1E968820000394B0 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1AC235099AA10D83D608A253 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
@ -598,9 +627,13 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "touchinstinct.LeadKitAdditions-iOS";
PRODUCT_NAME = LeadKitAdditions;

12
Podfile
View File

@ -1,20 +1,20 @@
source 'https://cdn.cocoapods.org/'
source "https://github.com/CocoaPods/Specs.git"
source "https://github.com/TouchInstinct/Podspecs.git"
abstract_target 'LeadKitAdditions' do
pod "KeychainAccess", '~> 4.2.0'
pod "CryptoSwift", "~> 1.4.0"
pod "KeychainAccess", '3.1.0'
pod "CryptoSwift", "~> 0.9.0"
pod "SwiftValidator", '4.0.2'
pod "SwiftLint", '~> 0.45.0'
pod "SwiftLint", '~> 0.25'
pod "PinLayout", '~> 1.6'
inhibit_all_warnings!
use_frameworks!
target 'LeadKitAdditions iOS' do
platform :ios, '10.0'
platform :ios, '9.0'
pod 'LeadKit', '~> 1.7.0'
pod 'LeadKit', '~> 0.9.0'
end
end

View File

@ -1,81 +1,78 @@
PODS:
- Alamofire (5.5.0)
- CryptoSwift (1.4.2)
- KeychainAccess (4.2.2)
- LeadKit (1.7.0):
- LeadKit/Core (= 1.7.0)
- LeadKit/Core (1.7.0):
- RxAlamofire (~> 6.1)
- RxCocoa (~> 6.2)
- RxSwift (~> 6.2)
- SnapKit (~> 5.0.1)
- SwiftDate (~> 6)
- TableKit (~> 2.11)
- Alamofire (4.7.3)
- CryptoSwift (0.9.0)
- KeychainAccess (3.1.0)
- LeadKit (0.9.0):
- LeadKit/Core (= 0.9.0)
- LeadKit/Core (0.9.0):
- RxAlamofire (~> 4.3)
- RxCocoa (~> 4.3)
- RxSwift (~> 4.3)
- SwiftDate (~> 5.0)
- TableKit (~> 2.8)
- UIScrollView-InfiniteScroll (~> 1.1.0)
- LeadKit/Core-iOS-Extension (0.9.0):
- RxAlamofire (~> 4.3)
- RxCocoa (~> 4.3)
- RxSwift (~> 4.3)
- SwiftDate (~> 5.0)
- TableKit (~> 2.8)
- PinLayout (1.8.6)
- RxAlamofire (6.1.1):
- RxAlamofire/Core (= 6.1.1)
- RxAlamofire/Core (6.1.1):
- Alamofire (~> 5.4)
- RxSwift (~> 6.0)
- RxCocoa (6.2.0):
- RxRelay (= 6.2.0)
- RxSwift (= 6.2.0)
- RxRelay (6.2.0):
- RxSwift (= 6.2.0)
- RxSwift (6.2.0)
- SnapKit (5.0.1)
- SwiftDate (6.3.1)
- SwiftLint (0.45.1)
- RxAlamofire (4.3.0):
- RxAlamofire/Core (= 4.3.0)
- RxAlamofire/Core (4.3.0):
- Alamofire (~> 4.5)
- RxSwift (~> 4)
- RxCocoa (4.3.1):
- RxSwift (~> 4.0)
- RxSwift (4.3.1)
- SwiftDate (5.0.10)
- SwiftLint (0.27.0)
- SwiftValidator (4.0.2)
- TableKit (2.11.0)
- TableKit (2.8.0)
- UIScrollView-InfiniteScroll (1.1.0)
DEPENDENCIES:
- CryptoSwift (~> 1.4.0)
- KeychainAccess (~> 4.2.0)
- LeadKit (~> 1.7.0)
- CryptoSwift (~> 0.9.0)
- KeychainAccess (= 3.1.0)
- LeadKit (~> 0.9.0)
- LeadKit/Core-iOS-Extension (~> 0.9.0)
- PinLayout (~> 1.6)
- SwiftLint (~> 0.45.0)
- SwiftLint (~> 0.25)
- SwiftValidator (= 4.0.2)
SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
- PinLayout
https://github.com/TouchInstinct/Podspecs.git:
- LeadKit
- SwiftValidator
trunk:
https://github.com/cocoapods/specs.git:
- Alamofire
- CryptoSwift
- KeychainAccess
- PinLayout
- RxAlamofire
- RxCocoa
- RxRelay
- RxSwift
- SnapKit
- SwiftDate
- SwiftLint
- TableKit
- UIScrollView-InfiniteScroll
https://github.com/TouchInstinct/Podspecs.git:
- LeadKit
- SwiftValidator
SPEC CHECKSUMS:
Alamofire: 1c4fb5369c3fe93d2857c780d8bbe09f06f97e7c
CryptoSwift: a532e74ed010f8c95f611d00b8bbae42e9fe7c17
KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51
LeadKit: e5765a6edac2813042304e940fd7a43b37be80ca
Alamofire: c7287b6e5d7da964a70935e5db17046b7fde6568
CryptoSwift: bca8c5b653dcc2d9734409242a070ff53bafac86
KeychainAccess: 94c5540b32eabf7bc32bfb976a268e8ea05fd6da
LeadKit: 80787b6215648cf9bfedf2c591fbe924ba4940a1
PinLayout: fe2a2432d6982588e208572005c941aeeae417ab
RxAlamofire: beb75a1c452d0de225651db4903f5d29d034a620
RxCocoa: 4baf94bb35f2c0ab31bc0cb9f1900155f646ba42
RxRelay: e72dbfd157807478401ef1982e1c61c945c94b2f
RxSwift: d356ab7bee873611322f134c5f9ef379fa183d8f
SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
SwiftDate: 72d28954e8e1c6c1c0f917ccc8005e4f83c7d4b2
SwiftLint: 06ac37e4d38c7068e0935bb30cda95f093bec761
RxAlamofire: 09624d0f2d48ed8b686e4eb4cf68e28cbd2df556
RxCocoa: 78763c7b07d02455598d9fc3c1ad091a28b73635
RxSwift: fe0fd770a43acdb7d0a53da411c9b892e69bb6e4
SwiftDate: fcdaa7ca22a903faf6d7ed231239a88d174dcae3
SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073
SwiftValidator: 8517a67bceebd7286cb487da259db7dd44c5fc74
TableKit: 8a1a267d841a2da638ea09bdb0db33aedb459fa8
TableKit: d635663343d00e209f258e35d4ee0072ad1beb1a
UIScrollView-InfiniteScroll: 3ef456bcbe759c19f510a383cff96e6647c98c98
PODFILE CHECKSUM: 1d0f91b670998d56b8cf9bc24d5b265a89e8409b
PODFILE CHECKSUM: 447350715f27bad97492296a2ed066c844cfaf5a
COCOAPODS: 1.10.1
COCOAPODS: 1.6.0.beta.2

View File

@ -99,13 +99,14 @@ public extension BaseTextFieldViewModelEvents {
using offlineRules: [Rule] = [],
validationClosure: @escaping OnlineValidationClosure) -> Driver<OnlineValidationState> {
textDriver.flatMap { string -> Driver<OnlineValidationState> in
return textDriver.flatMap { string -> Driver<OnlineValidationState> in
guard let nonEmptyString = string, !nonEmptyString.isEmpty else {
return .just(.initial)
}
let passedRules = offlineRules
.allSatisfy { $0.validate(nonEmptyString) }
.map { $0.validate(nonEmptyString) }
.reduce(true) { $0 && $1 }
guard passedRules else {
return .just(.initial)
@ -136,7 +137,7 @@ public extension BaseTextFieldViewModelEvents {
rules: [Rule] = [RequiredRule()],
validationService: ValidationService,
onlineValidationClosure: OnlineValidationClosure? = nil,
onlineValidationThrottle: RxTimeInterval = .milliseconds(500)) {
onlineValidationThrottle: RxTimeInterval = 0.5) {
let dataModelFieldDriver = binding.fieldDriver

View File

@ -0,0 +1,55 @@
//
// 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.UIGeometry
import LeadKit
/// Default view model for LabelTableViewCell.
open class LabelCellViewModel {
public let viewText: ViewText
public let contentBackground: ViewBackground
public let contentInsets: UIEdgeInsets
public let labelInsets: UIEdgeInsets
public let separatorType: CellSeparatorType
/// Memberwise initializer.
///
/// - Parameters:
/// - viewText: View text to configure label.
/// - contentBackground: View background to configure background.
/// - contentInsets: Content insets to use for layout whole content.
/// - labelInsets: Label insets to use for layout label.
/// - separatorType: Separator type to use for separators.
public init(viewText: ViewText,
contentBackground: ViewBackground = .color(.clear),
contentInsets: UIEdgeInsets = .zero,
labelInsets: UIEdgeInsets = .zero,
separatorType: CellSeparatorType = .none) {
self.viewText = viewText
self.contentBackground = contentBackground
self.contentInsets = contentInsets
self.labelInsets = labelInsets
self.separatorType = separatorType
}
}

View File

@ -0,0 +1,139 @@
//
// 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
import LeadKit
import PinLayout
/// Pin layout cell with separators, background and label.
open class LabelTableViewCell: SeparatorTableViewCell {
private let label = UILabel(frame: .zero)
private let backgroundImageView = UIImageView(frame: .zero)
private let contentContainerView = UIView(frame: .zero)
private var viewModel: LabelCellViewModel?
// MARK: - PinLayoutTableViewCell
override open func addViews() {
super.addViews()
contentContainerView.addSubviews(backgroundImageView, label)
contentView.addSubview(contentContainerView)
}
override open func configureAppearance() {
super.configureAppearance()
selectionStyle = .none
backgroundColor = .clear
contentView.backgroundColor = .clear
configureAppearance(of: label, backgroundImageView: backgroundImageView)
}
override open func layout() {
let topSeparatorHeight = viewModel?.separatorType.topConfiguration?.totalHeight ?? 0
let bottomSeparatorHeight = viewModel?.separatorType.bottomConfiguration?.totalHeight ?? 0
contentContainerView.pin
.top(topSeparatorHeight + contentInsets.top)
.horizontally(contentInsets)
.bottom(contentInsets.bottom + bottomSeparatorHeight)
.layout()
label.pin
.top(labelInsets)
.horizontally(labelInsets)
.sizeToFit(.width)
.layout()
backgroundImageView.pin
.all()
.layout()
// bottom separator positioning after content size (height) calculation
super.layout()
}
private var labelInsets: UIEdgeInsets {
return viewModel?.labelInsets ?? .zero
}
private var contentInsets: UIEdgeInsets {
return viewModel?.contentInsets ?? .zero
}
override open var contentHeight: CGFloat {
let selfContentHeight = contentInsets.top +
labelInsets.top +
label.frame.height +
labelInsets.bottom +
contentInsets.bottom
return selfContentHeight + super.contentHeight
}
// MARK: - Subclass methods to override
/// Callback for label and background image view appearance configuration.
///
/// - Parameters:
/// - label: Internal UILabel instance to configure.
/// - backgroundImageView: Internal UIImageView instance to configure.
open func configureAppearance(of label: UILabel, backgroundImageView: UIImageView) {
label.numberOfLines = 0
}
// MARK: - Configuration methods
/// Convenient method for configuration cell with LabelCellViewModel.
///
/// - Parameter viewModel: LabelCellViewModel instance.
public func configureLabelCell(with viewModel: LabelCellViewModel) {
self.viewModel = viewModel
configureSeparator(with: viewModel.separatorType)
configureLabelText(with: viewModel.viewText)
configureContentBackground(with: viewModel.contentBackground)
setNeedsLayout()
}
/// Method for background configuration.
///
/// - Parameter contentBackground: Content background to use as background.
public func configureContentBackground(with contentBackground: ViewBackground) {
contentBackground.configure(backgroundView: contentContainerView,
backgroundImageView: backgroundImageView)
}
/// Method for text configuration.
///
/// - Parameter viewText: View text to use as background.
public func configureLabelText(with viewText: ViewText) {
label.configure(with: viewText)
}
}

View File

@ -0,0 +1,102 @@
//
// 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
import PinLayout
/// Cell that uses PinLayout. Contains methods that should be overriden in subclasses.
open class PinLayoutTableViewCell: UITableViewCell, PinLayoutCell {
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
initializeCell()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initializeCell()
}
open override func sizeThatFits(_ size: CGSize) -> CGSize {
return layout(with: size)
}
open override func layoutSubviews() {
super.layoutSubviews()
layout()
}
// MARK: - PinLayoutCell
open func initializeCell() {
addViews()
configureAppearance()
configureLayout()
}
open func layout(with containerSize: CGSize) -> CGSize {
// 1) Set the contentView's width to the specified size parameter
contentView.pin.width(containerSize.width).layout()
// 2) Layout the contentView's controls
layout()
// 3) Returns a size that contains all controls
return CGSize(width: contentView.frame.width,
height: contentHeight)
}
open func addViews() {
// override in subclass
// move from _UISnapshotWindow superview in Playground
addSubview(contentView)
}
open func configureAppearance() {
// override in subclass
}
open func configureLayout() {
// override in subclass
}
open func layout() {
// override in subclass
}
open var contentHeight: CGFloat {
return contentView.subviewsMaxY
}
}
private extension UIView {
var subviewsMaxY: CGFloat {
return subviews
.map { $0.frame.maxY }
.max() ?? frame.maxY
}
}

View File

@ -0,0 +1,102 @@
//
// 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
import LeadKit
import PinLayout
/// Pin layout cell with top and bottom separators.
open class SeparatorTableViewCell: PinLayoutTableViewCell {
private let topSeparator = UIView(frame: .zero)
private let bottomSeparator = UIView(frame: .zero)
private var separatorType: CellSeparatorType = .none
/// Configure separator with viewModel.
/// - parameter separatorType: type of separators.
public func configureSeparator(with separatorType: CellSeparatorType) {
self.separatorType = separatorType
separatorType.configure(topSeparatorView: topSeparator,
bottomSeparatorView: bottomSeparator)
setNeedsLayout()
}
/// Move separator upward in hierarchy
public func bringSeparatorsToFront() {
contentView.bringSubviewToFront(topSeparator)
contentView.bringSubviewToFront(bottomSeparator)
}
/// Move separator backward in hierarchy
public func sendSeparatorsToBack() {
contentView.sendSubviewToBack(topSeparator)
contentView.sendSubviewToBack(bottomSeparator)
}
// MARK: - PinLayoutTableViewCell
override open func addViews() {
super.addViews()
contentView.addSubviews(topSeparator, bottomSeparator)
}
override open func layout() {
super.layout()
if let topConfiguration = separatorType.topConfiguration {
topSeparator.pin
.top(topConfiguration.insets)
.horizontally(topConfiguration.insets)
.height(topConfiguration.height)
.layout()
}
if let bottomConfiguration = separatorType.bottomConfiguration {
let topInset = contentHeight - (bottomConfiguration.height + bottomConfiguration.insets.bottom)
bottomSeparator.pin
.top(topInset)
.horizontally(bottomConfiguration.insets)
.height(bottomConfiguration.height)
.layout()
}
}
override open var contentHeight: CGFloat {
let topSeparatorHeight = separatorType.topConfiguration?.totalHeight ?? 0
let bottomSeparatorHeight = separatorType.bottomConfiguration?.totalHeight ?? 0
return topSeparatorHeight + bottomSeparatorHeight
}
// MARK: - UITableViewCell
override open func prepareForReuse() {
super.prepareForReuse()
configureSeparator(with: .none)
}
}

View File

@ -93,8 +93,8 @@ public extension Observable {
- Returns:
- observable, that handles LoadingBarButton behaviour
*/
func changeLoadingUI(using barButton: LoadingBarButton) -> Observable<Observable.Element> {
observe(on: MainScheduler.instance)
func changeLoadingUI(using barButton: LoadingBarButton) -> Observable<Observable.E> {
return observeOn(MainScheduler.instance)
.do(onSubscribe: {
barButton.setState(waiting: true)
}, onDispose: {

View File

@ -40,6 +40,6 @@ public struct PassCodeConfiguration {
/// Returns configuration with default values
public static var defaultConfiguration: PassCodeConfiguration {
PassCodeConfiguration()
return PassCodeConfiguration()
}
}

View File

@ -26,15 +26,15 @@ import RxCocoa
public extension PassCodeHolderProtocol {
var passCodeHolderCreate: PassCodeHolderCreate? {
self as? PassCodeHolderCreate
return self as? PassCodeHolderCreate
}
var passCodeHolderEnter: PassCodeHolderEnter? {
self as? PassCodeHolderEnter
return self as? PassCodeHolderEnter
}
var passCodeHolderChange: PassCodeHolderChange? {
self as? PassCodeHolderChange
return self as? PassCodeHolderChange
}
}
@ -55,7 +55,7 @@ public class PassCodeHolderCreate: PassCodeHolderProtocol {
}
public var shouldValidate: Bool {
firstPassCode != nil && secondPassCode != nil
return firstPassCode != nil && secondPassCode != nil
}
public var passCode: String? {
@ -100,7 +100,7 @@ public class PassCodeHolderEnter: PassCodeHolderProtocol {
public let enterStep: PassCodeControllerState = .enter
public var shouldValidate: Bool {
passCode != nil
return passCode != nil
}
public var passCode: String?
@ -153,7 +153,7 @@ public class PassCodeHolderChange: PassCodeHolderProtocol {
public var passCode: String? {
switch (oldPassCode, newFirstPassCode, newSecondPassCode) {
case let (oldPassCode?, nil, nil):
case (let oldPassCode?, nil, nil):
return oldPassCode
case (_, _?, nil):

View File

@ -201,8 +201,7 @@ open class BasePassCodeViewController: UIViewController, LegacyConfigurableContr
.sorted { $0.delay < $1.delay }
.map { [weak self] delayedDescription in
Observable<Int>
.interval(.seconds(Int(delayedDescription.delay)),
scheduler: MainScheduler.instance)
.interval(delayedDescription.delay, scheduler: MainScheduler.instance)
.take(1)
.do(onNext: { _ in
self?.errorLabel?.attributedText = delayedDescription.description
@ -261,7 +260,7 @@ open class BasePassCodeViewController: UIViewController, LegacyConfigurableContr
self?.setStates(for: text ?? "")
self?.hideError()
})
.delay(.milliseconds(100)) // time to draw dots
.delay(0.1) // time to draw dots
.drive(onNext: { [weak self] text in
self?.viewModel.setPassCodeText(text)
})

View File

@ -20,6 +20,7 @@
// THE SOFTWARE.
//
import LeadKit
import RxSwift
import RxCocoa
@ -30,7 +31,7 @@ public enum PassCodeAuthType {
}
/// Base view model for passCodeViewController
open class BasePassCodeViewModel {
open class BasePassCodeViewModel: BaseViewModel {
public let operationType: PassCodeOperationType
@ -42,17 +43,17 @@ open class BasePassCodeViewModel {
/// Contains configuration for pass code operations
public let passCodeConfiguration: PassCodeConfiguration
private let validationResultHolder = BehaviorRelay<PassCodeValidationResult?>(value: nil)
private let validationResultHolder = Variable<PassCodeValidationResult?>(nil)
public var validationResultDriver: Driver<PassCodeValidationResult?> {
validationResultHolder.asDriver()
return validationResultHolder.asDriver()
}
private let passCodeControllerStateVariable = BehaviorRelay<PassCodeControllerState>(value: .enter)
private let passCodeControllerStateVariable = Variable<PassCodeControllerState>(.enter)
public var passCodeControllerStateDriver: Driver<PassCodeControllerState> {
passCodeControllerStateVariable.asDriver()
return passCodeControllerStateVariable.asDriver()
}
private let passCodeText = BehaviorRelay<String?>(value: nil)
private let passCodeText = Variable<String?>(nil)
private var attemptsNumber = 0
@ -84,17 +85,17 @@ open class BasePassCodeViewModel {
// MARK: - Public
public var passCodeTextValue: String? {
passCodeText.value
return passCodeText.value
}
public func setPassCodeText(_ value: String?) {
passCodeText.accept(value)
passCodeText.value = value
}
public func reset() {
passCodeText.accept(nil)
validationResultHolder.accept(nil)
passCodeControllerStateVariable.accept(operationType == .change ? .oldEnter : .enter)
passCodeText.value = nil
validationResultHolder.value = nil
passCodeControllerStateVariable.value = operationType == .change ? .oldEnter : .enter
attemptsNumber = 0
passCodeHolder.reset()
}
@ -135,7 +136,7 @@ open class BasePassCodeViewModel {
/// Posibility to use biometrics for authentication
open var isBiometricsEnabled: Bool {
false
return false
}
/// Notify about activation for biometrics. Remember to save user choice
@ -152,7 +153,7 @@ open class BasePassCodeViewModel {
private extension BasePassCodeViewModel {
var validationResultBinder: Binder<PassCodeValidationResult?> {
Binder(self) { model, validationResult in
return Binder(self) { model, validationResult in
let isValid = validationResult?.isValid ?? false
let passCode = validationResult?.passCode
@ -160,13 +161,13 @@ private extension BasePassCodeViewModel {
if isValid, model.passCodeHolder.enterStep == .repeatEnter, let passCode = passCode {
model.authSucceed(.passCode(passCode))
} else {
model.passCodeControllerStateVariable.accept(model.passCodeHolder.enterStep)
model.passCodeControllerStateVariable.value = model.passCodeHolder.enterStep
}
} else {
if isValid, let passCode = passCode {
model.authSucceed(.passCode(passCode))
} else {
model.passCodeControllerStateVariable.accept(model.passCodeHolder.enterStep)
model.passCodeControllerStateVariable.value = model.passCodeHolder.enterStep
}
}
}
@ -180,12 +181,12 @@ extension BasePassCodeViewModel {
validateIfNeeded()
if shouldUpdateControllerState {
passCodeControllerStateVariable.accept(passCodeHolder.enterStep)
passCodeControllerStateVariable.value = passCodeHolder.enterStep
}
}
private var shouldUpdateControllerState: Bool {
!passCodeHolder.shouldValidate ||
return !passCodeHolder.shouldValidate ||
!(validationResultHolder.value?.isValid ?? true) ||
validationResultHolder.value?.error?.isTooManyAttempts ?? false
}
@ -230,6 +231,6 @@ extension BasePassCodeViewModel {
passCodeHolder.reset()
}
validationResultHolder.accept(validationResult)
validationResultHolder.value = validationResult
}
}

View File

@ -0,0 +1,30 @@
//
// 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 TableKit
extension LabelTableViewCell: ConfigurableCell {
public func configure(with viewModel: LabelCellViewModel) {
configureLabelCell(with: viewModel)
}
}

View File

@ -0,0 +1,32 @@
//
// 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
public extension PinLayoutCell {
func initializeCell() {
addViews()
configureAppearance()
configureLayout()
}
}

View File

@ -15,6 +15,6 @@ public extension Error {
/// Returns: true if server json response is not valid
var isResponseSerializationError: Bool {
(self as? AFError)?.isResponseSerializationError ?? false
return (self as? AFError)?.isResponseSerializationError ?? false
}
}

View File

@ -32,7 +32,7 @@ public extension UserDefaults {
/// Default place to store session id
var sessionId: String? {
get {
string(forKey: Keys.sessionId)
return string(forKey: Keys.sessionId)
}
set {
set(newValue, forKey: Keys.sessionId)
@ -42,7 +42,7 @@ public extension UserDefaults {
/// Default place to store userLogin
var userLogin: String? {
get {
string(forKey: Keys.userLogin)
return string(forKey: Keys.userLogin)
}
set {
set(newValue, forKey: Keys.userLogin)

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.3.13</string>
<string>0.3.12</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>

View File

@ -0,0 +1,59 @@
//
// 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 CoreGraphics.CGBase
/// Protocol with methods for configuration and layout cell.
public protocol PinLayoutCell {
/// Method is called when cell initialized from nib or from code.
func initializeCell()
/// Method for adding subviews to content view.
///
/// - Returns: Nothing.
func addViews()
/// Method for cofiguring appearance of views.
///
/// - Returns: Nothing.
func configureAppearance()
/// Method for cofiguring layout and layout properties.
///
/// - Returns: Nothing.
func configureLayout()
/// Method is called during layout calls.
///
/// - Returns: Nothing.
func layout()
/// Method for calculating best-fitting cell size.
///
/// - Parameter containerSize: The size for which the view should calculate its best-fitting size.
/// - Returns: Best-fitting size.
func layout(with containerSize: CGSize) -> CGSize
/// Current content height.
var contentHeight: CGFloat { get }
}

View File

@ -39,7 +39,7 @@ open class BasePassCodeService {
/// Override to set specific keychain service name
open class var keychainServiceString: String {
Bundle.main.bundleIdentifier ?? ""
return Bundle.main.bundleIdentifier ?? ""
}
public init() {
@ -55,7 +55,7 @@ open class BasePassCodeService {
private lazy var keychain = Keychain(service: BasePassCodeService.keychainServiceString).synchronizable(false)
private var passCodeHash: String? {
keychain[Keys.passCodeHash]
return keychain[Keys.passCodeHash]
}
}
@ -63,13 +63,13 @@ public extension BasePassCodeService {
/// Indicates is pass code already saved on this device
var isPassCodeSaved: Bool {
keychain[Keys.passCodeHash] != nil
return keychain[Keys.passCodeHash] != nil
}
/// Possibility to authenticate via biometrics. TouchID or FaceID
var isBiometricsAuthorizationEnabled: Bool {
get {
keychain[Keys.isBiometricsEnabled] == Values.biometricsEnabled
return keychain[Keys.isBiometricsEnabled] == Values.biometricsEnabled
}
set {
keychain[Keys.isBiometricsEnabled] = newValue ? Values.biometricsEnabled : nil
@ -87,7 +87,7 @@ public extension BasePassCodeService {
/// Check if pass code is correct
func check(passCode: String) -> Bool {
passCode.sha256() == passCodeHash
return passCode.sha256() == passCodeHash
}
/// Reset pass code settings

View File

@ -21,6 +21,7 @@
//
import RxSwift
import LeadKit
/// Represents service that store basic user information
open class BaseUserService {
@ -50,7 +51,7 @@ open class BaseUserService {
/// Indicates if user is logged in
open var isLoggedIn: Bool {
UserDefaults.standard.sessionId != nil
return UserDefaults.standard.sessionId != nil
}
/// Reset user information

View File

@ -41,7 +41,7 @@ public final class BiometricsService {
/// If the user unlocks the device using biometrics within the specified time interval,
/// then authentication for the receiver succeeds automatically, without prompting the user for biometrics.
/// Works only after device unlock event, no other apps authentications counts.
public var allowableReuseDuration: TimeInterval? {
public var allowableReuseDuration: TimeInterval? = nil {
didSet {
guard let duration = allowableReuseDuration else {
return
@ -66,9 +66,6 @@ public final class BiometricsService {
case .none:
return .none
@unknown default:
return .none
}
}
@ -85,7 +82,7 @@ public final class BiometricsService {
/// Indicates is it possible to authenticate on this device via any biometric.
/// Returns false if not enrolled or lockedout.
public var canAuthenticateWithBiometrics: Bool {
laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
return laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
}
/**

View File

@ -36,15 +36,15 @@ public final class ValidationItem {
private let disposeBag = DisposeBag()
private let validationStateHolder = BehaviorRelay<ValidationItemState>(value: .initial)
private let validationStateHolder = Variable<ValidationItemState>(.initial)
public var validationState: ValidationItemState {
validationStateHolder.value
return validationStateHolder.value
}
public var validationStateObservable: Observable<ValidationItemState> {
validationStateHolder.asObservable()
return validationStateHolder.asObservable()
}
private let text = BehaviorRelay<String?>(value: nil)
private let text = Variable<String?>(nil)
private(set) var rules: [Rule] = []
@ -90,13 +90,13 @@ public final class ValidationItem {
.correction where !isManual,
.valid where !isManual:
validationStateHolder.accept(.correction(validationError))
validationStateHolder.value = .correction(validationError)
default:
validationStateHolder.accept(.error(validationError))
validationStateHolder.value = .error(validationError)
}
} else {
validationStateHolder.accept(.valid)
validationStateHolder.value = .valid
}
}
}

View File

@ -17,7 +17,7 @@ public enum ValidationServiceState {
public extension ValidationServiceState {
var isValid: Bool {
self == .valid
return self == .valid
}
}
@ -27,12 +27,12 @@ public final class ValidationService {
private(set) var validationItems: [ValidationItem] = []
private let stateHolder = BehaviorRelay<ValidationServiceState>(value: .initial)
private let stateHolder = Variable<ValidationServiceState>(.initial)
public var state: ValidationServiceState {
stateHolder.value
return stateHolder.value
}
public var stateObservable: Observable<ValidationServiceState> {
stateHolder.asObservable()
return stateHolder.asObservable()
}
private var validationStateReactType: ValidationServiceStateReactType = .none
@ -71,7 +71,7 @@ public final class ValidationService {
public func validate() -> Bool {
validationStateReactType = .all
let isValid = validationItems.allSatisfy { $0.manualValidate() }
let isValid = validationItems.map { $0.manualValidate() }.reduce(true) { $0 && $1 }
validationStateReactType = .each
return isValid
@ -84,22 +84,18 @@ public final class ValidationService {
let zipStates = Observable
.zip(allValidationStateObservables) { $0 }
.filter { [weak self] _ in
self?.validationStateReactType == .all
}
.filter { [weak self] _ in self?.validationStateReactType == .all }
let combineLatestStates = Observable
.combineLatest(allValidationStateObservables) { $0 }
.filter { [weak self] _ in
self?.validationStateReactType == .each
}
.filter { [weak self] _ in self?.validationStateReactType == .each }
let stateObservables = [zipStates, combineLatestStates]
stateObservables.forEach { observable in
observable
.map { states -> Bool in
states.allSatisfy { $0.isValid }
states.map { $0.isValid }.reduce(true) { $0 && $1 }
}
.map { $0 ? ValidationServiceState.valid : .invalid }
.bind(to: stateHolder)

@ -1 +1 @@
Subproject commit 2799169e2103c034b0e1be221860a23292766f36
Subproject commit 54935bbe26063cdf04e72b8cb76d61c727ff99a7

View File

@ -1,14 +0,0 @@
#!/bin/sh
readonly CONFIG_PATH=${PROJECT_DIR}/build-scripts/xcode/.swiftlint.yml
readonly SWIFTLINT_VERSION=0.45.1
readonly SWIFTLINT_PORTABLE_FILENAME=portable_swiftlint.zip
readonly SWIFTLINT_PORTABLE_URL=https://github.com/realm/SwiftLint/releases/download/${SWIFTLINT_VERSION}/${SWIFTLINT_PORTABLE_FILENAME}
. build-scripts/xcode/aux_scripts/download_file.sh ${SWIFTLINT_PORTABLE_FILENAME} ${SWIFTLINT_PORTABLE_URL} Downloads --remove-cached
cd Downloads && unzip -o ${SWIFTLINT_PORTABLE_FILENAME}
${PROJECT_DIR}/Downloads/swiftlint autocorrect --path ${PROJECT_DIR}/Sources --config ${CONFIG_PATH} && ${PROJECT_DIR}/Downloads/swiftlint --path ${PROJECT_DIR}/Sources --config ${CONFIG_PATH}