From d560c035c6a6d358f2569c1426d8d96ba4f76312 Mon Sep 17 00:00:00 2001 From: Boyko Mihail Date: Thu, 29 Apr 2021 15:05:38 +0300 Subject: [PATCH 1/5] feat: Add TIKeychainUtils --- LeadKit.podspec | 2 +- Package.swift | 2 + README.md | 4 +- .../CodableKeyValueStorage/StorageError.swift | 2 +- TIFoundationUtils/TIFoundationUtils.podspec | 2 +- TIKeychainUtils/README.md | 38 +++++++++++ .../Keychain+CodableKeyValueStorage.swift | 68 +++++++++++++++++++ TIKeychainUtils/TIKeychainUtils.podspec | 17 +++++ TISwiftUtils/TISwiftUtils.podspec | 2 +- TITableKitUtils/TITableKitUtils.podspec | 2 +- TITransitions/TITransitions.podspec | 2 +- TIUIElements/TIUIElements.podspec | 2 +- TIUIKitCore/TIUIKitCore.podspec | 2 +- 13 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 TIKeychainUtils/README.md create mode 100644 TIKeychainUtils/Sources/KeychainCodableBackingStore/Keychain+CodableKeyValueStorage.swift create mode 100644 TIKeychainUtils/TIKeychainUtils.podspec diff --git a/LeadKit.podspec b/LeadKit.podspec index 0899b713..48bc9c4d 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "1.1.2" + s.version = "1.1.3" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/Package.swift b/Package.swift index 6c5640d1..e4fd65da 100644 --- a/Package.swift +++ b/Package.swift @@ -11,6 +11,7 @@ let package = Package( .library(name: "TIUIKitCore", targets: ["TIUIKitCore"]), .library(name: "TISwiftUtils", targets: ["TISwiftUtils"]), .library(name: "TIFoundationUtils", targets: ["TIFoundationUtils"]), + .library(name: "TIKeychainUtils", targets: ["TIKeychainUtils"]), .library(name: "TIUIElements", targets: ["TIUIElements"]), .library(name: "TITableKitUtils", targets: ["TITableKitUtils"]), .library(name: "OTPSwiftView", targets: ["OTPSwiftView"]) @@ -23,6 +24,7 @@ let package = Package( .target(name: "TIUIKitCore", path: "TIUIKitCore/Sources"), .target(name: "TISwiftUtils", path: "TISwiftUtils/Sources"), .target(name: "TIFoundationUtils", dependencies: ["TISwiftUtils"], path: "TIFoundationUtils/Sources"), + .target(name: "TIKeychainUtils", dependencies: ["TIFoundationUtils"], path: "TIKeychainUtils/Sources"), .target(name: "TIUIElements", dependencies: ["TIUIKitCore", "TISwiftUtils"], path: "TIUIElements/Sources"), .target(name: "TITableKitUtils", dependencies: ["TIUIElements", "TableKit"], path: "TITableKitUtils/Sources"), .target(name: "OTPSwiftView", dependencies: ["TIUIElements"], path: "OTPSwiftView/Sources") diff --git a/README.md b/README.md index 53dba73b..1c080af5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ This repository contains the following additional frameworks: - [OTPSwiftView](OTPSwiftView) - a fully customizable OTP view. - [TISwiftUtils](TISwiftUtils) - a bunch of useful helpers for development. - [TITableKitUtils](TITableKitUtils) - Set of helpers for TableKit classes. +- [TIFoundationUtils](TIFoundationUtils) - Set of helpers for Foundation framework classes. +- [TIKeychainUtils](TIKeychainUtils) - Set of helpers for Keychain classes. Useful docs: - [Semantic Commit Messages](docs/semantic-commit-messages.md) - commit message codestyle. @@ -42,4 +44,4 @@ source 'https://github.com/TouchInstinct/Podspecs.git' pod 'TISwiftUtils', 'x.y.z' pod 'TIFoundationUtils', 'x.y.z' # ... -``` \ No newline at end of file +``` diff --git a/TIFoundationUtils/Sources/CodableKeyValueStorage/StorageError.swift b/TIFoundationUtils/Sources/CodableKeyValueStorage/StorageError.swift index 0e64dc35..4e2617fd 100644 --- a/TIFoundationUtils/Sources/CodableKeyValueStorage/StorageError.swift +++ b/TIFoundationUtils/Sources/CodableKeyValueStorage/StorageError.swift @@ -20,7 +20,7 @@ // THE SOFTWARE. // -enum StorageError: Error { +public enum StorageError: Error { case valueNotFound case unableToExtractData(underlyingError: Error) case unableToDecode(underlyingError: Error) diff --git a/TIFoundationUtils/TIFoundationUtils.podspec b/TIFoundationUtils/TIFoundationUtils.podspec index c63f8958..cf9e4663 100644 --- a/TIFoundationUtils/TIFoundationUtils.podspec +++ b/TIFoundationUtils/TIFoundationUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIFoundationUtils' - s.version = '1.1.2' + s.version = '1.1.3' s.summary = 'Set of helpers for Foundation framework classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIKeychainUtils/README.md b/TIKeychainUtils/README.md new file mode 100644 index 00000000..b0f11574 --- /dev/null +++ b/TIKeychainUtils/README.md @@ -0,0 +1,38 @@ +# TIKeychainUtils + +Set of helpers for Keychain classes. +Bunch of CodableBackingStore from TIFoundationUtils and KeychainAccess. +Implement + +#### @propertyWrapper example + +```swift +extension StorageKey { + static var userProfileKey: StorageKey { + .init(rawValue: "userProfileKey") + } +} + +extension Bundle { + var bundleId: String { + Bundle.main.bundleIdentifier ?? .empty + } +} + +extension Keychain { + static var defaultKeychain: Keychain { + .init(service: Bundle.main.bundleId) + } +} + +final class ViewModel { + @KeychainCodableBackingStore(key: .userProfileKey, codableKeyValueStorage: .defaultKeychain) + + private(set) var profile: UserProfile? + + func updateProfile(profile newProfile: UserProfile?) { + let oldProfile = profile + } +} +``` + diff --git a/TIKeychainUtils/Sources/KeychainCodableBackingStore/Keychain+CodableKeyValueStorage.swift b/TIKeychainUtils/Sources/KeychainCodableBackingStore/Keychain+CodableKeyValueStorage.swift new file mode 100644 index 00000000..9e66246c --- /dev/null +++ b/TIKeychainUtils/Sources/KeychainCodableBackingStore/Keychain+CodableKeyValueStorage.swift @@ -0,0 +1,68 @@ +// +// Copyright (c) 2020 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 +import KeychainAccess +import TIFoundationUtils + +public typealias KeychainCodableBackingStore = CodableKeyValueBackingStore + +extension Keychain: CodableKeyValueStorage { + public func codableObject(forKey key: StorageKey, + decoder: CodableKeyValueDecoder) throws -> Value { + + let unwrappedStoredData: Data? + + do { + unwrappedStoredData = try getData(key.rawValue) + } catch { + throw StorageError.unableToExtractData(underlyingError: error) + } + + guard let storedData = unwrappedStoredData else { + throw StorageError.valueNotFound + } + + return try decoder.decodeDecodable(from: storedData, for: key) + } + + public func set(encodableObject: Value, + forKey key: StorageKey, + encoder: CodableKeyValueEncoder) throws { + + let objectData = try encoder.encodeEncodable(value: encodableObject, for: key) + + do { + try set(objectData, key: key.rawValue) + } catch { + throw StorageError.unableToWriteData(underlyingError: error) + } + } + + public func removeCodableValue(forKey key: StorageKey) throws { + do { + try remove(key.rawValue) + } catch { + throw StorageError.unableToWriteData(underlyingError: error) + } + } +} diff --git a/TIKeychainUtils/TIKeychainUtils.podspec b/TIKeychainUtils/TIKeychainUtils.podspec new file mode 100644 index 00000000..a3fcd59e --- /dev/null +++ b/TIKeychainUtils/TIKeychainUtils.podspec @@ -0,0 +1,17 @@ +Pod::Spec.new do |s| + s.name = 'TIKeychainUtils' + s.version = '1.1.3' + s.summary = 'Set of helpers for Keychain classes.' + s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'petropavel13' => 'ivan.smolin@touchin.ru' } + s.source = { :git => 'https://github.com/TouchInstinct/LeadKit.git', :tag => s.version.to_s } + + s.ios.deployment_target = '11.0' + s.swift_versions = ['5.3'] + + s.source_files = s.name + '/Sources/**/*' + + s.dependency 'TIFoundationUtils', s.version.to_s + s.dependency 'KeychainAccess' +end diff --git a/TISwiftUtils/TISwiftUtils.podspec b/TISwiftUtils/TISwiftUtils.podspec index b5a911ff..716c18c8 100644 --- a/TISwiftUtils/TISwiftUtils.podspec +++ b/TISwiftUtils/TISwiftUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUtils' - s.version = '1.1.2' + s.version = '1.1.3' s.summary = 'Bunch of useful helpers for Swift development.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITableKitUtils/TITableKitUtils.podspec b/TITableKitUtils/TITableKitUtils.podspec index eaffd093..8296d312 100644 --- a/TITableKitUtils/TITableKitUtils.podspec +++ b/TITableKitUtils/TITableKitUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITableKitUtils' - s.version = '1.1.2' + s.version = '1.1.3' s.summary = 'Set of helpers for TableKit classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITransitions/TITransitions.podspec b/TITransitions/TITransitions.podspec index bba696f5..f439e3f6 100644 --- a/TITransitions/TITransitions.podspec +++ b/TITransitions/TITransitions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITransitions' - s.version = '1.1.2' + s.version = '1.1.3' s.summary = 'Set of custom transitions to present controller. ' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIElements/TIUIElements.podspec b/TIUIElements/TIUIElements.podspec index 832ef76c..29044ba0 100644 --- a/TIUIElements/TIUIElements.podspec +++ b/TIUIElements/TIUIElements.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIElements' - s.version = '1.1.2' + s.version = '1.1.3' s.summary = 'Bunch of useful protocols and views.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec index 7387c9fb..7dead0e8 100644 --- a/TIUIKitCore/TIUIKitCore.podspec +++ b/TIUIKitCore/TIUIKitCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIKitCore' - s.version = '1.1.2' + s.version = '1.1.3' s.summary = 'Core UI elements: protocols, views and helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } From 529dd9edf8dfc817189148cf1538bd80356ea4ea Mon Sep 17 00:00:00 2001 From: Boyko Mihail Date: Fri, 30 Apr 2021 13:18:27 +0300 Subject: [PATCH 2/5] feat: Fix pr issue --- LeadKit.podspec | 2 +- TIFoundationUtils/TIFoundationUtils.podspec | 2 +- TIKeychainUtils/README.md | 4 ++-- TIKeychainUtils/TIKeychainUtils.podspec | 2 +- TISwiftUtils/TISwiftUtils.podspec | 2 +- TITableKitUtils/TITableKitUtils.podspec | 2 +- TITransitions/TITransitions.podspec | 2 +- TIUIElements/TIUIElements.podspec | 2 +- TIUIKitCore/TIUIKitCore.podspec | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/LeadKit.podspec b/LeadKit.podspec index 48bc9c4d..6a9a6f1f 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "1.1.3" + s.version = "1.2.0" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/TIFoundationUtils/TIFoundationUtils.podspec b/TIFoundationUtils/TIFoundationUtils.podspec index cf9e4663..bf875d6d 100644 --- a/TIFoundationUtils/TIFoundationUtils.podspec +++ b/TIFoundationUtils/TIFoundationUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIFoundationUtils' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Set of helpers for Foundation framework classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIKeychainUtils/README.md b/TIKeychainUtils/README.md index b0f11574..b709c446 100644 --- a/TIKeychainUtils/README.md +++ b/TIKeychainUtils/README.md @@ -30,8 +30,8 @@ final class ViewModel { private(set) var profile: UserProfile? - func updateProfile(profile newProfile: UserProfile?) { - let oldProfile = profile + func updateProfile(newProfile: UserProfile?) { + profile = newProfile } } ``` diff --git a/TIKeychainUtils/TIKeychainUtils.podspec b/TIKeychainUtils/TIKeychainUtils.podspec index a3fcd59e..789ee1a4 100644 --- a/TIKeychainUtils/TIKeychainUtils.podspec +++ b/TIKeychainUtils/TIKeychainUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIKeychainUtils' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Set of helpers for Keychain classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TISwiftUtils/TISwiftUtils.podspec b/TISwiftUtils/TISwiftUtils.podspec index 716c18c8..9e67d72c 100644 --- a/TISwiftUtils/TISwiftUtils.podspec +++ b/TISwiftUtils/TISwiftUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUtils' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Bunch of useful helpers for Swift development.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITableKitUtils/TITableKitUtils.podspec b/TITableKitUtils/TITableKitUtils.podspec index 8296d312..8a954ccd 100644 --- a/TITableKitUtils/TITableKitUtils.podspec +++ b/TITableKitUtils/TITableKitUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITableKitUtils' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Set of helpers for TableKit classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITransitions/TITransitions.podspec b/TITransitions/TITransitions.podspec index f439e3f6..51af6e08 100644 --- a/TITransitions/TITransitions.podspec +++ b/TITransitions/TITransitions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITransitions' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Set of custom transitions to present controller. ' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIElements/TIUIElements.podspec b/TIUIElements/TIUIElements.podspec index 29044ba0..0ee0b3db 100644 --- a/TIUIElements/TIUIElements.podspec +++ b/TIUIElements/TIUIElements.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIElements' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Bunch of useful protocols and views.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec index 7dead0e8..9d482c7b 100644 --- a/TIUIKitCore/TIUIKitCore.podspec +++ b/TIUIKitCore/TIUIKitCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIKitCore' - s.version = '1.1.3' + s.version = '1.2.0' s.summary = 'Core UI elements: protocols, views and helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } From ee78f008ebfd38d82d02d6ee4f5df923af1ed567 Mon Sep 17 00:00:00 2001 From: Boyko Mihail Date: Fri, 30 Apr 2021 14:55:32 +0300 Subject: [PATCH 3/5] feat: Fix pr issue --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72db96a1..e0f572ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +### 1.2.0 +- **Add**: `TIKeychainUtils` - Set of helpers for Keychain classes. + ### 1.1.1 - **Fix**: `StatefullButton` propagation From 77ca9d05fab07055b48b26d5f6a3ab4a69f186d0 Mon Sep 17 00:00:00 2001 From: Boyko Mihail Date: Fri, 30 Apr 2021 17:47:58 +0300 Subject: [PATCH 4/5] feat: fix pr issue --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index e4fd65da..e5050bd2 100644 --- a/Package.swift +++ b/Package.swift @@ -24,7 +24,7 @@ let package = Package( .target(name: "TIUIKitCore", path: "TIUIKitCore/Sources"), .target(name: "TISwiftUtils", path: "TISwiftUtils/Sources"), .target(name: "TIFoundationUtils", dependencies: ["TISwiftUtils"], path: "TIFoundationUtils/Sources"), - .target(name: "TIKeychainUtils", dependencies: ["TIFoundationUtils"], path: "TIKeychainUtils/Sources"), + .target(name: "TIKeychainUtils", dependencies: ["TIFoundationUtils", "KeychainAccess"], path: "TIKeychainUtils/Sources"), .target(name: "TIUIElements", dependencies: ["TIUIKitCore", "TISwiftUtils"], path: "TIUIElements/Sources"), .target(name: "TITableKitUtils", dependencies: ["TIUIElements", "TableKit"], path: "TITableKitUtils/Sources"), .target(name: "OTPSwiftView", dependencies: ["TIUIElements"], path: "OTPSwiftView/Sources") From d27c8ab97c80389346d6a6a71c645db3842627a9 Mon Sep 17 00:00:00 2001 From: Boyko Mihail Date: Fri, 30 Apr 2021 18:56:50 +0300 Subject: [PATCH 5/5] feat: Fix dependency (pr issue) --- Package.resolved | 9 +++++++++ Package.swift | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Package.resolved b/Package.resolved index 7c8c1236..65ac8579 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,6 +1,15 @@ { "object": { "pins": [ + { + "package": "KeychainAccess", + "repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git", + "state": { + "branch": null, + "revision": "84e546727d66f1adc5439debad16270d0fdd04e7", + "version": "4.2.2" + } + }, { "package": "TableKit", "repositoryURL": "https://github.com/maxsokolov/TableKit.git", diff --git a/Package.swift b/Package.swift index e5050bd2..ef8ed654 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,8 @@ let package = Package( .library(name: "OTPSwiftView", targets: ["OTPSwiftView"]) ], dependencies: [ - .package(url: "https://github.com/maxsokolov/TableKit.git", from: "2.11.0") + .package(url: "https://github.com/maxsokolov/TableKit.git", from: "2.11.0"), + .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "4.2.2") ], targets: [ .target(name: "TITransitions", path: "TITransitions/Sources"),