diff --git a/LeadKitAdditions.podspec b/LeadKitAdditions.podspec index 7833366..2c15e64 100644 --- a/LeadKitAdditions.podspec +++ b/LeadKitAdditions.podspec @@ -1,15 +1,39 @@ Pod::Spec.new do |s| s.name = "LeadKitAdditions" - s.version = "0.0.14" + s.version = "0.0.15" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/NikAshanin/LeadKitAdditions" s.license = "Apache License, Version 2.0" s.author = "Touch Instinct" s.platform = :ios, "9.0" s.source = { :git => "https://github.com/NikAshanin/LeadKitAdditions.git", :tag => s.version } - s.source_files = "LeadKitAdditions/LeadKitAdditions/**/*.swift" - s.dependency "LeadKit", '~> 0.4.6' - s.dependency "KeychainAccess", '3.0.2' - s.dependency "IDZSwiftCommonCrypto", '0.9.1' + s.subspec 'Core' do |ss| + ss.ios.deployment_target = '9.0' + ss.source_files = "LeadKitAdditions/Sources/**/*.swift" + + ss.exclude_files = [ + "LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator+Extension.swift", + ] + + ss.dependency "LeadKit", '0.5.1' + ss.dependency "KeychainAccess", '3.0.2' + ss.dependency "IDZSwiftCommonCrypto", '0.9.1' + end + + s.subspec 'Core-iOS-Extension' do |ss| + ss.platform = :ios, '9.0' + ss.source_files = "LeadKitAdditions/Sources/**/*.swift" + + ss.exclude_files = [ + "LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator.swift", + ] + + ss.dependency "LeadKit/Core-iOS-Extension", '0.5.1' + ss.dependency "KeychainAccess", '3.0.2' + ss.dependency "IDZSwiftCommonCrypto", '0.9.1' + end + + s.default_subspec = 'Core' + end diff --git a/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj b/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj index ef8b0fc..7ad3379 100644 --- a/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj +++ b/LeadKitAdditions/LeadKitAdditions.xcodeproj/project.pbxproj @@ -7,7 +7,8 @@ objects = { /* Begin PBXBuildFile section */ - 7A94B4A5956B82BE1CEBA873 /* Pods_LeadKitAdditions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B7F57C5E5275C4D8DC71992 /* Pods_LeadKitAdditions.framework */; }; + 248389A288C0A6D7914F0546 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ED4A1B793EAA73C9E95969F /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */; }; + B326804BA6CC8B8BB136A46A /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFD5627139CAB27705F75C07 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework */; }; CAE698E81E968820000394B0 /* LeadKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE698E61E968820000394B0 /* LeadKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; EF05EDB41EAF703A00CAE7B6 /* BaseUserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDB31EAF703A00CAE7B6 /* BaseUserService.swift */; }; EF05EDB71EAF704800CAE7B6 /* Observable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDB51EAF704800CAE7B6 /* Observable+Extensions.swift */; }; @@ -30,15 +31,44 @@ EF05EDFD1EB0D77400CAE7B6 /* ApiNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDFB1EB0D77400CAE7B6 /* ApiNetworkService.swift */; }; EF05EE021EB206C000CAE7B6 /* LoadingBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EE011EB206C000CAE7B6 /* LoadingBarButton.swift */; }; EF05EE041EB21A2D00CAE7B6 /* ApiErrorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EE031EB21A2D00CAE7B6 /* ApiErrorProtocol.swift */; }; + EF2EC13C1ED4A0F100AA67A7 /* DefaultNetworkService+ActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF2EC13B1ED4A0F100AA67A7 /* DefaultNetworkService+ActivityIndicator.swift */; }; + EF2EC13E1ED4A21100AA67A7 /* DefaultNetworkService+ActivityIndicator+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF2EC13D1ED4A21100AA67A7 /* DefaultNetworkService+ActivityIndicator+Extension.swift */; }; + EFBD557A1EBB893F0062AA63 /* Info-iOS-Extensions.plist in Resources */ = {isa = PBXBuildFile; fileRef = EFBD55781EBB893F0062AA63 /* Info-iOS-Extensions.plist */; }; + EFBD557B1EBB893F0062AA63 /* Info-iOS.plist in Resources */ = {isa = PBXBuildFile; fileRef = EFBD55791EBB893F0062AA63 /* Info-iOS.plist */; }; + EFBD557C1EBB95680062AA63 /* ApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDBD1EAF706200CAE7B6 /* ApiResponse.swift */; }; + EFBD557D1EBB956A0062AA63 /* BaseDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDBE1EAF706200CAE7B6 /* BaseDateFormatter.swift */; }; + EFBD557E1EBB956C0062AA63 /* LoadingBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EE011EB206C000CAE7B6 /* LoadingBarButton.swift */; }; + EFBD557F1EBB95730062AA63 /* PassCodeConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDE41EAFA80D00CAE7B6 /* PassCodeConfiguration.swift */; }; + EFBD55801EBB95730062AA63 /* PassCodeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDEA1EAFA8E600CAE7B6 /* PassCodeError.swift */; }; + EFBD55811EBB95730062AA63 /* PassCodeHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDEC1EAFA96D00CAE7B6 /* PassCodeHolder.swift */; }; + EFBD55821EBB95730062AA63 /* PassCodeHolderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDE81EAFA8A000CAE7B6 /* PassCodeHolderProtocol.swift */; }; + EFBD55831EBB95730062AA63 /* PassCodeValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDE61EAFA87300CAE7B6 /* PassCodeValidationResult.swift */; }; + EFBD55841EBB95770062AA63 /* BasePassCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDE01EAFA74200CAE7B6 /* BasePassCodeViewController.swift */; }; + EFBD55851EBB957A0062AA63 /* BasePassCodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDE21EAFA7A600CAE7B6 /* BasePassCodeViewModel.swift */; }; + EFBD55861EBB95810062AA63 /* ApiError.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDB91EAF705500CAE7B6 /* ApiError.swift */; }; + EFBD55871EBB95810062AA63 /* ApiErrorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EE031EB21A2D00CAE7B6 /* ApiErrorProtocol.swift */; }; + EFBD55881EBB95810062AA63 /* ConnectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDBA1EAF705500CAE7B6 /* ConnectionError.swift */; }; + EFBD55891EBB95850062AA63 /* Observable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDB51EAF704800CAE7B6 /* Observable+Extensions.swift */; }; + EFBD558A1EBB95850062AA63 /* UIBarButtonItem+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDF71EB0D5A600CAE7B6 /* UIBarButtonItem+Extensions.swift */; }; + EFBD558B1EBB95850062AA63 /* UserDefaults+UserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDB61EAF704800CAE7B6 /* UserDefaults+UserService.swift */; }; + EFBD558C1EBB95890062AA63 /* BasePassCodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDC71EAF91D500CAE7B6 /* BasePassCodeService.swift */; }; + EFBD558D1EBB95890062AA63 /* BaseUserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDB31EAF703A00CAE7B6 /* BaseUserService.swift */; }; + EFBD558E1EBB95890062AA63 /* TouchIDService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDC51EAF70EB00CAE7B6 /* TouchIDService.swift */; }; + EFBD558F1EBB958D0062AA63 /* ApiNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDFB1EB0D77400CAE7B6 /* ApiNetworkService.swift */; }; + EFBD55901EBB958D0062AA63 /* DefaultNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF05EDFA1EB0D77400CAE7B6 /* DefaultNetworkService.swift */; }; + EFBD55921EBB9A980062AA63 /* LeadKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE698E61E968820000394B0 /* LeadKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 53E343F9E8F0A27C6114C160 /* Pods-LeadKitAdditions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions/Pods-LeadKitAdditions.debug.xcconfig"; sourceTree = ""; }; + 01605ECA03749D49C27FA3DD /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig"; sourceTree = ""; }; + 0ED4A1B793EAA73C9E95969F /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 49738551AC648B0AFA74E57F /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS/Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig"; sourceTree = ""; }; 7B7F57C5E5275C4D8DC71992 /* Pods_LeadKitAdditions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitAdditions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 8A48492D1BE72C6D161A6E8E /* Pods-LeadKitAdditions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions/Pods-LeadKitAdditions.release.xcconfig"; sourceTree = ""; }; + 9D549FA5A7579702358E07DF /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig"; sourceTree = ""; }; CAE698E31E968820000394B0 /* LeadKitAdditions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKitAdditions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CAE698E61E968820000394B0 /* LeadKitAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LeadKitAdditions.h; sourceTree = ""; }; - CAE698E71E968820000394B0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CFD5627139CAB27705F75C07 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0AB283D10B2175EFDBF7924 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS/Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig"; sourceTree = ""; }; EF05EDB31EAF703A00CAE7B6 /* BaseUserService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseUserService.swift; sourceTree = ""; }; EF05EDB51EAF704800CAE7B6 /* Observable+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+Extensions.swift"; sourceTree = ""; }; EF05EDB61EAF704800CAE7B6 /* UserDefaults+UserService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaults+UserService.swift"; sourceTree = ""; }; @@ -60,6 +90,11 @@ EF05EDFB1EB0D77400CAE7B6 /* ApiNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiNetworkService.swift; sourceTree = ""; }; EF05EE011EB206C000CAE7B6 /* LoadingBarButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingBarButton.swift; sourceTree = ""; }; EF05EE031EB21A2D00CAE7B6 /* ApiErrorProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiErrorProtocol.swift; sourceTree = ""; }; + EF2EC13B1ED4A0F100AA67A7 /* DefaultNetworkService+ActivityIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DefaultNetworkService+ActivityIndicator.swift"; sourceTree = ""; }; + EF2EC13D1ED4A21100AA67A7 /* DefaultNetworkService+ActivityIndicator+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DefaultNetworkService+ActivityIndicator+Extension.swift"; sourceTree = ""; }; + EFBD55701EBB87100062AA63 /* LeadKitAdditions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKitAdditions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EFBD55781EBB893F0062AA63 /* Info-iOS-Extensions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS-Extensions.plist"; sourceTree = ""; }; + EFBD55791EBB893F0062AA63 /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -67,7 +102,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7A94B4A5956B82BE1CEBA873 /* Pods_LeadKitAdditions.framework in Frameworks */, + 248389A288C0A6D7914F0546 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EFBD556C1EBB87100062AA63 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B326804BA6CC8B8BB136A46A /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -78,6 +121,8 @@ isa = PBXGroup; children = ( 7B7F57C5E5275C4D8DC71992 /* Pods_LeadKitAdditions.framework */, + 0ED4A1B793EAA73C9E95969F /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */, + CFD5627139CAB27705F75C07 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework */, ); name = Frameworks; sourceTree = ""; @@ -85,7 +130,7 @@ CAE698D91E968820000394B0 = { isa = PBXGroup; children = ( - CAE698E51E968820000394B0 /* LeadKitAdditions */, + CAE698E51E968820000394B0 /* Sources */, CAE698E41E968820000394B0 /* Products */, F8A65FEC7C0EB4B93746E50F /* Pods */, A3117951840B8B7D2E7A8A80 /* Frameworks */, @@ -96,22 +141,24 @@ isa = PBXGroup; children = ( CAE698E31E968820000394B0 /* LeadKitAdditions.framework */, + EFBD55701EBB87100062AA63 /* LeadKitAdditions.framework */, ); name = Products; sourceTree = ""; }; - CAE698E51E968820000394B0 /* LeadKitAdditions */ = { + CAE698E51E968820000394B0 /* Sources */ = { isa = PBXGroup; children = ( - EF05EDDB1EAFA6FA00CAE7B6 /* Controllers */, CAE698EE1E968B72000394B0 /* Classes */, + EF05EDDB1EAFA6FA00CAE7B6 /* Controllers */, CAE699011E9693DE000394B0 /* Enums */, CAE698F81E968F56000394B0 /* Extensions */, - CAE698E71E968820000394B0 /* Info.plist */, - CAE698E61E968820000394B0 /* LeadKitAdditions.h */, CAE698F31E968E28000394B0 /* Services */, + EFBD55791EBB893F0062AA63 /* Info-iOS.plist */, + EFBD55781EBB893F0062AA63 /* Info-iOS-Extensions.plist */, + CAE698E61E968820000394B0 /* LeadKitAdditions.h */, ); - path = LeadKitAdditions; + path = Sources; sourceTree = ""; }; CAE698EE1E968B72000394B0 /* Classes */ = { @@ -206,6 +253,8 @@ children = ( EF05EDFB1EB0D77400CAE7B6 /* ApiNetworkService.swift */, EF05EDFA1EB0D77400CAE7B6 /* DefaultNetworkService.swift */, + EF2EC13B1ED4A0F100AA67A7 /* DefaultNetworkService+ActivityIndicator.swift */, + EF2EC13D1ED4A21100AA67A7 /* DefaultNetworkService+ActivityIndicator+Extension.swift */, ); path = Network; sourceTree = ""; @@ -213,8 +262,10 @@ F8A65FEC7C0EB4B93746E50F /* Pods */ = { isa = PBXGroup; children = ( - 53E343F9E8F0A27C6114C160 /* Pods-LeadKitAdditions.debug.xcconfig */, - 8A48492D1BE72C6D161A6E8E /* Pods-LeadKitAdditions.release.xcconfig */, + 49738551AC648B0AFA74E57F /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */, + D0AB283D10B2175EFDBF7924 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig */, + 9D549FA5A7579702358E07DF /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig */, + 01605ECA03749D49C27FA3DD /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -230,12 +281,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EFBD556D1EBB87100062AA63 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + EFBD55921EBB9A980062AA63 /* LeadKitAdditions.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - CAE698E21E968820000394B0 /* LeadKitAdditions */ = { + CAE698E21E968820000394B0 /* LeadKitAdditions iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = CAE698EB1E968820000394B0 /* Build configuration list for PBXNativeTarget "LeadKitAdditions" */; + buildConfigurationList = CAE698EB1E968820000394B0 /* Build configuration list for PBXNativeTarget "LeadKitAdditions iOS" */; buildPhases = ( E8E82E34792B38EF225575D7 /* [CP] Check Pods Manifest.lock */, CAE698DE1E968820000394B0 /* Sources */, @@ -250,11 +309,31 @@ ); dependencies = ( ); - name = LeadKitAdditions; + name = "LeadKitAdditions iOS"; productName = LeadKitAdditions; productReference = CAE698E31E968820000394B0 /* LeadKitAdditions.framework */; productType = "com.apple.product-type.framework"; }; + EFBD556F1EBB87100062AA63 /* LeadKitAdditions iOS Extensions */ = { + isa = PBXNativeTarget; + buildConfigurationList = EFBD55751EBB87100062AA63 /* Build configuration list for PBXNativeTarget "LeadKitAdditions iOS Extensions" */; + buildPhases = ( + 1C200FD9213D2207669C4304 /* [CP] Check Pods Manifest.lock */, + EFBD556B1EBB87100062AA63 /* Sources */, + EFBD556C1EBB87100062AA63 /* Frameworks */, + EFBD556D1EBB87100062AA63 /* Headers */, + EFBD556E1EBB87100062AA63 /* Resources */, + 808FF5474C0E1574D405EFAF /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "LeadKitAdditions iOS Extensions"; + productName = "LeadKitAdditions-iOS-Extensions"; + productReference = EFBD55701EBB87100062AA63 /* LeadKitAdditions.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -269,6 +348,10 @@ LastSwiftMigration = 0830; ProvisioningStyle = Manual; }; + EFBD556F1EBB87100062AA63 = { + CreatedOnToolsVersion = 8.3.1; + ProvisioningStyle = Manual; + }; }; }; buildConfigurationList = CAE698DD1E968820000394B0 /* Build configuration list for PBXProject "LeadKitAdditions" */; @@ -283,13 +366,23 @@ projectDirPath = ""; projectRoot = ""; targets = ( - CAE698E21E968820000394B0 /* LeadKitAdditions */, + CAE698E21E968820000394B0 /* LeadKitAdditions iOS */, + EFBD556F1EBB87100062AA63 /* LeadKitAdditions iOS Extensions */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ CAE698E11E968820000394B0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EFBD557B1EBB893F0062AA63 /* Info-iOS.plist in Resources */, + EFBD557A1EBB893F0062AA63 /* Info-iOS-Extensions.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EFBD556E1EBB87100062AA63 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -299,6 +392,36 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 1C200FD9213D2207669C4304 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + 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"; + showEnvVarsInLog = 0; + }; + 808FF5474C0E1574D405EFAF /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 94F6E1BA5AD68C6E2F10062B /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -311,7 +434,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeadKitAdditions/Pods-LeadKitAdditions-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS/Pods-LeadKitAdditions-LeadKitAdditions iOS-resources.sh\"\n"; showEnvVarsInLog = 0; }; CAE6990A1E969A7A000394B0 /* Swiftlint */ = { @@ -385,6 +508,36 @@ EF05EDC81EAF91D500CAE7B6 /* BasePassCodeService.swift in Sources */, EF05EDC11EAF706200CAE7B6 /* BaseDateFormatter.swift in Sources */, EF05EDE71EAFA87300CAE7B6 /* PassCodeValidationResult.swift in Sources */, + EF2EC13C1ED4A0F100AA67A7 /* DefaultNetworkService+ActivityIndicator.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EFBD556B1EBB87100062AA63 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EFBD55861EBB95810062AA63 /* ApiError.swift in Sources */, + EFBD55821EBB95730062AA63 /* PassCodeHolderProtocol.swift in Sources */, + EFBD55881EBB95810062AA63 /* ConnectionError.swift in Sources */, + EFBD558C1EBB95890062AA63 /* BasePassCodeService.swift in Sources */, + EFBD558A1EBB95850062AA63 /* UIBarButtonItem+Extensions.swift in Sources */, + EFBD557F1EBB95730062AA63 /* PassCodeConfiguration.swift in Sources */, + EFBD558E1EBB95890062AA63 /* TouchIDService.swift in Sources */, + EFBD558F1EBB958D0062AA63 /* ApiNetworkService.swift in Sources */, + EFBD55891EBB95850062AA63 /* Observable+Extensions.swift in Sources */, + EFBD55871EBB95810062AA63 /* ApiErrorProtocol.swift in Sources */, + EFBD55841EBB95770062AA63 /* BasePassCodeViewController.swift in Sources */, + EFBD55811EBB95730062AA63 /* PassCodeHolder.swift in Sources */, + EFBD557C1EBB95680062AA63 /* ApiResponse.swift in Sources */, + EFBD557E1EBB956C0062AA63 /* LoadingBarButton.swift in Sources */, + EFBD558B1EBB95850062AA63 /* UserDefaults+UserService.swift in Sources */, + EFBD55831EBB95730062AA63 /* PassCodeValidationResult.swift in Sources */, + EFBD557D1EBB956A0062AA63 /* BaseDateFormatter.swift in Sources */, + EFBD55901EBB958D0062AA63 /* DefaultNetworkService.swift in Sources */, + EFBD55801EBB95730062AA63 /* PassCodeError.swift in Sources */, + EF2EC13E1ED4A21100AA67A7 /* DefaultNetworkService+ActivityIndicator+Extension.swift in Sources */, + EFBD55851EBB957A0062AA63 /* BasePassCodeViewModel.swift in Sources */, + EFBD558D1EBB95890062AA63 /* BaseUserService.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -433,7 +586,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -481,7 +634,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -494,7 +647,7 @@ }; CAE698EC1E968820000394B0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 53E343F9E8F0A27C6114C160 /* Pods-LeadKitAdditions.debug.xcconfig */; + baseConfigurationReference = 49738551AC648B0AFA74E57F /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; CLANG_ENABLE_MODULES = YES; @@ -504,12 +657,12 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = LeadKitAdditions/Info.plist; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = touchinstinct.LeadKitAdditions; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_BUNDLE_IDENTIFIER = "touchinstinct.LeadKitAdditions-iOS"; + PRODUCT_NAME = LeadKitAdditions; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -519,7 +672,7 @@ }; CAE698ED1E968820000394B0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8A48492D1BE72C6D161A6E8E /* Pods-LeadKitAdditions.release.xcconfig */; + baseConfigurationReference = D0AB283D10B2175EFDBF7924 /* Pods-LeadKitAdditions-LeadKitAdditions iOS.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; CLANG_ENABLE_MODULES = YES; @@ -529,18 +682,66 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = LeadKitAdditions/Info.plist; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = touchinstinct.LeadKitAdditions; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_BUNDLE_IDENTIFIER = "touchinstinct.LeadKitAdditions-iOS"; + PRODUCT_NAME = LeadKitAdditions; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; }; name = Release; }; + EFBD55761EBB87100062AA63 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D549FA5A7579702358E07DF /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS-Extensions.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "touchinstinct.LeadKitAdditions-iOS-Extensions"; + PRODUCT_NAME = LeadKitAdditions; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + EFBD55771EBB87100062AA63 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 01605ECA03749D49C27FA3DD /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS-Extensions.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "touchinstinct.LeadKitAdditions-iOS-Extensions"; + PRODUCT_NAME = LeadKitAdditions; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -553,7 +754,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - CAE698EB1E968820000394B0 /* Build configuration list for PBXNativeTarget "LeadKitAdditions" */ = { + CAE698EB1E968820000394B0 /* Build configuration list for PBXNativeTarget "LeadKitAdditions iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( CAE698EC1E968820000394B0 /* Debug */, @@ -562,6 +763,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + EFBD55751EBB87100062AA63 /* Build configuration list for PBXNativeTarget "LeadKitAdditions iOS Extensions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EFBD55761EBB87100062AA63 /* Debug */, + EFBD55771EBB87100062AA63 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = CAE698DA1E968820000394B0 /* Project object */; diff --git a/LeadKitAdditions/Podfile b/LeadKitAdditions/Podfile index 611af05..f8797be 100644 --- a/LeadKitAdditions/Podfile +++ b/LeadKitAdditions/Podfile @@ -1,14 +1,27 @@ source "https://github.com/CocoaPods/Specs.git" source "https://github.com/TouchInstinct/Podspecs.git" -platform :ios, '9.0' +abstract_target 'LeadKitAdditions' do + pod 'KeychainAccess', '3.0.2' + pod 'IDZSwiftCommonCrypto', '0.9.1' -target 'LeadKitAdditions' do - use_frameworks! + inhibit_all_warnings! - pod 'LeadKit', :git => 'https://github.com/TouchInstinct/LeadKit.git', :branch => 'fix/sharedApplication', :commit => 'fd0eb18b8a6680ff16bbb1668d1ae0d29f29fad7' - pod 'KeychainAccess' - pod 'IDZSwiftCommonCrypto' + target 'LeadKitAdditions iOS' do + platform :ios, '9.0' + + use_frameworks! + + pod "LeadKit", '0.5.1' + end + + target 'LeadKitAdditions iOS Extensions' do + platform :ios, '9.0' + + use_frameworks! + + pod "LeadKit/Core-iOS-Extension", '0.5.1' + end end # If you have slow HDD diff --git a/LeadKitAdditions/Podfile.lock b/LeadKitAdditions/Podfile.lock index c69064f..8dd7060 100644 --- a/LeadKitAdditions/Podfile.lock +++ b/LeadKitAdditions/Podfile.lock @@ -5,52 +5,53 @@ PODS: - CocoaLumberjack/Default - IDZSwiftCommonCrypto (0.9.1) - KeychainAccess (3.0.2) - - LeadKit (0.4.6): + - LeadKit (0.5.1): + - LeadKit/Core (= 0.5.1) + - LeadKit/Core (0.5.1): - CocoaLumberjack/Swift (~> 3.1.0) - - ObjectMapper (~> 2.1) - - RxAlamofire (= 3.0.0) - - RxCocoa (= 3.2.0) - - RxSwift (= 3.2.0) - - Toast-Swift (~> 2.0.0) - - ObjectMapper (2.2.5) - - RxAlamofire (3.0.0): - - RxAlamofire/Core (= 3.0.0) - - RxAlamofire/Core (3.0.0): + - ObjectMapper (~> 2.2) + - RxAlamofire (= 3.0.2) + - RxCocoa (= 3.4.0) + - RxSwift (= 3.4.0) + - TableKit (~> 2.3.1) + - UIScrollView-InfiniteScroll (~> 1.0.0) + - LeadKit/Core-iOS-Extension (0.5.1): + - CocoaLumberjack/Swift (~> 3.1.0) + - ObjectMapper (~> 2.2) + - RxAlamofire (= 3.0.2) + - RxCocoa (= 3.4.0) + - RxSwift (= 3.4.0) + - ObjectMapper (2.2.6) + - RxAlamofire (3.0.2): + - RxAlamofire/Core (= 3.0.2) + - RxAlamofire/Core (3.0.2): - Alamofire (~> 4.0) - RxSwift (~> 3.0) - - RxCocoa (3.2.0): - - RxSwift (~> 3.1) - - RxSwift (3.2.0) - - Toast-Swift (2.0.0) + - RxCocoa (3.4.0): + - RxSwift (~> 3.4) + - RxSwift (3.4.0) + - TableKit (2.3.1) + - UIScrollView-InfiniteScroll (1.0.1) DEPENDENCIES: - - IDZSwiftCommonCrypto - - KeychainAccess - - LeadKit (from `https://github.com/TouchInstinct/LeadKit.git`, commit `fd0eb18b8a6680ff16bbb1668d1ae0d29f29fad7`, branch `fix/sharedApplication`) - -EXTERNAL SOURCES: - LeadKit: - :branch: fix/sharedApplication - :commit: fd0eb18b8a6680ff16bbb1668d1ae0d29f29fad7 - :git: https://github.com/TouchInstinct/LeadKit.git - -CHECKOUT OPTIONS: - LeadKit: - :commit: fd0eb18b8a6680ff16bbb1668d1ae0d29f29fad7 - :git: https://github.com/TouchInstinct/LeadKit.git + - IDZSwiftCommonCrypto (= 0.9.1) + - KeychainAccess (= 3.0.2) + - LeadKit (= 0.5.1) + - LeadKit/Core-iOS-Extension (= 0.5.1) SPEC CHECKSUMS: Alamofire: dc44b1600b800eb63da6a19039a0083d62a6a62d CocoaLumberjack: 8311463ddf9ee86a06ef92a071dd656c89244500 IDZSwiftCommonCrypto: c44fe5c0219a219846b56b4c148615dd06e58591 KeychainAccess: a986406022dfc7c634c691ad3bec670cc6a32002 - LeadKit: d688a8bef79de7bbd83d553da3cb6c5292d48f2d - ObjectMapper: fb30f71e08470d1e5a20b199fafe1246281db898 - RxAlamofire: 0b1fa48f545fffe7f7a28af2086bcaa3b5946cc9 - RxCocoa: ccdf43101a70407097a29082f648ba1676075b30 - RxSwift: 46574f70d416b7923c237195939cc488a7fbf3a0 - Toast-Swift: 5b2f8f720f7e78e48511f693df1f9c9a6e38a25a + LeadKit: a66ca7c85b3e33deb11b6544fa80f45c9f0044e4 + ObjectMapper: '042708195cc46c20871cbcbec0453826398273fd' + RxAlamofire: bc53604b29fd2d220cfaa490c736cc4500819f34 + RxCocoa: d14ef6b6029e1ddc6e966508c09289090de68ff9 + RxSwift: 3789a1af753002a14edecdb698a2424624296a9c + TableKit: 02e041b443f75fa3e9f1ee6024d4b256305bd904 + UIScrollView-InfiniteScroll: a90df4ba4a7ca1926128ade34a850ddbdf74c564 -PODFILE CHECKSUM: 8e8ba1566ac9d3fe5b93325ab2faa9c76da42cd5 +PODFILE CHECKSUM: beb86ea0a40ab5016c200ff07cb6495168593d77 COCOAPODS: 1.2.1 diff --git a/LeadKitAdditions/LeadKitAdditions/Classes/ApiResponse.swift b/LeadKitAdditions/Sources/Classes/ApiResponse.swift similarity index 81% rename from LeadKitAdditions/LeadKitAdditions/Classes/ApiResponse.swift rename to LeadKitAdditions/Sources/Classes/ApiResponse.swift index bb1f92b..73dfc71 100644 --- a/LeadKitAdditions/LeadKitAdditions/Classes/ApiResponse.swift +++ b/LeadKitAdditions/Sources/Classes/ApiResponse.swift @@ -22,10 +22,14 @@ import ObjectMapper +/// Class describes typical response from server, which designed by TouchInstinct public class ApiResponse: ApiResponseProtocol, ImmutableMappable { + /// nil in case of error, result of request otherwise public let result: Any? + /// In case of error contains error code, 0 (zero) otherwise public let errorCode: Int + /// nil in case of success, error description otherwise public let errorMessage: String? public required init(map: Map) throws { @@ -36,9 +40,12 @@ public class ApiResponse: ApiResponseProtocol, ImmutableMappable { } +/// Describes error, which received from server designed by TouchInstinct public protocol ApiResponseProtocol: ImmutableMappable { + /// Error code var errorCode: Int { get } + /// Error description var errorMessage: String? { get } } diff --git a/LeadKitAdditions/LeadKitAdditions/Classes/BaseDateFormatter.swift b/LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift similarity index 87% rename from LeadKitAdditions/LeadKitAdditions/Classes/BaseDateFormatter.swift rename to LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift index 0748a37..3bdf9ae 100644 --- a/LeadKitAdditions/LeadKitAdditions/Classes/BaseDateFormatter.swift +++ b/LeadKitAdditions/Sources/Classes/BaseDateFormatter.swift @@ -23,6 +23,7 @@ import Foundation import ObjectMapper +/// Base date formatter class, contains most frequently used formats, including RFC3339 open class BaseDateFormatter { private static let apiDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ssZ" @@ -61,37 +62,44 @@ open class BaseDateFormatter { return dateFormater }() - // MARK: Public interface + // MARK: - Public interface + /// DateFormatter's locale can be overriden open class var usedLocale: Locale { return .current } + /// Parse date from string with format: yyyy-MM-dd'T'HH:mm:ssZ public static func backendDate(fromStrDate strDate: String) -> Date? { apiFormatter.locale = usedLocale return apiFormatter.date(from: strDate) } + /// Serialize date into string with format: yyyy-MM-dd'T'HH:mm:ssZ public static func backendStrDate(withDate date: Date) -> String { apiFormatter.locale = usedLocale return apiFormatter.string(from: date) } + /// Serialize date into string with format: yyyy-MM-dd'T'Z public static func backendDateWithoutTime(withDate date: Date) -> String { apiDateWithoutTimeFormatter.locale = usedLocale return apiDateWithoutTimeFormatter.string(from: date) } + /// Serialize date into string with format: HH:mm public static func hourAndMinuteStrDate(withDate date: Date) -> String { hourAndMinuteFormatter.locale = usedLocale return hourAndMinuteFormatter.string(from: date) } + /// Serialize date into string with format: dd MMM public static func dayAndMonthStrDate(withDate date: Date) -> String { hourAndMinuteFormatter.locale = usedLocale return dayAndMonthFormatter.string(from: date) } + /// Serialize date into string with format: dd.MM.yyyy public static func dayMonthYearStrDate(withDate date: Date) -> String { hourAndMinuteFormatter.locale = usedLocale return dayMonthYearFormatter.string(from: date) @@ -99,6 +107,7 @@ open class BaseDateFormatter { // MARK: - Transformers + /// Transformer to workaround with dates in Mappable (ObjectMapper) objects public static var transformFromStringToDate: TransformOf { return TransformOf(fromJSON: { (stringValue) -> Date? in if let stringValue = stringValue { diff --git a/LeadKitAdditions/LeadKitAdditions/Classes/LoadingBarButton.swift b/LeadKitAdditions/Sources/Classes/LoadingBarButton.swift similarity index 81% rename from LeadKitAdditions/LeadKitAdditions/Classes/LoadingBarButton.swift rename to LeadKitAdditions/Sources/Classes/LoadingBarButton.swift index 4056510..2d7a7a9 100644 --- a/LeadKitAdditions/LeadKitAdditions/Classes/LoadingBarButton.swift +++ b/LeadKitAdditions/Sources/Classes/LoadingBarButton.swift @@ -24,11 +24,13 @@ import UIKit import RxSwift import RxCocoa +/// Side to which activity indicator applied public enum LoadingBarButtonSide { case left case right } +/// Workaround with navigationBarButton, that can change state (UI) into activity indicator public class LoadingBarButton { fileprivate weak var navigationItem: UINavigationItem? @@ -54,6 +56,13 @@ public class LoadingBarButton { } } + /** + Create an instance of LoadingBarButton + + - Parameters: + - navigationItem: item to which apply changes + - side: side where navigationItem would be placed + */ public init(navigationItem: UINavigationItem, side: LoadingBarButtonSide) { self.navigationItem = navigationItem self.side = side @@ -74,6 +83,15 @@ public class LoadingBarButton { extension Observable { + /** + Reactive extension for LoadingBarButton + Apply transformations on subscribe and on dispose events + + - Parameters: + - barButton: LoadingBarButton instance to which transformations would applied + - Returns: + - observable, that handles LoadingBarButton behaviour + */ public func changeLoadingUI(using barButton: LoadingBarButton) -> Observable { return observeOn(MainScheduler.instance) .do(onSubscribe: { diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeConfiguration.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift similarity index 87% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeConfiguration.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift index 2635d02..d48d8e5 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeConfiguration.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeConfiguration.swift @@ -20,11 +20,15 @@ // THE SOFTWARE. // +/// Configuration container for BasePassCodeViewController public struct PassCodeConfiguration { + /// Pass code length public var passCodeCharactersNumber: UInt = 4 + /// Incorrect pass code attempts count public var maxAttemptsLoginNumber: UInt = 5 + /// Clear input progress when application goes to background public var shouldResetWhenGoBackground: Bool = true private init() {} @@ -37,6 +41,7 @@ public struct PassCodeConfiguration { self.passCodeCharactersNumber = passCodeCharactersNumber } + /// Returns configuration with default values public static var defaultConfiguration: PassCodeConfiguration { return PassCodeConfiguration() } diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeError.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift similarity index 95% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeError.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift index 6fbcc8a..6e766af 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeError.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeError.swift @@ -20,6 +20,7 @@ // THE SOFTWARE. // +/// Describes error, which may occur during pass code entering public enum PassCodeError: Error { case codesNotMatch case wrongCode diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeHolder.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift similarity index 96% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeHolder.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift index 4a118a5..4dae8fc 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeHolder.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolder.swift @@ -38,6 +38,7 @@ extension PassCodeHolderProtocol { } } +/// Holds information about pass codes during pass code creation process public class PassCodeHolderCreate: PassCodeHolderProtocol { public let type: PassCodeControllerType = .create @@ -91,6 +92,7 @@ public class PassCodeHolderCreate: PassCodeHolderProtocol { } +/// Holds information about pass code during pass code entering process public class PassCodeHolderEnter: PassCodeHolderProtocol { public let type: PassCodeControllerType = .enter @@ -120,6 +122,7 @@ public class PassCodeHolderEnter: PassCodeHolderProtocol { } +/// Holds information about pass codes during pass code changing process public class PassCodeHolderChange: PassCodeHolderProtocol { public let type: PassCodeControllerType = .change diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeHolderProtocol.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift similarity index 76% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeHolderProtocol.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift index e281642..b4a031d 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeHolderProtocol.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeHolderProtocol.swift @@ -20,17 +20,26 @@ // THE SOFTWARE. // +/// Holds information about enter type (create, change, etc), step +/// Also describes interface to manipulate with entered pass code public protocol PassCodeHolderProtocol { + /// Type of operation with pass code var type: PassCodeControllerType { get } + /// Operation step var enterStep: PassCodeControllerState { get } + /// Add pass code for current step func add(passCode: String) + /// Reset all progress func reset() + /// Should been pass code validated var shouldValidate: Bool { get } + /// Current pass code var passCode: String? { get } + /// Returns passCode or error if pass code is invalid func validate() -> PassCodeValidationResult } @@ -39,6 +48,12 @@ public class PassCodeHolderBuilder { private init() {} + /** + Creates holder by type (create, change, etc) + + - parameter type: type of pass code controller + - returns: pass code information holder, specific by type + */ public static func build(with type: PassCodeControllerType) -> PassCodeHolderProtocol { switch type { case .create: diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeValidationResult.swift b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift similarity index 98% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeValidationResult.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift index 33bdd9b..41bdbd1 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/Model/PassCodeValidationResult.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/Model/PassCodeValidationResult.swift @@ -20,6 +20,7 @@ // THE SOFTWARE. // +/// Result of pass code validation public enum PassCodeValidationResult { case valid(String) diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/View/BasePassCodeViewController.swift b/LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift similarity index 93% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/View/BasePassCodeViewController.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift index c6ec92e..11591ce 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/View/BasePassCodeViewController.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift @@ -25,17 +25,20 @@ import RxSwift import RxCocoa import LeadKit +/// Describes pin image public enum PinImageType { case entered case clear } +/// Pass code operation type public enum PassCodeControllerType { case create case enter case change } +/// Pass code operation state public enum PassCodeControllerState { case enter case repeatEnter @@ -43,6 +46,7 @@ public enum PassCodeControllerState { case newEnter } +/// Base view controller that operates with pass code open class BasePassCodeViewController: UIViewController { public var viewModel: BasePassCodeViewModel! @@ -157,41 +161,44 @@ open class BasePassCodeViewController: UIViewController { // MARK: - HAVE TO OVERRIDE + /// Returns prompt that appears on touch id system alert open var touchIdHint: String { assertionFailure("You should override this var: touchIdHint") return "" } - // override to change Images + /// Override to point certain images open func imageFor(type: PinImageType) -> UIImage { assertionFailure("You should override this method: imageFor(type: PinImageType)") return UIImage() } - // override to change error text + /// Override to change error description open func errorDescription(for error: PassCodeError) -> String { assertionFailure("You should override this method: errorDescription(for error: PassCodeError)") return "" } - // override to change action title text + /// Override to change action title text open func actionTitle(for passCodeControllerState: PassCodeControllerState) -> String { assertionFailure("You should override this method: actionTitle(for passCodeControllerState: PassCodeControllerState)") return "" } - // MARK: - Functions that can you can override to castomise your controller + // MARK: - Functions that you can override to customize your controller + /// Call to show error open func showError(for error: PassCodeError) { errorLabel?.text = errorDescription(for: error) errorLabel?.isHidden = false } + /// Call to disappear error label open func hideError() { errorLabel?.isHidden = true } - // override to change UI for state + /// Override to change UI for state open func configureUI(for passCodeControllerState: PassCodeControllerState) { resetDotsUI() titleLabel?.text = actionTitle(for: passCodeControllerState) @@ -199,6 +206,7 @@ open class BasePassCodeViewController: UIViewController { } +// MARK: - ConfigurableController // We need to implement all functions of ConfigurableController protocol to give ability to override them. extension BasePassCodeViewController: ConfigurableController { @@ -242,6 +250,7 @@ extension BasePassCodeViewController: ConfigurableController { } +// MARK: - UITextFieldDelegate extension BasePassCodeViewController: UITextFieldDelegate { public func textField(_ textField: UITextField, diff --git a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift b/LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift similarity index 93% rename from LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift rename to LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift index 5582931..0679755 100644 --- a/LeadKitAdditions/LeadKitAdditions/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift +++ b/LeadKitAdditions/Sources/Controllers/PassCode/ViewModel/BasePassCodeViewModel.swift @@ -24,18 +24,22 @@ import LeadKit import RxSwift import RxCocoa +/// Describes types of authentication public enum PassCodeAuthType { case passCode(String) case touchId } +/// Base view model for passCodeViewController open class BasePassCodeViewModel: BaseViewModel { public let controllerType: PassCodeControllerType public let disposeBag = DisposeBag() + /// TouchId service, which can answer if user is authorized by finger public let touchIdService: TouchIDService? + /// Contains configuration for pass code operations public let passCodeConfiguration: PassCodeConfiguration fileprivate let validationResultHolder = Variable(nil) @@ -114,21 +118,25 @@ open class BasePassCodeViewModel: BaseViewModel { // MARK: - HAVE TO OVERRIDE + /// Override to check if entered pass code is equal to stored open func isEnteredPassCodeValid(_ passCode: String) -> Bool { assertionFailure("You should override this method: isEnteredPassCodeValid(_ passCode: String)") return false } + /// Handler called after successful authentication open func authSucceed(_ type: PassCodeAuthType) { assertionFailure("You should override this method: authSucceed(_ type: PassCodeAuthType)") } // MARK: - Functions that can you can override to use TouchId + /// Override to be able use touchId during authentication open var isTouchIdEnabled: Bool { return false } + /// You should save user choice about authenticate by touchId open func activateTouchIdForUser() { assertionFailure("You should override this method: activateTouchIdForUser()") } diff --git a/LeadKitAdditions/LeadKitAdditions/Enums/ApiError.swift b/LeadKitAdditions/Sources/Enums/ApiError.swift similarity index 95% rename from LeadKitAdditions/LeadKitAdditions/Enums/ApiError.swift rename to LeadKitAdditions/Sources/Enums/ApiError.swift index 1aadac7..bb4533e 100644 --- a/LeadKitAdditions/LeadKitAdditions/Enums/ApiError.swift +++ b/LeadKitAdditions/Sources/Enums/ApiError.swift @@ -20,8 +20,7 @@ // THE SOFTWARE. // -import Foundation - +/// Describes possible error, received from back-end public enum ApiError: Error { case error(code: Int, message: String) @@ -29,6 +28,7 @@ public enum ApiError: Error { } +// MARK: - LocalizedError extension ApiError: LocalizedError { public init(apiResponse: ApiResponseProtocol) { diff --git a/LeadKitAdditions/LeadKitAdditions/Enums/ApiErrorProtocol.swift b/LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift similarity index 91% rename from LeadKitAdditions/LeadKitAdditions/Enums/ApiErrorProtocol.swift rename to LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift index e71b6ae..31b0113 100644 --- a/LeadKitAdditions/LeadKitAdditions/Enums/ApiErrorProtocol.swift +++ b/LeadKitAdditions/Sources/Enums/ApiErrorProtocol.swift @@ -20,10 +20,12 @@ // THE SOFTWARE. // +/// Describes error by raw value (more likely - Int code), received from back-end public protocol ApiErrorProtocol: RawRepresentable {} extension Error { + /// Method indicates that error is back-end error public func isApiError(_ apiErrorType: T) -> Bool where T.RawValue == Int { if let error = self as? ApiError, case let .error(code: code, message: _) = error, diff --git a/LeadKitAdditions/LeadKitAdditions/Enums/ConnectionError.swift b/LeadKitAdditions/Sources/Enums/ConnectionError.swift similarity index 96% rename from LeadKitAdditions/LeadKitAdditions/Enums/ConnectionError.swift rename to LeadKitAdditions/Sources/Enums/ConnectionError.swift index 9cad52e..f6980c4 100644 --- a/LeadKitAdditions/LeadKitAdditions/Enums/ConnectionError.swift +++ b/LeadKitAdditions/Sources/Enums/ConnectionError.swift @@ -22,6 +22,7 @@ import Foundation +/// Describes "no connection to server" error public enum ConnectionError: LocalizedError { case noConnection diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/Observable+Extensions.swift b/LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift similarity index 85% rename from LeadKitAdditions/LeadKitAdditions/Extensions/Observable+Extensions.swift rename to LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift index 4a9eec8..7c67157 100644 --- a/LeadKitAdditions/LeadKitAdditions/Extensions/Observable+Extensions.swift +++ b/LeadKitAdditions/Sources/Extensions/Observable+Extensions.swift @@ -28,6 +28,7 @@ public typealias VoidBlock = () -> Void public extension Observable { + /// Handles connection errors during request public func handleConnectionErrors() -> Observable { return observeOn(CurrentThreadScheduler.instance) @@ -52,6 +53,13 @@ public extension Observable { }) } + /** + Allow to configure request to restart if error occured + + - parameters: + - errorTypes: list of error types, which triggers request restart + - retryLimit: how many times request can restarts + */ public func retryWithinErrors(_ errorTypes: [Error.Type] = [ConnectionError.self], retryLimit: Int = DefaultNetworkService.retryLimit) -> Observable { @@ -66,6 +74,13 @@ public extension Observable { } } + /** + Add block that executes, when error, described by ApiErrorProtocol, occured during request + + - parameters: + - apiErrorType: type of errors, received frim server + - handler: block, that executes, when error occured + */ public func handleApiError(_ apiErrorType: T, handler: @escaping () -> Void) -> Observable where T.RawValue == Int { @@ -78,6 +93,11 @@ public extension Observable { }) } + /** + Add ability to monitor request status + + - parameter isLoading: subject, request state bind to + */ public func changeLoadingBehaviour(isLoading: PublishSubject) -> Observable { return observeOn(CurrentThreadScheduler.instance) .do(onNext: { _ in diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/UIBarButtonItem+Extensions.swift b/LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift similarity index 94% rename from LeadKitAdditions/LeadKitAdditions/Extensions/UIBarButtonItem+Extensions.swift rename to LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift index 51c2d56..ef3eaf7 100644 --- a/LeadKitAdditions/LeadKitAdditions/Extensions/UIBarButtonItem+Extensions.swift +++ b/LeadKitAdditions/Sources/Extensions/UIBarButtonItem+Extensions.swift @@ -24,6 +24,7 @@ import UIKit extension UIBarButtonItem { + /// Creates activity indicator view and bar button item (based on activity indicator) public static var activityIndicator: (barButton: UIBarButtonItem, activityIndicator: UIActivityIndicatorView) { let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .white) let indicatorBar = UIBarButtonItem(customView: indicatorView) diff --git a/LeadKitAdditions/LeadKitAdditions/Extensions/UserDefaults+UserService.swift b/LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift similarity index 94% rename from LeadKitAdditions/LeadKitAdditions/Extensions/UserDefaults+UserService.swift rename to LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift index eb6e8f3..4015847 100644 --- a/LeadKitAdditions/LeadKitAdditions/Extensions/UserDefaults+UserService.swift +++ b/LeadKitAdditions/Sources/Extensions/UserDefaults+UserService.swift @@ -22,13 +22,14 @@ import Foundation -fileprivate enum Keys { +private enum Keys { static let sessionId = "sessionId" static let userLogin = "userLogin" } public extension UserDefaults { + /// Default place to store session id public var sessionId: String? { get { return string(forKey: Keys.sessionId) @@ -38,6 +39,7 @@ public extension UserDefaults { } } + /// Default place to store userLogin public var userLogin: String? { get { return string(forKey: Keys.userLogin) diff --git a/LeadKitAdditions/Sources/Info-iOS-Extensions.plist b/LeadKitAdditions/Sources/Info-iOS-Extensions.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/LeadKitAdditions/Sources/Info-iOS-Extensions.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/LeadKitAdditions/LeadKitAdditions/Info.plist b/LeadKitAdditions/Sources/Info-iOS.plist similarity index 100% rename from LeadKitAdditions/LeadKitAdditions/Info.plist rename to LeadKitAdditions/Sources/Info-iOS.plist diff --git a/LeadKitAdditions/LeadKitAdditions/LeadKitAdditions.h b/LeadKitAdditions/Sources/LeadKitAdditions.h similarity index 100% rename from LeadKitAdditions/LeadKitAdditions/LeadKitAdditions.h rename to LeadKitAdditions/Sources/LeadKitAdditions.h diff --git a/LeadKitAdditions/LeadKitAdditions/Services/BasePassCodeService.swift b/LeadKitAdditions/Sources/Services/BasePassCodeService.swift similarity index 89% rename from LeadKitAdditions/LeadKitAdditions/Services/BasePassCodeService.swift rename to LeadKitAdditions/Sources/Services/BasePassCodeService.swift index 91dbf56..13414f0 100644 --- a/LeadKitAdditions/LeadKitAdditions/Services/BasePassCodeService.swift +++ b/LeadKitAdditions/Sources/Services/BasePassCodeService.swift @@ -24,8 +24,10 @@ import KeychainAccess import CocoaLumberjack import IDZSwiftCommonCrypto +/// Represents base pass code service which encapsulates pass code storing open class BasePassCodeService { + /// Override to set specific keychain service name open class var keychainService: String { return Bundle.main.bundleIdentifier ?? "" } @@ -64,10 +66,12 @@ open class BasePassCodeService { extension BasePassCodeService { + /// Indicates is pass code already saved on this device public var isPassCodeSaved: Bool { return keychain[Keys.passCodeHash] != nil } + /// Indicates is it possible to authenticate on this device via touch id public var isTouchIdEnabled: Bool { get { return keychain[Keys.isTouchIdEnabled] == Values.touchIdEnabled @@ -77,6 +81,7 @@ extension BasePassCodeService { } } + /// Saves new pass code public func save(passCode: String?) { if let passCode = passCode { keychain[Keys.passCodeHash] = sha256(passCode) @@ -85,10 +90,12 @@ extension BasePassCodeService { } } + /// Check if pass code is correct public func check(passCode: String) -> Bool { return sha256(passCode) == passCodeHash } + /// Reset pass code settings public func reset() { save(passCode: nil) isTouchIdEnabled = false diff --git a/LeadKitAdditions/LeadKitAdditions/Services/BaseUserService.swift b/LeadKitAdditions/Sources/Services/BaseUserService.swift similarity index 91% rename from LeadKitAdditions/LeadKitAdditions/Services/BaseUserService.swift rename to LeadKitAdditions/Sources/Services/BaseUserService.swift index 8923c7f..b5a7125 100644 --- a/LeadKitAdditions/LeadKitAdditions/Services/BaseUserService.swift +++ b/LeadKitAdditions/Sources/Services/BaseUserService.swift @@ -23,12 +23,14 @@ import RxSwift import LeadKit +/// Represents service that store basic user information open class BaseUserService { public init() { // Can be overrided } + /// Returns user login open var userLogin: String { guard let defaultsLogin = UserDefaults.standard.userLogin else { assertionFailure("userLogin is nil. Use isLoggedIn before read userLogin") @@ -38,6 +40,7 @@ open class BaseUserService { return defaultsLogin } + /// Returns session id open var sessionId: String { guard let defaultsSessionId = UserDefaults.standard.sessionId else { assertionFailure("sessionId is nil. Use isLoggedIn before read sessionId") @@ -46,10 +49,12 @@ open class BaseUserService { return defaultsSessionId } + /// Indicates if user is logged in open var isLoggedIn: Bool { return UserDefaults.standard.sessionId != nil } + /// Reset user information open class func clearData() { UserDefaults.standard.sessionId = nil UserDefaults.standard.userLogin = nil diff --git a/LeadKitAdditions/LeadKitAdditions/Services/Network/ApiNetworkService.swift b/LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift similarity index 91% rename from LeadKitAdditions/LeadKitAdditions/Services/Network/ApiNetworkService.swift rename to LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift index d588926..762a737 100644 --- a/LeadKitAdditions/LeadKitAdditions/Services/Network/ApiNetworkService.swift +++ b/LeadKitAdditions/Sources/Services/Network/ApiNetworkService.swift @@ -25,8 +25,10 @@ import Alamofire import ObjectMapper import RxSwift +/// Base network service implementation for back-end designed by TouchInstinct open class ApiNetworkService: DefaultNetworkService { + /// Returns observable for ImmutableMappable response model by parameters open func request(with parameters: ApiRequestParameters) -> Observable { let apiResponseRequest = rxRequest(with: parameters) as Observable<(response: HTTPURLResponse, model: ApiResponse)> @@ -41,6 +43,7 @@ open class ApiNetworkService: DefaultNetworkService { } } + /// Returns observable for boolean response by parameters open func requestForResult(with parameters: ApiRequestParameters) -> Observable { let apiResponseRequest = rxRequest(with: parameters) as Observable<(response: HTTPURLResponse, model: ApiResponse)> diff --git a/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator+Extension.swift b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator+Extension.swift new file mode 100644 index 0000000..8322648 --- /dev/null +++ b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator+Extension.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) 2017 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 + +extension DefaultNetworkService { + + func activityIndicatorBinding() -> Disposable? { + return nil + } + +} diff --git a/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator.swift b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator.swift new file mode 100644 index 0000000..abe2e32 --- /dev/null +++ b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService+ActivityIndicator.swift @@ -0,0 +1,32 @@ +// +// Copyright (c) 2017 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 LeadKit + +extension DefaultNetworkService { + + func activityIndicatorBinding() -> Disposable? { + return bindActivityIndicator() + } + +} diff --git a/LeadKitAdditions/LeadKitAdditions/Services/Network/DefaultNetworkService.swift b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift similarity index 82% rename from LeadKitAdditions/LeadKitAdditions/Services/Network/DefaultNetworkService.swift rename to LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift index a728d15..7082eb3 100644 --- a/LeadKitAdditions/LeadKitAdditions/Services/Network/DefaultNetworkService.swift +++ b/LeadKitAdditions/Sources/Services/Network/DefaultNetworkService.swift @@ -25,14 +25,19 @@ import LeadKit import ObjectMapper import RxSwift +/// Default implementation of network service, which trust any server and use default timeout interval open class DefaultNetworkService: NetworkService { static let retryLimit = 3 + private let disposeBag = DisposeBag() + + /// Override to set base server url open class var baseUrl: String { fatalError("You should override this var: baseUrl") } + /// Override to change timeout interval default value open class var defaultTimeoutInterval: TimeInterval { return 20.0 } @@ -40,17 +45,19 @@ open class DefaultNetworkService: NetworkService { public override init(sessionManager: SessionManager) { super.init(sessionManager: sessionManager) - bindActivityIndicator() + activityIndicatorBinding()?.addDisposableTo(disposeBag) } // MARK: - Default Values + /// Override to change server trust policies open class var serverTrustPolicies: [String: ServerTrustPolicy] { return [ baseUrl: .disableEvaluation ] } + /// Override to change default urlSession configuration open class var configuration: URLSessionConfiguration { let configuration = URLSessionConfiguration.default configuration.timeoutIntervalForRequest = defaultTimeoutInterval @@ -58,6 +65,7 @@ open class DefaultNetworkService: NetworkService { return configuration } + /// Override to configure alamofire session manager open class var sessionManager: SessionManager { let sessionManager = SessionManager(configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)) diff --git a/LeadKitAdditions/LeadKitAdditions/Services/TouchIDService.swift b/LeadKitAdditions/Sources/Services/TouchIDService.swift similarity index 80% rename from LeadKitAdditions/LeadKitAdditions/Services/TouchIDService.swift rename to LeadKitAdditions/Sources/Services/TouchIDService.swift index 394186d..4dfaab2 100644 --- a/LeadKitAdditions/LeadKitAdditions/Services/TouchIDService.swift +++ b/LeadKitAdditions/Sources/Services/TouchIDService.swift @@ -24,6 +24,7 @@ import LocalAuthentication public typealias TouchIDServiceAuthHandler = (Bool) -> Void +/// Represents service that provides access to authentication via touch id public class TouchIDService { private lazy var laContext: LAContext = { @@ -32,10 +33,18 @@ public class TouchIDService { public init() {} + /// Indicates is it possible to authenticate on this device via touch id public var canAuthenticateByTouchId: Bool { return laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) } + /** + Initiates system touch id authentication process + + - parameters: + - description: prompt on the system alert that describes what for user should attach finger to device + - authHandler: callback, with parameter, indicates if user authenticate successfuly + */ public func authenticateByTouchId(description: String, authHandler: @escaping TouchIDServiceAuthHandler) { laContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: description) { success, _ in