swift-standard-clients
swift-standard-clients copied to clipboard
Client declarations and live implementations for standard iOS managers
swift-standard-clients
Client declarations and live implementations for standard iOS managers
More info about client approach:
Source Description Brandon Williams - Protocol Witnesses Talk on App Builders Conference 2019 Pointfree - Protocol Witnesses Pointfree collection pointfree/isowords Examples of different clients can be found here
Table of contents
| Description | Interface | Implementations |
|---|---|---|
| Caching | CacheClient | MemoryCacheClient |
| IDFA | IDFAPermissionsClient | IDFAPermissionsClientLive |
| Keychain | KeychainClient | KeychainClientLive |
| Notifications | NotificationsPermissionsClient | NotificationsPermissionsClientLive |
| HapticEngine | HapticEngineClient | HapticEngineClientLive |
| UserDefaults | UserDefaultsClient | UserDefaultsClientLive |
Todos
- [ ] Improve readme by adding examples and simplifying descriptions.
- [ ] Add LocalAuthenticationClient [ Soon ]
- [ ] Find out if it's better to use
Any-based UserDefaults storage instead ofDataRepresentable-based. - Add more tests
- [ ] Caching
- [ ] IDFA
- [ ] Keychain
- [ ] Notifications
- [ ] HapticEngine
- [ ] UserDefaults
- [x] DataRepresentable
Caching
CacheClient<Key, Value> is a generic client over hashable key and value, it provides interfaces for the following operations:
saveValue(_: Value, forKey: Key)loadValue(of: Value.Type = Value.self, forKey: Key) -> ValueremoveValue(forKey: Key)removeAllValues()
MemoryCacheClient
MemoryCacheClient is build on top of NSCache. Under the hood it uses MemoryCache wrapper, improved version of John Sundells' Cache. You can use MemoryCache (which also provides a way to save itself to disk if your types are codable) directly to build your own CacheClient implementations.
IDFA
IDFAPermissionClient is a client for ASIdentifierManager and ATTrackingManager, it provides interfaces for the following operations:
requestAuthorizationStatus() -> AnyPublisher<AuthorizationStatus, Never>requestAuthorization() -> AnyPublisher<AuthorizationStatus, Never>requestIDFA() -> AnyPublisher<UUID?, Never>
IDFAPermissionClient.AuthorizationStatusis a wrapper forATTrackingManager.AuthorizationStatustype andASIdentifierManager.isAdvertisingTrackingEnabledvalue it's values are:
notDetermined = "Not Determined"// ATTrackingManager.AuthorizationStatus.notDeterminedrestricted = "Restricted"// ATTrackingManager.AuthorizationStatus.restricteddenied = "Denied"// ATTrackingManager.AuthorizationStatus.deniedauthorized = "Authorized"// ATTrackingManager.AuthorizationStatus.authorizedunknown = "Unknown"// ATTrackingManager.AuthorizationStatus.unknownunavailableWithTrackingEnabled = "Unavailable: Tracking Enabled"// iOS<14 macOS<11, tvOS<14 ASIdentifierManager.shared().isAdvertisingTrackingEnabled == trueunavailableWithTrackingDisabled = "Unavailable: Tracking Disabled"// iOS<14 macOS<11, tvOS<14 ASIdentifierManager.shared().isAdvertisingTrackingEnabled == falseIt also has a computed property
isPermissivewhich istruefor.authorizedand.unavailableWithTrackingEnabled
Keychain
KeychainClient is a client for Security framework keychain access, it stores objects as data (Using DataRepresentable protocol) and provides interfaces for the following operations:
saveValue<Value: DataRepresentable>(_: Value, forKey: Key, policy: AccessPolicy)loadValue<Value: DataRepresentable>(of: Value.Type = Value.self, forKey: Key) -> ValueremoveValue(forKey: Key)
KeychainClient.Key can be initialized by rawValue: Stirng, StringLiteral or StringInterpolation. Also you can use .bundle(_:Key) or .bundle(_:Bundle, _:Key) to add bundleID prefix to your key.
KeychainClient.Operations.Save.AccessPolicyis a wrapper for kSec access constants and it's values are:
accessibleWhenUnlocked// kSecAttrAccessibleWhenUnlockedaccessibleWhenUnlockedThisDeviceOnly// kSecAttrAccessibleWhenUnlockedThisDeviceOnlyaccessibleAfterFirstUnlock// kSecAttrAccessibleAfterFirstUnlockaccessibleAfterFirstUnlockThisDeviceOnly// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnlyaccessibleWhenPasscodeSetThisDeviceOnly// kSecAttrAccessibleWhenPasscodeSetThisDeviceOnlyaccessibleAlways// kSecAttrAccessibleAlwaysaccessibleAlwaysThisDeviceOnly// kSecAttrAccessibleAlwaysThisDeviceOnly
Notifications
NotificationsPermissionsClient is a client for UNUserNotificationCenter, it provides interfaces for the following operations:
requestAuthorizationStatus() -> AnyPublisher<AuthorizationStatus, Never>requestAuthorization(options: AuthorizationOptions) -> AnyPublisher<AuthorizationStatus, Never>configureRemoteNotifications(_:)// Pass.registeror.unregisterto the function
NotificationsPermissionsClient.AuthorizationStatusis a wrapper forUNAuthorizationStatustype it's values are:
notDetermined
denied
authorized
provisional
ephemeral// iOS14+ onlyIt also has a computed property
isPermissivewhich is true forauthorized,ephimeralandprovisional
NotificationsPermissionsClient.AuthorizationOptionsis a wrapper forUNAuthorizationOptionstype it's predefined values are:
badgesoundalertcarPlaycriticalAlertprovidesAppNotificationSettingsprovisionalannouncement// iOS onlyYou can also construct
AuthorizationOptionsobject by providingUIntraw value.
HapticEngine
HapticEngineClient is a factory-client for HapticFeedback clients. HapticFeedback is a client for UIFeedbackGenerator.
Usage
import HapticEngineClientLive
// If you need just one generator you can use HapticFeedback directly
HapticFeedback.success.trigger()
// Otherwise if you need more flexible way to create Haptic feedbacks use HapticEngineClient
HapticEngineClient.live.generator(for: .success).trigger()
UserDefaults
UserDefaultsClient is a client for UserDefaults object, it stores objects as data (Using DataRepresentable protocol) and provides interfaces for the following operations:
saveValue<Value: DataRepresentable>(_: Value, forKey: Key)loadValue<Value: DataRepresentable>(of: Value.Type = Value.self, forKey: Key) -> ValueremoveValue(forKey: Key)
UserDefaultsClient.Key can be initialized by rawValue: Stirng, StringLiteral or StringInterpolation. Also you can use .bundle(_:Key) or .bundle(_:Bundle, _:Key) to add bundleID prefix to your key.
DataRepresentable
DataRepresentable module provides a protocol for objects data representation. It is used by UserDefaultsClient and KeychainClient to store objects as data.
Installation
Basic
You can add StandardClients to an Xcode project by adding it as a package dependency.
- From the File menu, select Swift Packages › Add Package Dependency…
- Enter
"https://github.com/capturecontext/swift-standard-clients.git"into the package repository URL text field - Choose products you need to link them to your project.
Recommended
If you use SwiftPM for your project, you can add StandardClients to your package file.
.package(
name: "swift-standard-clients",
url: "https://github.com/capturecontext/swift-standard-clients.git",
.upToNextMinor(from: "0.1.0")
)
Do not forget about target dependencies:
.product(
name: "SomeClientOrClientLive",
package: "swift-standard-clients"
)
License
This library is released under the MIT license. See LICENSE for details.