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
- 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
- DataRepresentable
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 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.
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
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
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.
HapticEngineClient is a factory-client for HapticFeedback clients. HapticFeedback is a client for UIFeedbackGenerator.
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()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 module provides a protocol for objects data representation. It is used by UserDefaultsClient and KeychainClient to store objects as data.
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.
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"
)This library is released under the MIT license. See LICENSE for details.