From f1d92627b8e5053050c48502ccb09a827e5057f1 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Tue, 9 Jan 2024 22:55:26 -0800 Subject: [PATCH] Upgrade to Spezi 1.0 releases (#45) # Upgrade to Spezi 1.0 releases ## :recycle: Current situation & Problem This PR upgrades to the latest Spezi 1.0 releases. Further, we made our Standard constraints protocol naming consistent with the rest of the ecosystem. Lastly, we replaced a `preconditionFailure` with a log message to avoid some unnecessary crashes. ## :gear: Release Notes * Upgrade to latest Spezi 1.0 releases * Renamed `AccountNotifyStandard` and `AccountStorageStandard` to `AccountNotifyConstraint` and `AccountStorageConstraint` to be more consistent with the rest of the Spezi framework ecosystem. ## :pencil: Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md). --- Package.swift | 10 +++++----- README.md | 2 +- Sources/SpeziAccount/Account.swift | 12 +++++------- Sources/SpeziAccount/AccountConfiguration.swift | 6 +++--- ...yStandard.swift => AccountNotifyConstraint.swift} | 2 +- .../SpeziAccount/AccountService/AccountService.swift | 2 +- .../Configuration/AccountServiceConfiguration.swift | 4 ++-- .../Configuration/SupportedAccountKeys.swift | 2 +- .../AccountService/EmbeddableAccountService.swift | 4 ++-- .../Wrapper/NotifyStandardBackedAccountService.swift | 2 +- .../AccountService/Wrapper/StandardBacked.swift | 10 +++++----- .../StorageStandardBackedAccountService.swift | 4 ++-- .../AccountSetupViewStyle.swift | 2 +- ...Standard.swift => AccountStorageConstraint.swift} | 6 +++--- Sources/SpeziAccount/AccountValue/AccountKey.swift | 2 +- Sources/SpeziAccount/Model/AdditionalRecordId.swift | 2 +- .../Account Values/Adding new Account Values.md | 2 +- .../Account Values/Handling Account Value Storage.md | 2 +- .../Setup Guides/Custom Storage Provider.md | 10 +++++----- .../SpeziAccount.docc/Setup Guides/Initial Setup.md | 4 ++-- .../ViewModifier/AccountServiceButtonModifier.swift | 2 +- .../UITests/TestApp/AccountTests/TestStandard.swift | 4 ++-- 22 files changed, 47 insertions(+), 49 deletions(-) rename Sources/SpeziAccount/{AccountNotifyStandard.swift => AccountNotifyConstraint.swift} (92%) rename Sources/SpeziAccount/{AccountStorageStandard.swift => AccountStorageConstraint.swift} (95%) diff --git a/Package.swift b/Package.swift index 4348a729..5e4e2e6e 100644 --- a/Package.swift +++ b/Package.swift @@ -21,11 +21,11 @@ let package = Package( .library(name: "SpeziAccount", targets: ["SpeziAccount"]) ], dependencies: [ - .package(url: "https://github.com/StanfordSpezi/SpeziFoundation.git", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/StanfordSpezi/Spezi", .upToNextMinor(from: "0.8.0")), - .package(url: "https://github.com/StanfordSpezi/SpeziViews", .upToNextMinor(from: "0.6.1")), - .package(url: "https://github.com/StanfordBDHG/XCTRuntimeAssertions", .upToNextMinor(from: "0.2.5")), - .package(url: "https://github.com/apple/swift-collections.git", .upToNextMajor(from: "1.0.4")) + .package(url: "https://github.com/StanfordSpezi/SpeziFoundation.git", from: "1.0.0"), + .package(url: "https://github.com/StanfordSpezi/Spezi", from: "1.0.0"), + .package(url: "https://github.com/StanfordSpezi/SpeziViews", from: "1.0.0"), + .package(url: "https://github.com/StanfordBDHG/XCTRuntimeAssertions", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-collections.git", from: "1.0.4") ], targets: [ .target( diff --git a/README.md b/README.md index 0702a6b5..bd42c903 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ framework provides the [`FirebaseAccountConfiguration`](https://swiftpackageinde you can use to configure an Account Service base on the Google Firebase service. -## Setup +### Setup You need to add the Spezi Account Swift package to [your app in Xcode](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app#) or diff --git a/Sources/SpeziAccount/Account.swift b/Sources/SpeziAccount/Account.swift index 431a1513..7039ee2c 100644 --- a/Sources/SpeziAccount/Account.swift +++ b/Sources/SpeziAccount/Account.swift @@ -220,16 +220,14 @@ public final class Account: Sendable { } } - if let existingDetails = self.details { - precondition( - existingDetails.accountService.id == details.accountService.id, - "The AccountService \(details.accountService) tried to overwrite `AccountDetails` from \(existingDetails.accountService)!" - ) + if let existingDetails = self.details, + existingDetails.accountService.id != details.accountService.id { + logger.warning("The AccountService \(details.accountService.description) is overwriting `AccountDetails` from \(existingDetails.accountService.description)!") } // Check if the account service is wrapped with a storage standard. If that's the case, contact them about the signup! if let standardBacked = details.accountService as? any _StandardBacked, - let storageStandard = standardBacked.standard as? any AccountStorageStandard { + let storageStandard = standardBacked.standard as? any AccountStorageConstraint { let recordId = AdditionalRecordId(serviceId: standardBacked.backedId, accountId: details.accountId) try await standardBacked.preUserDetailsSupply(recordId: recordId) @@ -257,7 +255,7 @@ public final class Account: Sendable { public func removeUserDetails() async { if let details, let standardBacked = details.accountService as? any _StandardBacked, - let storageStandard = standardBacked.standard as? any AccountStorageStandard { + let storageStandard = standardBacked.standard as? any AccountStorageConstraint { let recordId = AdditionalRecordId(serviceId: standardBacked.backedId, accountId: details.accountId) await storageStandard.clear(recordId) diff --git a/Sources/SpeziAccount/AccountConfiguration.swift b/Sources/SpeziAccount/AccountConfiguration.swift index 2fe4c052..3f5d4a23 100644 --- a/Sources/SpeziAccount/AccountConfiguration.swift +++ b/Sources/SpeziAccount/AccountConfiguration.swift @@ -72,7 +72,7 @@ public final class AccountConfiguration: Module { // If applicable, wraps the service into an StandardBackedAccountService let service = verifyConfigurationRequirements(against: service) - if let notifyStandard = standard as? any AccountNotifyStandard { + if let notifyStandard = standard as? any AccountNotifyConstraint { return service.backedBy(standard: notifyStandard) } @@ -112,7 +112,7 @@ public final class AccountConfiguration: Module { } - if let accountStandard = standard as? any AccountStorageStandard { + if let accountStandard = standard as? any AccountStorageConstraint { // we are also fine, we have a standard that can store any unsupported account values logger.debug(""" The standard \(accountStandard.description) is used to store the following account values that \ @@ -132,7 +132,7 @@ public final class AccountConfiguration: Module { The Account Service \(service.description) indicated that it cannot store the above-listed account values. In order to proceed you may use a Standard inside your Spezi Configuration that conforms to \ - `AccountStorageStandard` which handles storage of the above-listed account values. Otherwise, you may \ + `AccountStorageConstraint` which handles storage of the above-listed account values. Otherwise, you may \ remove the above-listed account values from your SpeziAccount configuration. """ ) diff --git a/Sources/SpeziAccount/AccountNotifyStandard.swift b/Sources/SpeziAccount/AccountNotifyConstraint.swift similarity index 92% rename from Sources/SpeziAccount/AccountNotifyStandard.swift rename to Sources/SpeziAccount/AccountNotifyConstraint.swift index dfb451ca..13d3ef8a 100644 --- a/Sources/SpeziAccount/AccountNotifyStandard.swift +++ b/Sources/SpeziAccount/AccountNotifyConstraint.swift @@ -15,7 +15,7 @@ import Spezi /// /// ### Access Account /// - ``Spezi/Standard/AccountReference`` -public protocol AccountNotifyStandard: Standard { +public protocol AccountNotifyConstraint: Standard { /// Notifies the Standard that the associated account was requested to be deleted by the user. /// /// Use this method to cleanup any account related data that might be associated with the account. diff --git a/Sources/SpeziAccount/AccountService/AccountService.swift b/Sources/SpeziAccount/AccountService/AccountService.swift index 26cfdef4..3b7fb54d 100644 --- a/Sources/SpeziAccount/AccountService/AccountService.swift +++ b/Sources/SpeziAccount/AccountService/AccountService.swift @@ -37,7 +37,7 @@ public protocol AccountService: AnyObject, Hashable, CustomStringConvertible, Se /// This identifier is used to uniquely identify an account service that persists across process instances. /// /// - Important: A default implementation is defined that relies on the type name. If you rename the account service - /// type without supplying a manual `id` implementation, components like a ``AccountStorageStandard`` won't + /// type without supplying a manual `id` implementation, components like a ``AccountStorageConstraint`` won't /// be able to associate existing user details with this account service. var id: String { get } diff --git a/Sources/SpeziAccount/AccountService/Configuration/AccountServiceConfiguration.swift b/Sources/SpeziAccount/AccountService/Configuration/AccountServiceConfiguration.swift index 8febe767..946ff505 100644 --- a/Sources/SpeziAccount/AccountService/Configuration/AccountServiceConfiguration.swift +++ b/Sources/SpeziAccount/AccountService/Configuration/AccountServiceConfiguration.swift @@ -58,7 +58,7 @@ public struct AccountServiceConfiguration: Sendable { /// - Parameters: /// - name: The name of the ``AccountService``. Refer to ``AccountServiceName`` for more information. /// - supportedKeys: The set of ``SupportedAccountKeys`` the ``AccountService`` is capable of storing itself. - /// If ``SupportedAccountKeys/exactly(_:)`` is chosen, the user is responsible of providing a ``AccountStorageStandard`` + /// If ``SupportedAccountKeys/exactly(_:)`` is chosen, the user is responsible of providing a ``AccountStorageConstraint`` /// that is capable of handling all non-supported ``AccountKey``s. public init(name: LocalizedStringResource, supportedKeys: SupportedAccountKeys) { self.storage = Self.createStorage(name: name, supportedKeys: supportedKeys) @@ -68,7 +68,7 @@ public struct AccountServiceConfiguration: Sendable { /// - Parameters: /// - name: The name of the ``AccountService``. Refer to ``AccountServiceName`` for more information. /// - supportedKeys: The set of ``SupportedAccountKeys`` the ``AccountService`` is capable of storing itself. - /// If ``SupportedAccountKeys/exactly(_:)`` is chosen, the user is responsible of providing a ``AccountStorageStandard`` + /// If ``SupportedAccountKeys/exactly(_:)`` is chosen, the user is responsible of providing a ``AccountStorageConstraint`` /// that is capable of handling all non-supported ``AccountKey``s. /// - configuration: A ``AccountServiceConfigurationBuilder`` to provide a list of ``AccountServiceConfigurationKey``s. public init( diff --git a/Sources/SpeziAccount/AccountService/Configuration/SupportedAccountKeys.swift b/Sources/SpeziAccount/AccountService/Configuration/SupportedAccountKeys.swift index 8707a119..b271c1f3 100644 --- a/Sources/SpeziAccount/AccountService/Configuration/SupportedAccountKeys.swift +++ b/Sources/SpeziAccount/AccountService/Configuration/SupportedAccountKeys.swift @@ -13,7 +13,7 @@ /// capable of storing. /// /// Upon startup, `SpeziAccount` automatically verifies that the user-configured account values match what the -/// ``AccountService`` is capable of storing or that the user provides a ``AccountStorageStandard`` conforming +/// ``AccountService`` is capable of storing or that the user provides a ``AccountStorageConstraint`` conforming /// `Standard` in their app that is used to handle storage of all unsupported account values. /// /// Access the configuration via the ``AccountServiceConfiguration/supportedAccountKeys``. diff --git a/Sources/SpeziAccount/AccountService/EmbeddableAccountService.swift b/Sources/SpeziAccount/AccountService/EmbeddableAccountService.swift index 3a6d55ff..cc922119 100644 --- a/Sources/SpeziAccount/AccountService/EmbeddableAccountService.swift +++ b/Sources/SpeziAccount/AccountService/EmbeddableAccountService.swift @@ -12,9 +12,9 @@ import Foundation /// A embeddable ``AccountService`` allows to render simplified UI in the ``AccountSetup`` view. /// /// By default, the ``AccountSetup`` renders all ``AccountService`` as a list of buttons that navigate -/// to ``AccountSetupViewStyle/makePrimaryView()`` where login and signup flows are completely defined by the ``AccountService``. +/// to ``AccountSetupViewStyle/makePrimaryView(_:)`` where login and signup flows are completely defined by the ``AccountService``. /// /// However, if there is a single `EmbeddableAccountService` in the list of all configured account service, this /// account service is directly embedded into the main ``AccountSetup`` view for easier access. -/// The view is rendered using ``EmbeddableAccountSetupViewStyle/makeEmbeddedAccountView()`` +/// The view is rendered using ``EmbeddableAccountSetupViewStyle/makeEmbeddedAccountView(_:)`` public protocol EmbeddableAccountService: AccountService where ViewStyle: EmbeddableAccountSetupViewStyle {} diff --git a/Sources/SpeziAccount/AccountService/Wrapper/NotifyStandardBackedAccountService.swift b/Sources/SpeziAccount/AccountService/Wrapper/NotifyStandardBackedAccountService.swift index 26910bdf..dcab3bfa 100644 --- a/Sources/SpeziAccount/AccountService/Wrapper/NotifyStandardBackedAccountService.swift +++ b/Sources/SpeziAccount/AccountService/Wrapper/NotifyStandardBackedAccountService.swift @@ -9,7 +9,7 @@ import Spezi -actor NotifyStandardBackedAccountService: AccountService, _StandardBacked { +actor NotifyStandardBackedAccountService: AccountService, _StandardBacked { @AccountReference private var account let accountService: Service diff --git a/Sources/SpeziAccount/AccountService/Wrapper/StandardBacked.swift b/Sources/SpeziAccount/AccountService/Wrapper/StandardBacked.swift index 59b22907..cd2ff2b0 100644 --- a/Sources/SpeziAccount/AccountService/Wrapper/StandardBacked.swift +++ b/Sources/SpeziAccount/AccountService/Wrapper/StandardBacked.swift @@ -9,7 +9,7 @@ import Spezi -/// Internal marker protocol to determine what ``AccountService`` require assistance by a ``AccountStorageStandard``. +/// Internal marker protocol to determine what ``AccountService`` require assistance by a ``AccountStorageConstraint``. public protocol _StandardBacked: AccountService { // swiftlint:disable:this type_name associatedtype Service: AccountService associatedtype AccountStandard: Standard @@ -88,24 +88,24 @@ extension _StandardBacked where Self: UserIdPasswordAccountService, Service: Use extension AccountService { - func backedBy(standard: any AccountStorageStandard) -> any AccountService { + func backedBy(standard: any AccountStorageConstraint) -> any AccountService { standard.backedService(with: self) } - func backedBy(standard: any AccountNotifyStandard) -> any AccountService { + func backedBy(standard: any AccountNotifyConstraint) -> any AccountService { standard.backedService(with: self) } } -extension AccountStorageStandard { +extension AccountStorageConstraint { fileprivate nonisolated func backedService(with service: Service) -> any AccountService { StorageStandardBackedAccountService(service: service, standard: self) } } -extension AccountNotifyStandard { +extension AccountNotifyConstraint { fileprivate nonisolated func backedService(with service: Service) -> any AccountService { NotifyStandardBackedAccountService(service: service, standard: self) } diff --git a/Sources/SpeziAccount/AccountService/Wrapper/StorageStandardBackedAccountService.swift b/Sources/SpeziAccount/AccountService/Wrapper/StorageStandardBackedAccountService.swift index 9364e43f..5dd0ee14 100644 --- a/Sources/SpeziAccount/AccountService/Wrapper/StorageStandardBackedAccountService.swift +++ b/Sources/SpeziAccount/AccountService/Wrapper/StorageStandardBackedAccountService.swift @@ -10,8 +10,8 @@ import Spezi /// An ``AccountService`` implementation for account services with ``SupportedAccountKeys/exactly(_:)`` configuration -/// to forward unsupported account values to a ``AccountStorageStandard`` implementation. -actor StorageStandardBackedAccountService: AccountService, _StandardBacked { +/// to forward unsupported account values to a ``AccountStorageConstraint`` implementation. +actor StorageStandardBackedAccountService: AccountService, _StandardBacked { @AccountReference private var account let accountService: Service diff --git a/Sources/SpeziAccount/AccountSetupViewStyle/AccountSetupViewStyle.swift b/Sources/SpeziAccount/AccountSetupViewStyle/AccountSetupViewStyle.swift index b5ebeeed..90fef44a 100644 --- a/Sources/SpeziAccount/AccountSetupViewStyle/AccountSetupViewStyle.swift +++ b/Sources/SpeziAccount/AccountSetupViewStyle/AccountSetupViewStyle.swift @@ -34,7 +34,7 @@ public protocol AccountSetupViewStyle { @ViewBuilder func makeServiceButtonLabel(_ service: any AccountService) -> ButtonLabel - /// The primary view that is opened as the destination of the ``makeServiceButtonLabel()-6ihdh`` button. + /// The primary view that is opened as the destination of the ``makeServiceButtonLabel(_:)-54dx4`` button. @ViewBuilder func makePrimaryView(_ service: any AccountService) -> PrimaryView diff --git a/Sources/SpeziAccount/AccountStorageStandard.swift b/Sources/SpeziAccount/AccountStorageConstraint.swift similarity index 95% rename from Sources/SpeziAccount/AccountStorageStandard.swift rename to Sources/SpeziAccount/AccountStorageConstraint.swift index 295b4095..ba5e1265 100644 --- a/Sources/SpeziAccount/AccountStorageStandard.swift +++ b/Sources/SpeziAccount/AccountStorageConstraint.swift @@ -13,7 +13,7 @@ import Spezi /// /// Certain ``AccountService`` implementations might be limited to supported only a specific set of ``AccountKey``s /// (see ``SupportedAccountKeys/exactly(_:)``. If you nonetheless want to use ``AccountKey``s that are unsupported -/// by your ``AccountService``, you may add an implementation of the `AccountStorageStandard` protocol to your App's `Standard`, +/// by your ``AccountService``, you may add an implementation of the `AccountStorageConstraint` protocol to your App's `Standard`, /// inorder to handle storage and retrieval of these additional account values. /// /// - Note: You can use the ``Spezi/Standard/AccountReference`` property wrapper to get access to the global ``Account`` object if you need it to implement additional functionality. @@ -22,7 +22,7 @@ import Spezi /// /// ### Access Account /// - ``Spezi/Standard/AccountReference`` -public protocol AccountStorageStandard: Standard { +public protocol AccountStorageConstraint: Standard { /// Create new associated account data. /// /// - Note: A call to this method might certainly be immediately followed by a call to ``load(_:_:)``. @@ -85,7 +85,7 @@ extension Standard { /// /// Below is a short code example on how to use this property wrapper: /// ```swift - /// public actor MyStandard: AccountStorageStandard { + /// public actor MyStandard: AccountStorageConstraint { /// @AccountReference var account /// } /// ``` diff --git a/Sources/SpeziAccount/AccountValue/AccountKey.swift b/Sources/SpeziAccount/AccountValue/AccountKey.swift index 61577314..4004c937 100644 --- a/Sources/SpeziAccount/AccountValue/AccountKey.swift +++ b/Sources/SpeziAccount/AccountValue/AccountKey.swift @@ -22,7 +22,7 @@ import XCTRuntimeAssertions /// can be safely passed between actor boundaries. /// `Equatable` conformance is required such that views like the ``SignupForm`` can react to changes /// and validate input. -/// `Codable` conformance is required such that ``AccountService``s of ``AccountStorageStandard``s +/// `Codable` conformance is required such that ``AccountService``s of ``AccountStorageConstraint``s /// can easily store arbitrarily defined account values. /// /// ## Topics diff --git a/Sources/SpeziAccount/Model/AdditionalRecordId.swift b/Sources/SpeziAccount/Model/AdditionalRecordId.swift index 443bf354..e15e69b9 100644 --- a/Sources/SpeziAccount/Model/AdditionalRecordId.swift +++ b/Sources/SpeziAccount/Model/AdditionalRecordId.swift @@ -7,7 +7,7 @@ // -/// A stable identifier used by ``AccountStorageStandard`` instances to identity a set of additionally stored records. +/// A stable identifier used by ``AccountStorageConstraint`` instances to identity a set of additionally stored records. /// /// The identifier is built by combining a stable ``AccountService`` identifier and the primary accountID (see ``AccountIdKey``). /// Using both, additional data records of a user can be uniquely identified across ``AccountService`` implementations. diff --git a/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Adding new Account Values.md b/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Adding new Account Values.md index c31a8677..8d56b3b2 100644 --- a/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Adding new Account Values.md +++ b/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Adding new Account Values.md @@ -53,7 +53,7 @@ Your `Value` type requires several protocol conformances. * The `Value` type must conform to `Sendable` to be safely passed across actor boundaries. * The `Value` type must conform to `Equatable` to be easily notified about changes at data entry. -* The `Value` type must conform to `Codable` such that ``AccountService``s or a ``AccountStorageStandard`` can easily store and retrieve +* The `Value` type must conform to `Codable` such that ``AccountService``s or a ``AccountStorageConstraint`` can easily store and retrieve arbitrary `Value` types. ### Accessors diff --git a/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Handling Account Value Storage.md b/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Handling Account Value Storage.md index 010bc683..54662d34 100644 --- a/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Handling Account Value Storage.md +++ b/Sources/SpeziAccount/SpeziAccount.docc/Account Values/Handling Account Value Storage.md @@ -64,7 +64,7 @@ let encoded = details.acceptAll(&visitor) You can iterate through a collection of ``AccountKey``s in a type-safe way using the [Visitor Pattern](https://en.wikipedia.org/wiki/Visitor_pattern). This is provided through the ``AccountKeyVisitor`` protocol and the ``AcceptingAccountKeyVisitor/acceptAll(_:)-1ytax`` method all implemented by `[any AccountKey.Type]` arrays or ``AccountKeyCollection``s. This is useful when you are accessing the ``AccountValues/keys-572sk`` property or -implement a custom storage provider (see ``AccountStorageStandard/load(_:_:)``). +implement a custom storage provider (see ``AccountStorageConstraint/load(_:_:)``). An implementation is similarly structured to the code example shown in the previous section. diff --git a/Sources/SpeziAccount/SpeziAccount.docc/Setup Guides/Custom Storage Provider.md b/Sources/SpeziAccount/SpeziAccount.docc/Setup Guides/Custom Storage Provider.md index 54719703..f42b2c6e 100644 --- a/Sources/SpeziAccount/SpeziAccount.docc/Setup Guides/Custom Storage Provider.md +++ b/Sources/SpeziAccount/SpeziAccount.docc/Setup Guides/Custom Storage Provider.md @@ -1,6 +1,6 @@ # Custom Storage Provider -Store arbitrary account values by providing a ``AccountStorageStandard`` implementation. +Store arbitrary account values by providing a ``AccountStorageConstraint`` implementation.