From 4e0fb7c73872c69e6ac3f890684021c11179a92a Mon Sep 17 00:00:00 2001 From: Tuan Pham <103537251+phantumcode@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:38:29 -0500 Subject: [PATCH 01/13] chore: resolve SwiftFormat errors and warnings at the categories module (#3843) * resolve swiftformat errors and warnings * resolve review comments * move braces back to same-line * fix argument spacing --- Amplify/Amplify.swift | 29 +- Amplify/Categories/API/APICategory.swift | 14 +- .../APICategory+ReachabilityBehavior.swift | 2 +- .../ClientBehavior/APICategoryBehavior.swift | 6 +- .../APICategoryGraphQLBehavior.swift | 2 +- .../APICategoryReachabilityBehavior.swift | 2 +- .../AmplifyOperation+APIPublishers.swift | 2 +- .../Operation/NondeterminsticOperation.swift | 4 +- .../Operation/RetryableGraphQLOperation.swift | 24 +- .../API/Request/GraphQLOperationRequest.swift | 18 +- .../API/Request/GraphQLRequest.swift | 16 +- .../API/Request/RESTOperationRequest.swift | 16 +- .../Categories/API/Request/RESTRequest.swift | 12 +- .../API/Response/GraphQLError.swift | 14 +- .../AnalyticsCategory+ClientBehavior.swift | 6 +- .../Analytics/AnalyticsCategory.swift | 8 +- .../Analytics/AnalyticsProfile.swift | 16 +- .../Analytics/Event/BasicAnalyticsEvent.swift | 6 +- .../Auth/AuthCategory+ClientBehavior.swift | 34 +- .../Auth/AuthCategory+UserBehavior.swift | 14 +- Amplify/Categories/Auth/AuthCategory.swift | 14 +- .../Auth/AuthCategoryBehavior.swift | 43 ++- .../Auth/Models/AuthCodeDeliveryDetails.swift | 6 +- .../Auth/Models/AuthSignUpStep.swift | 3 +- .../Auth/Models/TOTPSetupDetails.swift | 9 +- ...tributeResendConfirmationCodeRequest.swift | 6 +- ...AttributeSendVerificationCodeRequest.swift | 6 +- .../Request/AuthChangePasswordRequest.swift | 8 +- .../AuthConfirmResetPasswordRequest.swift | 10 +- .../AuthConfirmUserAttributeRequest.swift | 8 +- .../Request/AuthFetchSessionRequest.swift | 7 +- .../Request/AuthForgetDeviceRequest.swift | 6 +- .../Request/AuthResetPasswordRequest.swift | 6 +- .../Auth/Request/AuthSignOutRequest.swift | 14 +- .../Auth/Request/AuthSignUpRequest.swift | 6 +- .../AuthUpdateUserAttributeRequest.swift | 6 +- .../AuthUpdateUserAttributesRequest.swift | 6 +- .../Auth/Request/AuthWebUISignInRequest.swift | 14 +- .../Auth/Request/VerifyTOTPSetupRequest.swift | 3 +- .../DataStore/DataStoreCallback+Combine.swift | 4 +- .../DataStore/DataStoreCallback.swift | 6 +- .../DataStoreCategory+Behavior.swift | 70 ++-- .../DataStore/DataStoreCategory.swift | 14 +- .../DataStore/DataStoreCategoryBehavior.swift | 86 +++-- .../DataStore/Model/Internal/Embedded.swift | 16 +- .../Model/Internal/Model+Array.swift | 8 +- .../Model/Internal/Model+Codable.swift | 19 +- .../Model/Internal/Model+DateFormatting.swift | 2 +- .../Model/Internal/Model+Subscript.swift | 4 +- .../Model/Internal/ModelListDecoder.swift | 2 +- .../Model/Internal/ModelProvider.swift | 1 + .../Model/Internal/ModelProviderDecoder.swift | 6 +- .../Model/Internal/ModelRegistry.swift | 33 +- .../Model/Internal/Persistable.swift | 2 +- .../Model/Internal/Schema/AuthRule.swift | 18 +- .../Model/Internal/Schema/Model+Schema.swift | 56 +-- .../Schema/ModelField+Association.swift | 44 +-- .../Internal/Schema/ModelPrimaryKey.swift | 30 +- .../ModelSchema+AuthRulesByOperation.swift | 2 +- .../Schema/ModelSchema+Definition.swift | 331 ++++++++++-------- .../Model/Internal/Schema/ModelSchema.swift | 50 +-- .../Model/Lazy/ArrayLiteralListProvider.swift | 16 +- .../DataStore/Model/Lazy/LazyReference.swift | 14 +- .../DataStore/Model/Lazy/List+Combine.swift | 4 +- .../DataStore/Model/Lazy/List+LazyLoad.swift | 6 +- .../DataStore/Model/Lazy/List+Model.swift | 6 +- .../Model/Lazy/List+Pagination.swift | 6 +- .../DataStore/Model/Model+ModelName.swift | 6 +- .../Categories/DataStore/Model/Model.swift | 8 +- .../DataStore/Model/ModelIdentifiable.swift | 21 +- .../DataStore/Model/PropertyPath.swift | 6 +- .../Temporal/DataStoreError+Temporal.swift | 7 +- .../Model/Temporal/Date+Operation.swift | 6 +- .../DataStore/Model/Temporal/Date.swift | 4 +- .../DataStore/Model/Temporal/DateTime.swift | 6 +- .../Temporal/SpecBasedDateConverting.swift | 12 +- .../Model/Temporal/Temporal+Cache.swift | 8 +- .../Model/Temporal/Temporal+Codable.swift | 6 +- .../Model/Temporal/Temporal+Comparable.swift | 6 +- .../DataStore/Model/Temporal/Temporal.swift | 14 +- .../Model/Temporal/TemporalFormat.swift | 19 +- .../Model/Temporal/Time+Operation.swift | 6 +- .../DataStore/Model/Temporal/Time.swift | 4 +- .../Model/Temporal/TimeZone+Extension.swift | 2 +- .../Categories/DataStore/Query/ModelKey.swift | 44 +-- .../DataStore/Query/QueryOperator.swift | 4 +- .../Query/QueryPaginationInput.swift | 12 +- .../DataStore/Query/QueryPredicate.swift | 10 +- .../DataStoreCategory+Subscribe.swift | 10 +- .../Subscribe/MutationEvent+Model.swift | 42 ++- .../Subscribe/MutationEvent+Schema.swift | 8 +- .../DataStore/Subscribe/MutationEvent.swift | 71 ++-- .../Geo/GeoCategory+ClientBehavior.swift | 12 +- Amplify/Categories/Geo/GeoCategory.swift | 8 +- .../Categories/Geo/GeoCategoryBehavior.swift | 12 +- ...LocationCoordinate2D+Geo.Coordinates.swift | 2 +- .../Geo/Types/Geo+Coordinates.swift | 2 +- Amplify/Categories/Geo/Types/Geo+Error.swift | 8 +- Amplify/Categories/Geo/Types/Geo+Place.swift | 22 +- .../Categories/Geo/Types/Geo+SearchArea.swift | 2 +- .../Geo/Types/Geo+SearchOptions.swift | 16 +- .../Hub/HubCategory+ClientBehavior.swift | 16 +- Amplify/Categories/Hub/HubCategory.swift | 14 +- .../Categories/Hub/HubCategoryBehavior.swift | 16 +- Amplify/Categories/Hub/HubChannel.swift | 4 +- Amplify/Categories/Hub/HubFilter.swift | 6 +- Amplify/Categories/Hub/HubPayload.swift | 8 +- ...LoggingCategory+CategoryConfigurable.swift | 8 +- .../Categories/Logging/LoggingCategory.swift | 14 +- .../Notifications/NotificationsCategory.swift | 2 +- .../PushNotificationsCategory.swift | 6 +- .../PushNotificationsCategory+Types.swift | 4 +- .../PushNotificationsCategory+UserInfo.swift | 6 +- .../Error/PredictionsError+ClientError.swift | 24 +- .../Error/PredictionsError+ServiceError.swift | 28 +- .../Predictions/Models/Attribute.swift | 4 +- .../Predictions/Models/BoundedKeyValue.swift | 4 +- .../Models/Celebrity+Metadata.swift | 4 +- .../Predictions/Models/Celebrity.swift | 6 +- .../Predictions/Models/Emotion+Kind.swift | 4 +- .../Predictions/Models/Emotion.swift | 4 +- .../Models/Entity+DetectionResult.swift | 4 +- .../Predictions/Models/Entity+Kind.swift | 4 +- .../Predictions/Models/Entity+Match.swift | 8 +- .../Predictions/Models/Entity+Metadata.swift | 4 +- .../Predictions/Models/Entity.swift | 4 +- .../Predictions/Models/Gender.swift | 4 +- .../Predictions/Models/GenderAttribute.swift | 4 +- .../Predictions/Models/IdentifiedLine.swift | 4 +- .../Predictions/Models/IdentifiedWord.swift | 4 +- .../Predictions/Models/KeyPhrase.swift | 4 +- .../Predictions/Models/LabelType.swift | 4 +- .../Predictions/Models/Landmark.swift | 8 +- .../Models/Language+DetectionResult.swift | 4 +- .../Predictions/Models/Language.swift | 8 +- .../Models/PartOfSpeech+DetectionResult.swift | 4 +- .../Predictions/Models/PartOfSpeech.swift | 4 +- .../Predictions/Models/Polygon.swift | 4 +- .../Categories/Predictions/Models/Pose.swift | 4 +- .../Predictions/Models/Selection.swift | 4 +- .../Predictions/Models/Sentiment+Kind.swift | 4 +- .../Predictions/Models/Sentiment.swift | 4 +- .../Predictions/Models/SyntaxToken.swift | 4 +- .../Categories/Predictions/Models/Table.swift | 8 +- .../Predictions/Models/TextFormatType.swift | 4 +- .../Categories/Predictions/Models/Voice.swift | 4 +- .../PredictionsCategory+ClientBehavior.swift | 4 +- .../Predictions/PredictionsCategory.swift | 2 +- .../Request/Convert/Convert+Lift.swift | 4 +- .../Convert+SpeechToText+Options.swift | 4 +- .../Convert+SpeechToText+Request.swift | 4 +- .../Convert/Convert+SpeechToText+Result.swift | 4 +- .../Convert/Convert+SpeechToText.swift | 8 +- .../Convert+TextToSpeech+Options.swift | 4 +- .../Convert+TextToSpeech+Request.swift | 4 +- .../Convert/Convert+TextToSpeech+Result.swift | 4 +- .../Convert/Convert+TextToSpeech.swift | 8 +- .../Convert+TranslateText+Options.swift | 4 +- .../Convert+TranslateText+Request.swift | 4 +- .../Convert+TranslateText+Result.swift | 4 +- .../Convert/Convert+TranslateText.swift | 8 +- .../Predictions/Request/Convert/Convert.swift | 26 +- .../Identify+Celebrities+Result.swift | 4 +- .../Identify/Identify+Celebrities.swift | 8 +- .../Request/Identify/Identify+Document.swift | 8 +- .../Identify+DocumentText+Result.swift | 4 +- .../Identify/Identify+Entities+Result.swift | 4 +- .../Request/Identify/Identify+Entities.swift | 8 +- .../Identify+EntityMatches+Result.swift | 4 +- .../Identify/Identify+EntityMatches.swift | 8 +- .../Identify/Identify+Labels+Result.swift | 14 +- .../Request/Identify/Identify+Labels.swift | 8 +- .../Request/Identify/Identify+Lift.swift | 4 +- .../Identify/Identify+Text+Result.swift | 4 +- .../Request/Identify/Identify+Text.swift | 8 +- .../Request/Identify/Identify.swift | 8 +- .../Request/Interpret/Interpret+Result.swift | 4 +- .../Request/Interpret/Interpret.swift | 10 +- .../Request/StorageDownloadDataRequest.swift | 10 +- .../Request/StorageDownloadFileRequest.swift | 8 +- .../Request/StorageGetURLRequest.swift | 16 +- .../Request/StorageListRequest.swift | 16 +- .../Request/StorageRemoveRequest.swift | 6 +- .../Request/StorageUploadDataRequest.swift | 18 +- .../Request/StorageUploadFileRequest.swift | 18 +- .../StorageDownloadDataOperation.swift | 10 +- .../StorageDownloadFileOperation.swift | 10 +- .../StorageUploadDataOperation.swift | 10 +- .../StorageUploadFileOperation.swift | 10 +- .../Storage/Result/StorageListResult.swift | 6 +- .../Categories/Storage/StorageCategory.swift | 16 +- .../Storage/StorageCategoryBehavior.swift | 6 +- .../Configuration/AmplifyConfiguration.swift | 22 +- .../Configuration/AmplifyOutputsData.swift | 68 ++-- .../Configuration/ConfigurationError.swift | 2 +- .../Internal/Amplify+Resolve.swift | 2 +- Amplify/Core/Model/BasicUserProfile.swift | 12 +- Amplify/Core/Model/UserProfile.swift | 14 +- .../Core/Model/UserProfilePropertyValue.swift | 2 +- Amplify/Core/Support/AccessLevel.swift | 1 + .../Core/Support/AmplifyAsyncSequence.swift | 8 +- .../AmplifyAsyncThrowingSequence.swift | 8 +- Amplify/Core/Support/AmplifyError.swift | 2 +- .../Core/Support/AmplifyErrorMessages.swift | 18 +- ...yInProcessReportingOperation+Combine.swift | 2 +- .../AmplifyInProcessReportingOperation.swift | 30 +- .../Support/AmplifyOperation+Combine.swift | 2 +- .../Core/Support/AmplifyOperation+Hub.swift | 3 +- Amplify/Core/Support/AmplifyOperation.swift | 18 +- .../AmplifyTask+OperationTaskAdapters.swift | 38 +- .../Core/Support/AmplifyTaskExecution.swift | 1 + Amplify/Core/Support/AmplifyTaskGateway.swift | 16 +- Amplify/Core/Support/Array+Extensions.swift | 4 +- .../Core/Support/AsychronousOperation.swift | 18 +- Amplify/Core/Support/AtomicDictionary.swift | 2 +- Amplify/Core/Support/AtomicValue+Bool.swift | 4 +- .../Core/Support/AtomicValue+Numeric.swift | 6 +- ...omicValue+RangeReplaceableCollection.swift | 10 +- Amplify/Core/Support/Cancellable.swift | 2 +- Amplify/Core/Support/ChildTask.swift | 6 +- Amplify/Core/Support/DeviceInfo.swift | 15 +- .../Support/DispatchSource+MakeOneOff.swift | 18 +- .../Core/Support/Encodable+AnyEncodable.swift | 4 +- Amplify/Core/Support/Fatal.swift | 18 +- .../Internal/InternalTask+AsyncSequence.swift | 12 +- .../Support/Internal/InternalTask+Hub.swift | 40 ++- .../Support/Internal/NSLocking+Execute.swift | 6 +- Amplify/Core/Support/JSONValue+KeyPath.swift | 6 +- Amplify/Core/Support/JSONValue.swift | 16 +- .../Support/OperationCancelledError.swift | 2 +- Amplify/Core/Support/Operations+Combine.swift | 2 +- Amplify/Core/Support/Optional+Extension.swift | 4 +- Amplify/Core/Support/Result+Void.swift | 4 +- Amplify/Core/Support/String+Extensions.swift | 8 +- Amplify/Core/Support/TaskQueue.swift | 4 +- .../Core/Support/TimeInterval+Helper.swift | 12 +- .../AWSHubPlugin/AWSHubPlugin.swift | 18 +- .../Internal/ConcurrentDispatcher.swift | 2 +- .../Internal/SerialDispatcher.swift | 6 +- .../AWSUnifiedLoggingPlugin.swift | 32 +- .../Internal/OSLogWrapper.swift | 60 ++-- Amplify/DevMenu/AmplifyDevMenu.swift | 3 +- Amplify/DevMenu/AmplifyVersionable.swift | 4 +- Amplify/DevMenu/Data/DeviceInfoHelper.swift | 14 +- Amplify/DevMenu/Data/DeviceInfoItem.swift | 2 +- .../DevMenu/Data/EnvironmentInfoHelper.swift | 2 +- Amplify/DevMenu/Data/IssueInfo.swift | 4 +- Amplify/DevMenu/Data/LogEntryHelper.swift | 5 +- Amplify/DevMenu/Data/PluginInfoHelper.swift | 2 +- Amplify/DevMenu/DevMenuStringConstants.swift | 2 +- .../Trigger/LongPressGestureRecognizer.swift | 6 +- Amplify/DevMenu/View/DevMenuList.swift | 3 +- Amplify/DevMenu/View/InfoRow.swift | 4 +- Amplify/DevMenu/View/IssueReporter.swift | 40 ++- .../AsyncTesting/AsyncExpectation.swift | 16 +- .../Sources/AsyncTesting/AsyncTesting.swift | 6 +- .../XCTestCase+AsyncTesting.swift | 41 ++- ...mplifyConfigurationInitFromFileTests.swift | 2 +- ...faultHubPluginPerformanceTestHelpers.swift | 33 +- Package.swift | 2 +- 260 files changed, 1802 insertions(+), 1369 deletions(-) diff --git a/Amplify/Amplify.swift b/Amplify/Amplify.swift index fdc88954a3..b6f8bb79d7 100644 --- a/Amplify/Amplify.swift +++ b/Amplify/Amplify.swift @@ -33,37 +33,37 @@ public class Amplify { // ease of testing. /// - Tag: Amplify.Analytics - public static internal(set) var Analytics = AnalyticsCategory() + public internal(set) static var Analytics = AnalyticsCategory() /// - Tag: Amplify.API - public static internal(set) var API: APICategory = APICategory() + public internal(set) static var API = APICategory() /// - Tag: Amplify.Auth - public static internal(set) var Auth = AuthCategory() + public internal(set) static var Auth = AuthCategory() /// - Tag: Amplify.DataStore - public static internal(set) var DataStore = DataStoreCategory() + public internal(set) static var DataStore = DataStoreCategory() /// - Tag: Amplify.Geo - public static internal(set) var Geo = GeoCategory() + public internal(set) static var Geo = GeoCategory() /// - Tag: Amplify.Hub - public static internal(set) var Hub = HubCategory() + public internal(set) static var Hub = HubCategory() /// - Tag: Amplify.Notifications - public static internal(set) var Notifications = NotificationsCategory() + public internal(set) static var Notifications = NotificationsCategory() /// - Tag: Amplify.Predictions - public static internal(set) var Predictions = PredictionsCategory() + public internal(set) static var Predictions = PredictionsCategory() /// - Tag: Amplify.Storage - public static internal(set) var Storage = StorageCategory() + public internal(set) static var Storage = StorageCategory() /// Special case category. We protect this with an AtomicValue because it is used by reset() /// methods during setup & teardown of tests /// /// - Tag: Amplify.Logging - public static internal(set) var Logging: LoggingCategory { + public internal(set) static var Logging: LoggingCategory { get { loggingAtomic.get() } @@ -73,13 +73,15 @@ public class Amplify { } private static let loggingAtomic = AtomicValue(initialValue: LoggingCategory()) + // swiftlint:disable cyclomatic_complexity + /// Adds `plugin` to the category /// /// See: [Category.removePlugin(for:)](x-source-tag://Category.removePlugin) /// /// - Parameter plugin: The plugin to add /// - Tag: Amplify.add_plugin - public static func add(plugin: P) throws { + public static func add(plugin: some Plugin) throws { log.debug("Adding plugin: \(plugin))") switch plugin { case let plugin as AnalyticsCategoryPlugin: @@ -105,8 +107,11 @@ public class Amplify { default: throw PluginError.pluginConfigurationError( "Plugin category does not exist.", - "Verify that the library version is correct and supports the plugin's category.") + "Verify that the library version is correct and supports the plugin's category." + ) } + + // swiftlint:enable cyclomatic_complexity } } diff --git a/Amplify/Categories/API/APICategory.swift b/Amplify/Categories/API/APICategory.swift index 4725180daa..9478ff26d0 100644 --- a/Amplify/Categories/API/APICategory.swift +++ b/Amplify/Categories/API/APICategory.swift @@ -6,7 +6,7 @@ // /// The API category provides a solution for making HTTP requests to REST and GraphQL endpoints. -final public class APICategory: Category { +public final class APICategory: Category { /// The category type for API public var categoryType: CategoryType { .api @@ -57,8 +57,10 @@ final public class APICategory: Category { let key = plugin.key guard !key.isEmpty else { let pluginDescription = String(describing: plugin) - let error = APIError.invalidConfiguration("Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + let error = APIError.invalidConfiguration( + "Plugin \(pluginDescription) has an empty `key`.", + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -81,8 +83,10 @@ final public class APICategory: Category { public func getPlugin(for key: PluginKey) throws -> APICategoryPlugin { guard let plugin = plugins[key] else { let keys = plugins.keys.joined(separator: ", ") - let error = APIError.invalidConfiguration("No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + let error = APIError.invalidConfiguration( + "No plugin has been added for '\(key)'.", + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/API/ClientBehavior/APICategory+ReachabilityBehavior.swift b/Amplify/Categories/API/ClientBehavior/APICategory+ReachabilityBehavior.swift index 1f714f94ef..050a0b7f68 100644 --- a/Amplify/Categories/API/ClientBehavior/APICategory+ReachabilityBehavior.swift +++ b/Amplify/Categories/API/ClientBehavior/APICategory+ReachabilityBehavior.swift @@ -6,8 +6,8 @@ // #if canImport(Combine) -import Foundation import Combine +import Foundation extension APICategory: APICategoryReachabilityBehavior { #if !os(watchOS) diff --git a/Amplify/Categories/API/ClientBehavior/APICategoryBehavior.swift b/Amplify/Categories/API/ClientBehavior/APICategoryBehavior.swift index 3c2356d564..d17b2f98d3 100644 --- a/Amplify/Categories/API/ClientBehavior/APICategoryBehavior.swift +++ b/Amplify/Categories/API/ClientBehavior/APICategoryBehavior.swift @@ -7,8 +7,8 @@ /// Behavior of the API category that clients will use public typealias APICategoryBehavior = - APICategoryRESTBehavior & + APICategoryAuthProviderFactoryBehavior & APICategoryGraphQLBehavior & APICategoryInterceptorBehavior & - APICategoryReachabilityBehavior & - APICategoryAuthProviderFactoryBehavior + APICategoryRESTBehavior & + APICategoryReachabilityBehavior diff --git a/Amplify/Categories/API/ClientBehavior/APICategoryGraphQLBehavior.swift b/Amplify/Categories/API/ClientBehavior/APICategoryGraphQLBehavior.swift index d149b5d945..05bda4d470 100644 --- a/Amplify/Categories/API/ClientBehavior/APICategoryGraphQLBehavior.swift +++ b/Amplify/Categories/API/ClientBehavior/APICategoryGraphQLBehavior.swift @@ -35,7 +35,7 @@ public protocol APICategoryGraphQLBehavior: AnyObject { /// - request: The GraphQL request containing apiName, document, variables, and responseType /// - valueListener: Invoked when the GraphQL subscription receives a new value from the service /// - completionListener: Invoked when the subscription has terminated - /// - Returns: The AmplifyInProcessReportingOperation being enqueued + /// - Returns: The AmplifyInProcessReportingOperation being enqueued func subscribe( request: GraphQLRequest ) -> AmplifyAsyncThrowingSequence> diff --git a/Amplify/Categories/API/ClientBehavior/APICategoryReachabilityBehavior.swift b/Amplify/Categories/API/ClientBehavior/APICategoryReachabilityBehavior.swift index d14ab48a3b..ad28239d43 100644 --- a/Amplify/Categories/API/ClientBehavior/APICategoryReachabilityBehavior.swift +++ b/Amplify/Categories/API/ClientBehavior/APICategoryReachabilityBehavior.swift @@ -6,8 +6,8 @@ // #if canImport(Combine) -import Foundation import Combine +import Foundation /// API Reachability Behavior public protocol APICategoryReachabilityBehavior { diff --git a/Amplify/Categories/API/Operation/AmplifyOperation+APIPublishers.swift b/Amplify/Categories/API/Operation/AmplifyOperation+APIPublishers.swift index 83a3d25e76..0f2132d04d 100644 --- a/Amplify/Categories/API/Operation/AmplifyOperation+APIPublishers.swift +++ b/Amplify/Categories/API/Operation/AmplifyOperation+APIPublishers.swift @@ -6,8 +6,8 @@ // #if canImport(Combine) -import Foundation import Combine +import Foundation // MARK: - GraphQLSubscriptionOperation diff --git a/Amplify/Categories/API/Operation/NondeterminsticOperation.swift b/Amplify/Categories/API/Operation/NondeterminsticOperation.swift index cd17b65fe5..292cb7d1f3 100644 --- a/Amplify/Categories/API/Operation/NondeterminsticOperation.swift +++ b/Amplify/Categories/API/Operation/NondeterminsticOperation.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // - import Combine + /** A non-deterministic operation offers multiple paths to accomplish its task. It attempts the next path if all preceding paths have failed with an error that allows for continuation. @@ -62,7 +62,7 @@ final class NondeterminsticOperation { self?.task = Task { [weak self] in do { if let self { - promise(.success(try await self.run())) + try await promise(.success(run())) } else { promise(.failure(NondeterminsticOperationError.cancelled)) } diff --git a/Amplify/Categories/API/Operation/RetryableGraphQLOperation.swift b/Amplify/Categories/API/Operation/RetryableGraphQLOperation.swift index d746ba4905..197427bcae 100644 --- a/Amplify/Categories/API/Operation/RetryableGraphQLOperation.swift +++ b/Amplify/Categories/API/Operation/RetryableGraphQLOperation.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Combine +import Foundation // MARK: - RetryableGraphQLOperation @@ -16,7 +16,7 @@ public final class RetryableGraphQLOperation { private let nondeterminsticOperation: NondeterminsticOperation.Success> public init( - requestStream: AsyncStream<() async throws -> GraphQLTask.Success> + requestStream: AsyncStream < () async throws -> GraphQLTask.Success> ) { self.nondeterminsticOperation = NondeterminsticOperation( operations: requestStream, @@ -80,7 +80,7 @@ public final class RetryableGraphQLSubscriptionOperation { private let nondeterminsticOperation: NondeterminsticOperation> public init( - requestStream: AsyncStream<() async throws -> AmplifyAsyncThrowingSequence> + requestStream: AsyncStream < () async throws -> AmplifyAsyncThrowingSequence < SubscriptionEvents>> ) { self.nondeterminsticOperation = NondeterminsticOperation(operations: requestStream) } @@ -91,7 +91,7 @@ public final class RetryableGraphQLSubscriptionOperation { public func subscribe() -> AnyPublisher { let subject = PassthroughSubject() - self.task = Task { await self.trySubscribe(subject) } + task = Task { await self.trySubscribe(subject) } return subject.eraseToAnyPublisher() } @@ -99,7 +99,7 @@ public final class RetryableGraphQLSubscriptionOperation { var apiError: APIError? do { try Task.checkCancellation() - let sequence = try await self.nondeterminsticOperation.run() + let sequence = try await nondeterminsticOperation.run() defer { sequence.cancel() } for try await event in sequence { try Task.checkCancellation() @@ -122,13 +122,13 @@ public final class RetryableGraphQLSubscriptionOperation { } public func cancel() { - self.task?.cancel() - self.nondeterminsticOperation.cancel() + task?.cancel() + nondeterminsticOperation.cancel() } } -extension AsyncSequence { - fileprivate var asyncStream: AsyncStream { +private extension AsyncSequence { + var asyncStream: AsyncStream { AsyncStream { continuation in Task { var it = self.makeAsyncIterator() @@ -145,11 +145,11 @@ extension AsyncSequence { } } -extension RetryableGraphQLSubscriptionOperation { - public static var log: Logger { +public extension RetryableGraphQLSubscriptionOperation { + static var log: Logger { Amplify.Logging.logger(forCategory: CategoryType.api.displayName, forNamespace: String(describing: self)) } - public var log: Logger { + var log: Logger { Self.log } } diff --git a/Amplify/Categories/API/Request/GraphQLOperationRequest.swift b/Amplify/Categories/API/Request/GraphQLOperationRequest.swift index 2f5ebf1ed2..994b30c5b6 100644 --- a/Amplify/Categories/API/Request/GraphQLOperationRequest.swift +++ b/Amplify/Categories/API/Request/GraphQLOperationRequest.swift @@ -32,14 +32,16 @@ public struct GraphQLOperationRequest: AmplifyOperationRequest { public let options: Options /// Initializer for GraphQLOperationRequest - public init(apiName: String?, - operationType: GraphQLOperationType, - document: String, - variables: [String: Any]? = nil, - responseType: R.Type, - decodePath: String? = nil, - authMode: AuthorizationMode? = nil, - options: Options) { + public init( + apiName: String?, + operationType: GraphQLOperationType, + document: String, + variables: [String: Any]? = nil, + responseType: R.Type, + decodePath: String? = nil, + authMode: AuthorizationMode? = nil, + options: Options + ) { self.apiName = apiName self.operationType = operationType self.document = document diff --git a/Amplify/Categories/API/Request/GraphQLRequest.swift b/Amplify/Categories/API/Request/GraphQLRequest.swift index ba0086de66..88915bb0ba 100644 --- a/Amplify/Categories/API/Request/GraphQLRequest.swift +++ b/Amplify/Categories/API/Request/GraphQLRequest.swift @@ -35,13 +35,15 @@ public struct GraphQLRequest { /// Options to adjust the behavior of this request, including plugin-options public var options: Options? - public init(apiName: String? = nil, - document: String, - variables: [String: Any]? = nil, - responseType: R.Type, - decodePath: String? = nil, - authMode: AuthorizationMode? = nil, - options: GraphQLRequest.Options? = nil) { + public init( + apiName: String? = nil, + document: String, + variables: [String: Any]? = nil, + responseType: R.Type, + decodePath: String? = nil, + authMode: AuthorizationMode? = nil, + options: GraphQLRequest.Options? = nil + ) { self.apiName = apiName self.document = document self.variables = variables diff --git a/Amplify/Categories/API/Request/RESTOperationRequest.swift b/Amplify/Categories/API/Request/RESTOperationRequest.swift index b1e5deaf8e..a9af7576b6 100644 --- a/Amplify/Categories/API/Request/RESTOperationRequest.swift +++ b/Amplify/Categories/API/Request/RESTOperationRequest.swift @@ -32,13 +32,15 @@ public struct RESTOperationRequest: AmplifyOperationRequest { public let options: Options /// Initializer with all properties - public init(apiName: String?, - operationType: RESTOperationType, - path: String? = nil, - headers: [String: String]? = nil, - queryParameters: [String: String]? = nil, - body: Data? = nil, - options: Options) { + public init( + apiName: String?, + operationType: RESTOperationType, + path: String? = nil, + headers: [String: String]? = nil, + queryParameters: [String: String]? = nil, + body: Data? = nil, + options: Options + ) { self.apiName = apiName self.operationType = operationType self.path = path diff --git a/Amplify/Categories/API/Request/RESTRequest.swift b/Amplify/Categories/API/Request/RESTRequest.swift index 5af207568e..a576983ee3 100644 --- a/Amplify/Categories/API/Request/RESTRequest.swift +++ b/Amplify/Categories/API/Request/RESTRequest.swift @@ -27,11 +27,13 @@ public class RESTRequest { public let body: Data? /// Initializer with all properties - public init(apiName: String? = nil, - path: String? = nil, - headers: [String: String]? = nil, - queryParameters: [String: String]? = nil, - body: Data? = nil) { + public init( + apiName: String? = nil, + path: String? = nil, + headers: [String: String]? = nil, + queryParameters: [String: String]? = nil, + body: Data? = nil + ) { let inputHeaders = headers ?? [:] self.headers = inputHeaders.merging( ["Cache-Control": "no-store"], diff --git a/Amplify/Categories/API/Response/GraphQLError.swift b/Amplify/Categories/API/Response/GraphQLError.swift index 7d1d21f104..b970a20870 100644 --- a/Amplify/Categories/API/Response/GraphQLError.swift +++ b/Amplify/Categories/API/Response/GraphQLError.swift @@ -21,10 +21,12 @@ public struct GraphQLError: Decodable { public let extensions: [String: JSONValue]? /// Initializer with all properties - public init(message: String, - locations: [Location]? = nil, - path: [JSONValue]? = nil, - extensions: [String: JSONValue]? = nil) { + public init( + message: String, + locations: [Location]? = nil, + path: [JSONValue]? = nil, + extensions: [String: JSONValue]? = nil + ) { self.message = message self.locations = locations self.path = path @@ -32,10 +34,10 @@ public struct GraphQLError: Decodable { } } -extension GraphQLError { +public extension GraphQLError { /// Both `line` and `column` are positive numbers describing the beginning of an associated syntax element - public struct Location: Decodable { + struct Location: Decodable { /// The line describing the associated syntax element public let line: Int diff --git a/Amplify/Categories/Analytics/AnalyticsCategory+ClientBehavior.swift b/Amplify/Categories/Analytics/AnalyticsCategory+ClientBehavior.swift index e73abe1c15..0f184b96ff 100644 --- a/Amplify/Categories/Analytics/AnalyticsCategory+ClientBehavior.swift +++ b/Amplify/Categories/Analytics/AnalyticsCategory+ClientBehavior.swift @@ -40,14 +40,14 @@ extension AnalyticsCategory: AnalyticsCategoryBehavior { } /// Methods that wrap `AnalyticsCategoryBehavior` to provides additional useful calling patterns -extension AnalyticsCategory { +public extension AnalyticsCategory { /// Registered global properties can be unregistered though this method. In case no keys are provided, *all* /// registered global properties will be unregistered. Duplicate keys will be ignored. This method can be called /// from `Amplify.Analytics` and is a wrapper for `unregisterGlobalProperties(_ keys: Set? = nil)` /// /// - Parameter keys: one or more of property names to unregister - public func unregisterGlobalProperties(_ keys: String...) { + func unregisterGlobalProperties(_ keys: String...) { plugin.unregisterGlobalProperties(keys.isEmpty ? nil : Set(keys)) } @@ -56,7 +56,7 @@ extension AnalyticsCategory { /// from `Amplify.Analytics` and is a wrapper for `unregisterGlobalProperties(_ keys: Set? = nil)` /// /// - Parameter keys: an array of property names to unregister - public func unregisterGlobalProperties(_ keys: [String]) { + func unregisterGlobalProperties(_ keys: [String]) { plugin.unregisterGlobalProperties(keys.isEmpty ? nil : Set(keys)) } } diff --git a/Amplify/Categories/Analytics/AnalyticsCategory.swift b/Amplify/Categories/Analytics/AnalyticsCategory.swift index 4697d51685..79a0d53976 100644 --- a/Amplify/Categories/Analytics/AnalyticsCategory.swift +++ b/Amplify/Categories/Analytics/AnalyticsCategory.swift @@ -6,7 +6,7 @@ // /// The Analytics category enables you to collect analytics data for your app. -final public class AnalyticsCategory: Category { +public final class AnalyticsCategory: Category { /// Analytics category type public let categoryType = CategoryType.analytics @@ -56,7 +56,8 @@ final public class AnalyticsCategory: Category { let pluginDescription = String(describing: plugin) let error = AnalyticsError.configuration( "Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -81,7 +82,8 @@ final public class AnalyticsCategory: Category { let keys = plugins.keys.joined(separator: ", ") let error = AnalyticsError.configuration( "No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/Analytics/AnalyticsProfile.swift b/Amplify/Categories/Analytics/AnalyticsProfile.swift index d4f1d6e3e4..1f480a5e35 100644 --- a/Amplify/Categories/Analytics/AnalyticsProfile.swift +++ b/Amplify/Categories/Analytics/AnalyticsProfile.swift @@ -32,11 +32,13 @@ public struct AnalyticsUserProfile { /// - plan: The plan for the user /// - location: Location data about the user /// - properties: Properties of the user profile - public init(name: String? = nil, - email: String? = nil, - plan: String? = nil, - location: Location? = nil, - properties: AnalyticsProperties? = nil) { + public init( + name: String? = nil, + email: String? = nil, + plan: String? = nil, + location: Location? = nil, + properties: AnalyticsProperties? = nil + ) { self.name = name self.email = email self.plan = plan @@ -45,10 +47,10 @@ public struct AnalyticsUserProfile { } } -extension AnalyticsUserProfile { +public extension AnalyticsUserProfile { /// Location specific data - public typealias Location = UserProfileLocation + typealias Location = UserProfileLocation } extension AnalyticsUserProfile: UserProfile { diff --git a/Amplify/Categories/Analytics/Event/BasicAnalyticsEvent.swift b/Amplify/Categories/Analytics/Event/BasicAnalyticsEvent.swift index 2e2792a153..ce9762ac15 100644 --- a/Amplify/Categories/Analytics/Event/BasicAnalyticsEvent.swift +++ b/Amplify/Categories/Analytics/Event/BasicAnalyticsEvent.swift @@ -20,8 +20,10 @@ public struct BasicAnalyticsEvent: AnalyticsEvent { /// - Parameters: /// - name: The name of the event /// - properties: Properties of the event - public init(name: String, - properties: AnalyticsProperties? = nil) { + public init( + name: String, + properties: AnalyticsProperties? = nil + ) { self.name = name self.properties = properties } diff --git a/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift b/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift index 8896be20ea..a1e9d37102 100644 --- a/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategory+ClientBehavior.swift @@ -17,9 +17,11 @@ extension AuthCategory: AuthCategoryBehavior { return try await plugin.signUp(username: username, password: password, options: options) } - public func confirmSignUp(for username: String, - confirmationCode: String, - options: AuthConfirmSignUpRequest.Options? = nil) async throws -> AuthSignUpResult { + public func confirmSignUp( + for username: String, + confirmationCode: String, + options: AuthConfirmSignUpRequest.Options? = nil + ) async throws -> AuthSignUpResult { return try await plugin.confirmSignUp(for: username, confirmationCode: confirmationCode, options: options) } @@ -30,26 +32,32 @@ extension AuthCategory: AuthCategoryBehavior { return try await plugin.resendSignUpCode(for: username, options: options) } - public func signIn(username: String? = nil, - password: String? = nil, - options: AuthSignInRequest.Options? = nil) async throws -> AuthSignInResult { + public func signIn( + username: String? = nil, + password: String? = nil, + options: AuthSignInRequest.Options? = nil + ) async throws -> AuthSignInResult { return try await plugin.signIn(username: username, password: password, options: options) } #if os(iOS) || os(macOS) public func signInWithWebUI( presentationAnchor: AuthUIPresentationAnchor? = nil, - options: AuthWebUISignInRequest.Options? = nil) async throws -> AuthSignInResult { + options: AuthWebUISignInRequest.Options? = nil + ) async throws -> AuthSignInResult { return try await plugin.signInWithWebUI(presentationAnchor: presentationAnchor, options: options) } public func signInWithWebUI( for authProvider: AuthProvider, presentationAnchor: AuthUIPresentationAnchor? = nil, - options: AuthWebUISignInRequest.Options? = nil) async throws -> AuthSignInResult { - return try await plugin.signInWithWebUI(for: authProvider, - presentationAnchor: presentationAnchor, - options: options) + options: AuthWebUISignInRequest.Options? = nil + ) async throws -> AuthSignInResult { + return try await plugin.signInWithWebUI( + for: authProvider, + presentationAnchor: presentationAnchor, + options: options + ) } #endif @@ -80,8 +88,8 @@ extension AuthCategory: AuthCategoryBehavior { } public func confirmResetPassword( - for username: String, with - newPassword: String, + for username: String, + with newPassword: String, confirmationCode: String, options: AuthConfirmResetPasswordRequest.Options? = nil ) async throws { diff --git a/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift b/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift index 6589e03083..9c4651a6b5 100644 --- a/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategory+UserBehavior.swift @@ -26,8 +26,10 @@ extension AuthCategory: AuthCategoryUserBehavior { try await plugin.update(userAttribute: userAttribute, options: options) } - public func update(userAttributes: [AuthUserAttribute], - options: AuthUpdateUserAttributesRequest.Options? = nil) + public func update( + userAttributes: [AuthUserAttribute], + options: AuthUpdateUserAttributesRequest.Options? = nil + ) async throws -> [AuthUserAttributeKey: AuthUpdateAttributeResult] { try await plugin.update(userAttributes: userAttributes, options: options) } @@ -47,9 +49,11 @@ extension AuthCategory: AuthCategoryUserBehavior { try await plugin.sendVerificationCode(forUserAttributeKey: userAttributeKey, options: options) } - public func confirm(userAttribute: AuthUserAttributeKey, - confirmationCode: String, - options: AuthConfirmUserAttributeRequest.Options? = nil) async throws { + public func confirm( + userAttribute: AuthUserAttributeKey, + confirmationCode: String, + options: AuthConfirmUserAttributeRequest.Options? = nil + ) async throws { try await plugin.confirm( userAttribute: userAttribute, confirmationCode: confirmationCode, diff --git a/Amplify/Categories/Auth/AuthCategory.swift b/Amplify/Categories/Auth/AuthCategory.swift index 04fb854778..afa4b22c76 100644 --- a/Amplify/Categories/Auth/AuthCategory.swift +++ b/Amplify/Categories/Auth/AuthCategory.swift @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 // -final public class AuthCategory: Category { +public final class AuthCategory: Category { public let categoryType = CategoryType.auth @@ -51,8 +51,10 @@ final public class AuthCategory: Category { let key = plugin.key guard !key.isEmpty else { let pluginDescription = String(describing: plugin) - let error = AuthError.configuration("Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + let error = AuthError.configuration( + "Plugin \(pluginDescription) has an empty `key`.", + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -75,8 +77,10 @@ final public class AuthCategory: Category { public func getPlugin(for key: PluginKey) throws -> AuthCategoryPlugin { guard let plugin = plugins[key] else { let keys = plugins.keys.joined(separator: ", ") - let error = AuthError.configuration("No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + let error = AuthError.configuration( + "No plugin has been added for '\(key)'.", + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/Auth/AuthCategoryBehavior.swift b/Amplify/Categories/Auth/AuthCategoryBehavior.swift index 68f6cc2f7f..91ded88b3d 100644 --- a/Amplify/Categories/Auth/AuthCategoryBehavior.swift +++ b/Amplify/Categories/Auth/AuthCategoryBehavior.swift @@ -8,6 +8,7 @@ import Foundation #if os(iOS) || os(macOS) import AuthenticationServices + public typealias AuthUIPresentationAnchor = ASPresentationAnchor #endif @@ -39,9 +40,11 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi /// - username: Username used that was used to signUp. /// - confirmationCode: Confirmation code received to the user. /// - options: Parameters specific to plugin behavior - func confirmSignUp(for username: String, - confirmationCode: String, - options: AuthConfirmSignUpRequest.Options?) async throws -> AuthSignUpResult + func confirmSignUp( + for username: String, + confirmationCode: String, + options: AuthConfirmSignUpRequest.Options? + ) async throws -> AuthSignUpResult /// Resends the confirmation code to confirm the signUp process /// @@ -62,9 +65,11 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi /// - username: Username to signIn the user /// - password: Password to signIn the user /// - options: Parameters specific to plugin behavior - func signIn(username: String?, - password: String?, - options: AuthSignInRequest.Options?) async throws -> AuthSignInResult + func signIn( + username: String?, + password: String?, + options: AuthSignInRequest.Options? + ) async throws -> AuthSignInResult #if os(iOS) || os(macOS) /// SignIn using pre configured web UI. @@ -74,8 +79,10 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi /// - Parameters: /// - presentationAnchor: Anchor on which the UI is presented. /// - options: Parameters specific to plugin behavior. - func signInWithWebUI(presentationAnchor: AuthUIPresentationAnchor?, - options: AuthWebUISignInRequest.Options?) async throws -> AuthSignInResult + func signInWithWebUI( + presentationAnchor: AuthUIPresentationAnchor?, + options: AuthWebUISignInRequest.Options? + ) async throws -> AuthSignInResult /// SignIn using an auth provider on a web UI /// @@ -87,9 +94,11 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi /// - authProvider: Auth provider used to signIn. /// - presentationAnchor: Anchor on which the UI is presented. /// - options: Parameters specific to plugin behavior. - func signInWithWebUI(for authProvider: AuthProvider, - presentationAnchor: AuthUIPresentationAnchor?, - options: AuthWebUISignInRequest.Options?) async throws -> AuthSignInResult + func signInWithWebUI( + for authProvider: AuthProvider, + presentationAnchor: AuthUIPresentationAnchor?, + options: AuthWebUISignInRequest.Options? + ) async throws -> AuthSignInResult #endif /// Confirms a next step in signIn flow. @@ -122,8 +131,10 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi /// - Parameters: /// - username: username whose password need to reset /// - options: Parameters specific to plugin behavior - func resetPassword(for username: String, - options: AuthResetPasswordRequest.Options?) async throws -> AuthResetPasswordResult + func resetPassword( + for username: String, + options: AuthResetPasswordRequest.Options? + ) async throws -> AuthResetPasswordResult /// Confirms a reset password flow /// @@ -140,10 +151,10 @@ public protocol AuthCategoryBehavior: AuthCategoryUserBehavior, AuthCategoryDevi ) async throws /// Initiates TOTP Setup - /// + /// /// Invoke this operation to setup TOTP for the user while signed in. - /// Calling this method will initiate TOTP setup process and - /// returns a shared secret that can be used to generate QR code. + /// Calling this method will initiate TOTP setup process and + /// returns a shared secret that can be used to generate QR code. /// The setup details also contains a URI generator helper that can be used to retireve a TOTP Setup URI. /// func setUpTOTP() async throws -> TOTPSetupDetails diff --git a/Amplify/Categories/Auth/Models/AuthCodeDeliveryDetails.swift b/Amplify/Categories/Auth/Models/AuthCodeDeliveryDetails.swift index 1f73a5ec0e..af5b81ff46 100644 --- a/Amplify/Categories/Auth/Models/AuthCodeDeliveryDetails.swift +++ b/Amplify/Categories/Auth/Models/AuthCodeDeliveryDetails.swift @@ -18,8 +18,10 @@ public struct AuthCodeDeliveryDetails { /// Attribute that is confirmed or verified. public let attributeKey: AuthUserAttributeKey? - public init(destination: DeliveryDestination, - attributeKey: AuthUserAttributeKey? = nil) { + public init( + destination: DeliveryDestination, + attributeKey: AuthUserAttributeKey? = nil + ) { self.destination = destination self.attributeKey = attributeKey } diff --git a/Amplify/Categories/Auth/Models/AuthSignUpStep.swift b/Amplify/Categories/Auth/Models/AuthSignUpStep.swift index 2d66d9cf56..15e74aa8f0 100644 --- a/Amplify/Categories/Auth/Models/AuthSignUpStep.swift +++ b/Amplify/Categories/Auth/Models/AuthSignUpStep.swift @@ -14,7 +14,8 @@ public enum AuthSignUpStep { case confirmUser( AuthCodeDeliveryDetails? = nil, AdditionalInfo? = nil, - UserId? = nil) + UserId? = nil + ) /// Sign up is complete case done diff --git a/Amplify/Categories/Auth/Models/TOTPSetupDetails.swift b/Amplify/Categories/Auth/Models/TOTPSetupDetails.swift index 608ddcab77..fe432e2e8d 100644 --- a/Amplify/Categories/Auth/Models/TOTPSetupDetails.swift +++ b/Amplify/Categories/Auth/Models/TOTPSetupDetails.swift @@ -26,15 +26,18 @@ public struct TOTPSetupDetails { /// (for example, if the parameter string contains characters that are illegal in a URL, or is an empty string). public func getSetupURI( appName: String, - accountName: String? = nil) throws -> URL { + accountName: String? = nil + ) throws -> URL { guard let URL = URL( - string: "otpauth://totp/\(appName):\(accountName ?? username)?secret=\(sharedSecret)&issuer=\(appName)") else { + string: "otpauth://totp/\(appName):\(accountName ?? username)?secret=\(sharedSecret)&issuer=\(appName)") + else { throw AuthError.validation( "appName or accountName", "Invalid Parameters. Cannot form URL from the supplied appName or accountName", "Please make sure that the supplied parameters don't contain any characters that are illegal in a URL or is an empty String", - nil) + nil + ) } return URL } diff --git a/Amplify/Categories/Auth/Request/AuthAttributeResendConfirmationCodeRequest.swift b/Amplify/Categories/Auth/Request/AuthAttributeResendConfirmationCodeRequest.swift index 4c514c97fb..790c48490c 100644 --- a/Amplify/Categories/Auth/Request/AuthAttributeResendConfirmationCodeRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthAttributeResendConfirmationCodeRequest.swift @@ -18,8 +18,10 @@ public struct AuthAttributeResendConfirmationCodeRequest: AmplifyOperationReques /// Extra request options defined in `AuthAttributeResendConfirmationCodeRequest.Options` public var options: Options - public init(attributeKey: AuthUserAttributeKey, - options: Options) { + public init( + attributeKey: AuthUserAttributeKey, + options: Options + ) { self.attributeKey = attributeKey self.options = options } diff --git a/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift b/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift index ec5f0a4683..4e48b30f7b 100644 --- a/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthAttributeSendVerificationCodeRequest.swift @@ -18,8 +18,10 @@ public struct AuthSendUserAttributeVerificationCodeRequest: AmplifyOperationRequ /// Extra request options defined in `AuthSendUserAttributeVerificationCodeRequest.Options` public var options: Options - public init(attributeKey: AuthUserAttributeKey, - options: Options) { + public init( + attributeKey: AuthUserAttributeKey, + options: Options + ) { self.attributeKey = attributeKey self.options = options } diff --git a/Amplify/Categories/Auth/Request/AuthChangePasswordRequest.swift b/Amplify/Categories/Auth/Request/AuthChangePasswordRequest.swift index d385b95d52..fbd9bb1f93 100644 --- a/Amplify/Categories/Auth/Request/AuthChangePasswordRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthChangePasswordRequest.swift @@ -19,9 +19,11 @@ public struct AuthChangePasswordRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthChangePasswordRequest.Options` public var options: Options - public init(oldPassword: String, - newPassword: String, - options: Options) { + public init( + oldPassword: String, + newPassword: String, + options: Options + ) { self.oldPassword = oldPassword self.newPassword = newPassword self.options = options diff --git a/Amplify/Categories/Auth/Request/AuthConfirmResetPasswordRequest.swift b/Amplify/Categories/Auth/Request/AuthConfirmResetPasswordRequest.swift index c4e0be2e19..d09406b999 100644 --- a/Amplify/Categories/Auth/Request/AuthConfirmResetPasswordRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthConfirmResetPasswordRequest.swift @@ -22,10 +22,12 @@ public struct AuthConfirmResetPasswordRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthConfirmResetPasswordRequest.Options` public var options: Options - public init(username: String, - newPassword: String, - confirmationCode: String, - options: Options) { + public init( + username: String, + newPassword: String, + confirmationCode: String, + options: Options + ) { self.username = username self.newPassword = newPassword self.confirmationCode = confirmationCode diff --git a/Amplify/Categories/Auth/Request/AuthConfirmUserAttributeRequest.swift b/Amplify/Categories/Auth/Request/AuthConfirmUserAttributeRequest.swift index 57650da6cb..6c6e9713cf 100644 --- a/Amplify/Categories/Auth/Request/AuthConfirmUserAttributeRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthConfirmUserAttributeRequest.swift @@ -19,9 +19,11 @@ public struct AuthConfirmUserAttributeRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthConfirmUserAttributeRequest.Options` public var options: Options - public init(attributeKey: AuthUserAttributeKey, - confirmationCode: String, - options: Options) { + public init( + attributeKey: AuthUserAttributeKey, + confirmationCode: String, + options: Options + ) { self.attributeKey = attributeKey self.confirmationCode = confirmationCode self.options = options diff --git a/Amplify/Categories/Auth/Request/AuthFetchSessionRequest.swift b/Amplify/Categories/Auth/Request/AuthFetchSessionRequest.swift index debdb449e4..569575f0d2 100644 --- a/Amplify/Categories/Auth/Request/AuthFetchSessionRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthFetchSessionRequest.swift @@ -35,15 +35,16 @@ public extension AuthFetchSessionRequest { public init( forceRefresh: Bool = false, - pluginOptions: Any? = nil) { + pluginOptions: Any? = nil + ) { self.forceRefresh = forceRefresh self.pluginOptions = pluginOptions } } } -extension AuthFetchSessionRequest.Options { - public static func forceRefresh() -> AuthFetchSessionRequest.Options { +public extension AuthFetchSessionRequest.Options { + static func forceRefresh() -> AuthFetchSessionRequest.Options { return AuthFetchSessionRequest.Options(forceRefresh: true) } } diff --git a/Amplify/Categories/Auth/Request/AuthForgetDeviceRequest.swift b/Amplify/Categories/Auth/Request/AuthForgetDeviceRequest.swift index 530c0e1f4b..1e59e17e56 100644 --- a/Amplify/Categories/Auth/Request/AuthForgetDeviceRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthForgetDeviceRequest.swift @@ -18,8 +18,10 @@ public struct AuthForgetDeviceRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthForgetDeviceRequest.Options` public var options: Options - public init(device: AuthDevice? = nil, - options: Options) { + public init( + device: AuthDevice? = nil, + options: Options + ) { self.device = device self.options = options } diff --git a/Amplify/Categories/Auth/Request/AuthResetPasswordRequest.swift b/Amplify/Categories/Auth/Request/AuthResetPasswordRequest.swift index 79038d6406..85079dbac0 100644 --- a/Amplify/Categories/Auth/Request/AuthResetPasswordRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthResetPasswordRequest.swift @@ -15,8 +15,10 @@ public struct AuthResetPasswordRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthResetPasswordRequest.Options` public var options: Options - public init(username: String, - options: Options) { + public init( + username: String, + options: Options + ) { self.username = username self.options = options } diff --git a/Amplify/Categories/Auth/Request/AuthSignOutRequest.swift b/Amplify/Categories/Auth/Request/AuthSignOutRequest.swift index 4d7e12093f..963795c5f1 100644 --- a/Amplify/Categories/Auth/Request/AuthSignOutRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthSignOutRequest.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import AuthenticationServices +import Foundation /// Request for sign out user public struct AuthSignOutRequest: AmplifyOperationRequest { @@ -37,9 +37,11 @@ public extension AuthSignOutRequest { /// in the presentation anchor provided. public let presentationAnchorForWebUI: AuthUIPresentationAnchor? - public init(globalSignOut: Bool = false, - presentationAnchor: AuthUIPresentationAnchor? = nil, - pluginOptions: Any? = nil) { + public init( + globalSignOut: Bool = false, + presentationAnchor: AuthUIPresentationAnchor? = nil, + pluginOptions: Any? = nil + ) { self.globalSignOut = globalSignOut self.pluginOptions = pluginOptions self.presentationAnchorForWebUI = presentationAnchor @@ -55,8 +57,8 @@ public extension AuthSignOutRequest { } #if os(iOS) || os(macOS) -extension AuthSignOutRequest.Options { - public static func presentationAnchor(_ anchor: AuthUIPresentationAnchor) -> AuthSignOutRequest.Options { +public extension AuthSignOutRequest.Options { + static func presentationAnchor(_ anchor: AuthUIPresentationAnchor) -> AuthSignOutRequest.Options { return AuthSignOutRequest.Options(presentationAnchor: anchor) } } diff --git a/Amplify/Categories/Auth/Request/AuthSignUpRequest.swift b/Amplify/Categories/Auth/Request/AuthSignUpRequest.swift index e8145e454f..ed61d97a62 100644 --- a/Amplify/Categories/Auth/Request/AuthSignUpRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthSignUpRequest.swift @@ -38,8 +38,10 @@ public extension AuthSignUpRequest { /// key/values public let pluginOptions: Any? - public init(userAttributes: [AuthUserAttribute]? = nil, - pluginOptions: Any? = nil) { + public init( + userAttributes: [AuthUserAttribute]? = nil, + pluginOptions: Any? = nil + ) { self.userAttributes = userAttributes self.pluginOptions = pluginOptions } diff --git a/Amplify/Categories/Auth/Request/AuthUpdateUserAttributeRequest.swift b/Amplify/Categories/Auth/Request/AuthUpdateUserAttributeRequest.swift index be3b978526..b1b76f47c2 100644 --- a/Amplify/Categories/Auth/Request/AuthUpdateUserAttributeRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthUpdateUserAttributeRequest.swift @@ -16,8 +16,10 @@ public struct AuthUpdateUserAttributeRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthUpdateUserAttributeRequest.Options` public var options: Options - public init(userAttribute: AuthUserAttribute, - options: Options) { + public init( + userAttribute: AuthUserAttribute, + options: Options + ) { self.userAttribute = userAttribute self.options = options } diff --git a/Amplify/Categories/Auth/Request/AuthUpdateUserAttributesRequest.swift b/Amplify/Categories/Auth/Request/AuthUpdateUserAttributesRequest.swift index 32a87a794d..41310d470e 100644 --- a/Amplify/Categories/Auth/Request/AuthUpdateUserAttributesRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthUpdateUserAttributesRequest.swift @@ -16,8 +16,10 @@ public struct AuthUpdateUserAttributesRequest: AmplifyOperationRequest { /// Extra request options defined in `AuthUpdateUserAttributesRequest.Options` public var options: Options - public init(userAttributes: [AuthUserAttribute], - options: Options) { + public init( + userAttributes: [AuthUserAttribute], + options: Options + ) { self.userAttributes = userAttributes self.options = options } diff --git a/Amplify/Categories/Auth/Request/AuthWebUISignInRequest.swift b/Amplify/Categories/Auth/Request/AuthWebUISignInRequest.swift index f320daff43..d78066aabf 100644 --- a/Amplify/Categories/Auth/Request/AuthWebUISignInRequest.swift +++ b/Amplify/Categories/Auth/Request/AuthWebUISignInRequest.swift @@ -22,9 +22,11 @@ public struct AuthWebUISignInRequest: AmplifyOperationRequest { /// Presentation anchor on which the webUI is displayed public let presentationAnchor: AuthUIPresentationAnchor? - public init(presentationAnchor: AuthUIPresentationAnchor?, - authProvider: AuthProvider? = nil, - options: Options) { + public init( + presentationAnchor: AuthUIPresentationAnchor?, + authProvider: AuthProvider? = nil, + options: Options + ) { self.presentationAnchor = presentationAnchor self.authProvider = authProvider self.options = options @@ -43,8 +45,10 @@ public extension AuthWebUISignInRequest { /// key/values public let pluginOptions: Any? - public init(scopes: [String]? = nil, - pluginOptions: Any? = nil) { + public init( + scopes: [String]? = nil, + pluginOptions: Any? = nil + ) { self.scopes = scopes self.pluginOptions = pluginOptions } diff --git a/Amplify/Categories/Auth/Request/VerifyTOTPSetupRequest.swift b/Amplify/Categories/Auth/Request/VerifyTOTPSetupRequest.swift index 4a03d3ff21..6a3fbfc166 100644 --- a/Amplify/Categories/Auth/Request/VerifyTOTPSetupRequest.swift +++ b/Amplify/Categories/Auth/Request/VerifyTOTPSetupRequest.swift @@ -18,7 +18,8 @@ public struct VerifyTOTPSetupRequest: AmplifyOperationRequest { public init( code: String, - options: Options) { + options: Options + ) { self.code = code self.options = options } diff --git a/Amplify/Categories/DataStore/DataStoreCallback+Combine.swift b/Amplify/Categories/DataStore/DataStoreCallback+Combine.swift index 58bae6f161..c5b9672604 100644 --- a/Amplify/Categories/DataStore/DataStoreCallback+Combine.swift +++ b/Amplify/Categories/DataStore/DataStoreCallback+Combine.swift @@ -7,9 +7,9 @@ import Combine -extension DataStoreResult where Success: Any { +public extension DataStoreResult where Success: Any { - public func resolve(promise: Future.Promise) { + func resolve(promise: Future.Promise) { switch self { case .success(let result): promise(.success(result)) diff --git a/Amplify/Categories/DataStore/DataStoreCallback.swift b/Amplify/Categories/DataStore/DataStoreCallback.swift index be75ee967f..e3afc14dde 100644 --- a/Amplify/Categories/DataStore/DataStoreCallback.swift +++ b/Amplify/Categories/DataStore/DataStoreCallback.swift @@ -11,7 +11,7 @@ import Foundation /// - seealso: [DataStoreCallback](#DataStoreCallback) public typealias DataStoreResult = Result -extension DataStoreResult { +public extension DataStoreResult { /// Creates a `DataStoreResult` based on a error raised during `DataStore` operations. /// In case the error is not already a `DataStoreError`, it gets wrapped @@ -19,12 +19,12 @@ extension DataStoreResult { /// /// - Parameter error: the root cause of the failure /// - Returns: a `DataStoreResult.error` - public static func failure(causedBy error: Error) -> DataStoreResult { + static func failure(causedBy error: Error) -> DataStoreResult { let dataStoreError = error as? DataStoreError ?? .invalidOperation(causedBy: error) return .failure(dataStoreError) } - public static var emptyResult: DataStoreResult { + static var emptyResult: DataStoreResult { .successfulVoid } diff --git a/Amplify/Categories/DataStore/DataStoreCategory+Behavior.swift b/Amplify/Categories/DataStore/DataStoreCategory+Behavior.swift index 4d15a9bff1..489b02e8bf 100644 --- a/Amplify/Categories/DataStore/DataStoreCategory+Behavior.swift +++ b/Amplify/Categories/DataStore/DataStoreCategory+Behavior.swift @@ -8,61 +8,81 @@ extension DataStoreCategory: DataStoreBaseBehavior { @discardableResult - public func save(_ model: M, - where condition: QueryPredicate? = nil) async throws -> M { + public func save( + _ model: M, + where condition: QueryPredicate? = nil + ) async throws -> M { try await plugin.save(model, where: condition) } - public func query(_ modelType: M.Type, - byId id: String) async throws -> M? { + public func query( + _ modelType: M.Type, + byId id: String + ) async throws -> M? { try await plugin.query(modelType, byId: id) } - public func query(_ modelType: M.Type, - byIdentifier id: String) async throws -> M? + public func query( + _ modelType: M.Type, + byIdentifier id: String + ) async throws -> M? where M: ModelIdentifiable, M.IdentifierFormat == ModelIdentifierFormat.Default { try await plugin.query(modelType, byIdentifier: id) } - public func query(_ modelType: M.Type, - byIdentifier identifier: ModelIdentifier) + public func query( + _ modelType: M.Type, + byIdentifier identifier: ModelIdentifier + ) async throws -> M? where M: ModelIdentifiable { try await plugin.query(modelType, byIdentifier: identifier) } - public func query(_ modelType: M.Type, - where predicate: QueryPredicate? = nil, - sort sortInput: QuerySortInput? = nil, - paginate paginationInput: QueryPaginationInput? = nil) async throws -> [M] { + public func query( + _ modelType: M.Type, + where predicate: QueryPredicate? = nil, + sort sortInput: QuerySortInput? = nil, + paginate paginationInput: QueryPaginationInput? = nil + ) async throws -> [M] { try await plugin.query(modelType, where: predicate, sort: sortInput, paginate: paginationInput) } - public func delete(_ model: M, - where predicate: QueryPredicate? = nil) async throws { + public func delete( + _ model: some Model, + where predicate: QueryPredicate? = nil + ) async throws { try await plugin.delete(model, where: predicate) } - public func delete(_ modelType: M.Type, - withId id: String, - where predicate: QueryPredicate? = nil) async throws { + public func delete( + _ modelType: (some Model).Type, + withId id: String, + where predicate: QueryPredicate? = nil + ) async throws { try await plugin.delete(modelType, withId: id, where: predicate) } - public func delete(_ modelType: M.Type, - withIdentifier id: String, - where predicate: QueryPredicate? = nil) async throws + public func delete( + _ modelType: M.Type, + withIdentifier id: String, + where predicate: QueryPredicate? = nil + ) async throws where M: ModelIdentifiable, M.IdentifierFormat == ModelIdentifierFormat.Default { try await plugin.delete(modelType, withIdentifier: id, where: predicate) } - public func delete(_ modelType: M.Type, - withIdentifier id: ModelIdentifier, - where predicate: QueryPredicate? = nil) async throws where M: ModelIdentifiable { + public func delete( + _ modelType: M.Type, + withIdentifier id: ModelIdentifier, + where predicate: QueryPredicate? = nil + ) async throws where M: ModelIdentifiable { try await plugin.delete(modelType, withIdentifier: id, where: predicate) } - public func delete(_ modelType: M.Type, - where predicate: QueryPredicate) async throws { + public func delete( + _ modelType: (some Model).Type, + where predicate: QueryPredicate + ) async throws { try await plugin.delete(modelType, where: predicate) } diff --git a/Amplify/Categories/DataStore/DataStoreCategory.swift b/Amplify/Categories/DataStore/DataStoreCategory.swift index ec2e8a29ab..7e2fc4f85e 100644 --- a/Amplify/Categories/DataStore/DataStoreCategory.swift +++ b/Amplify/Categories/DataStore/DataStoreCategory.swift @@ -7,7 +7,7 @@ import Foundation -final public class DataStoreCategory: Category { +public final class DataStoreCategory: Category { /// Always .dataStore public let categoryType: CategoryType = .dataStore @@ -54,8 +54,10 @@ final public class DataStoreCategory: Category { let key = plugin.key guard !key.isEmpty else { let pluginDescription = String(describing: plugin) - let error = DataStoreError.configuration("Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + let error = DataStoreError.configuration( + "Plugin \(pluginDescription) has an empty `key`.", + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -78,8 +80,10 @@ final public class DataStoreCategory: Category { public func getPlugin(for key: PluginKey) throws -> DataStoreCategoryPlugin { guard let plugin = plugins[key] else { let keys = plugins.keys.joined(separator: ", ") - let error = DataStoreError.configuration("No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + let error = DataStoreError.configuration( + "No plugin has been added for '\(key)'.", + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/DataStore/DataStoreCategoryBehavior.swift b/Amplify/Categories/DataStore/DataStoreCategoryBehavior.swift index 43aa4d3892..88ef599cb2 100644 --- a/Amplify/Categories/DataStore/DataStoreCategoryBehavior.swift +++ b/Amplify/Categories/DataStore/DataStoreCategoryBehavior.swift @@ -13,44 +13,64 @@ public protocol DataStoreBaseBehavior { /// Saves the model to storage. If sync is enabled, also initiates a sync of the mutation to the remote API @discardableResult - func save(_ model: M, - where condition: QueryPredicate?) async throws -> M + func save( + _ model: M, + where condition: QueryPredicate? + ) async throws -> M @available(*, deprecated, renamed: "query(byIdentifier:)") - func query(_ modelType: M.Type, - byId id: String) async throws -> M? - - func query(_ modelType: M.Type, - byIdentifier id: String) async throws -> M? + func query( + _ modelType: M.Type, + byId id: String + ) async throws -> M? + + func query( + _ modelType: M.Type, + byIdentifier id: String + ) async throws -> M? where M: ModelIdentifiable, M.IdentifierFormat == ModelIdentifierFormat.Default - func query(_ modelType: M.Type, - byIdentifier id: ModelIdentifier) async throws -> M? + func query( + _ modelType: M.Type, + byIdentifier id: ModelIdentifier + ) async throws -> M? where M: ModelIdentifiable - func query(_ modelType: M.Type, - where predicate: QueryPredicate?, - sort sortInput: QuerySortInput?, - paginate paginationInput: QueryPaginationInput?) async throws -> [M] - - func delete(_ model: M, - where predicate: QueryPredicate?) async throws - - func delete(_ modelType: M.Type, - withId id: String, - where predicate: QueryPredicate?) async throws - - func delete(_ modelType: M.Type, - withIdentifier id: String, - where predicate: QueryPredicate?) async throws where M: ModelIdentifiable, + func query( + _ modelType: M.Type, + where predicate: QueryPredicate?, + sort sortInput: QuerySortInput?, + paginate paginationInput: QueryPaginationInput? + ) async throws -> [M] + + func delete( + _ model: M, + where predicate: QueryPredicate? + ) async throws + + func delete( + _ modelType: M.Type, + withId id: String, + where predicate: QueryPredicate? + ) async throws + + func delete( + _ modelType: M.Type, + withIdentifier id: String, + where predicate: QueryPredicate? + ) async throws where M: ModelIdentifiable, M.IdentifierFormat == ModelIdentifierFormat.Default - func delete(_ modelType: M.Type, - withIdentifier id: ModelIdentifier, - where predicate: QueryPredicate?) async throws where M: ModelIdentifiable + func delete( + _ modelType: M.Type, + withIdentifier id: ModelIdentifier, + where predicate: QueryPredicate? + ) async throws where M: ModelIdentifiable - func delete(_ modelType: M.Type, - where predicate: QueryPredicate) async throws + func delete( + _ modelType: M.Type, + where predicate: QueryPredicate + ) async throws /** Synchronization starts automatically whenever you run any DataStore operation (query(), save(), delete()) @@ -89,8 +109,10 @@ public protocol DataStoreSubscribeBehavior { /// - modelType: The model type to observe /// - predicate: The predicate to match for filtered results /// - sortInput: The field and order of data to be returned - func observeQuery(for modelType: M.Type, - where predicate: QueryPredicate?, - sort sortInput: QuerySortInput?) + func observeQuery( + for modelType: M.Type, + where predicate: QueryPredicate?, + sort sortInput: QuerySortInput? + ) -> AmplifyAsyncThrowingSequence> } diff --git a/Amplify/Categories/DataStore/Model/Internal/Embedded.swift b/Amplify/Categories/DataStore/Model/Internal/Embedded.swift index 0a588d1d43..3e5adada7d 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Embedded.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Embedded.swift @@ -23,12 +23,16 @@ public protocol Embeddable: Codable { static var schema: ModelSchema { get } } -extension Embeddable { - public static func defineSchema(name: String? = nil, - attributes: ModelAttribute..., - define: (inout ModelSchemaDefinition) -> Void) -> ModelSchema { - var definition = ModelSchemaDefinition(name: name ?? "", - attributes: attributes) +public extension Embeddable { + static func defineSchema( + name: String? = nil, + attributes: ModelAttribute..., + define: (inout ModelSchemaDefinition) -> Void + ) -> ModelSchema { + var definition = ModelSchemaDefinition( + name: name ?? "", + attributes: attributes + ) define(&definition) return definition.build() } diff --git a/Amplify/Categories/DataStore/Model/Internal/Model+Array.swift b/Amplify/Categories/DataStore/Model/Internal/Model+Array.swift index 4054f30af8..8a0b17b405 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Model+Array.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Model+Array.swift @@ -7,13 +7,13 @@ import Foundation -extension Array where Element: Model { +public extension Array where Element: Model { /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public func unique() throws -> Element? { + func unique() throws -> Element? { guard (0 ... 1).contains(count) else { throw DataStoreError.nonUniqueResult(model: Element.modelName, count: count) } @@ -21,13 +21,13 @@ extension Array where Element: Model { } } -extension Array where Element == Model { +public extension [Model] { /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public func unique() throws -> Element? { + func unique() throws -> Element? { guard (0 ... 1).contains(count) else { let firstModelName = self[0].modelName throw DataStoreError.nonUniqueResult(model: firstModelName, count: count) diff --git a/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift b/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift index 2eff95f1e7..58fb41b0e2 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift @@ -8,7 +8,7 @@ import Foundation /// Adds JSON serialization behavior to all types that conform to the `Model` protocol. -extension Model where Self: Codable { +public extension Model where Self: Codable { /// De-serialize a JSON string into an instance of the concrete type that conforms /// to the `Model` protocol. @@ -24,13 +24,14 @@ extension Model where Self: Codable { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public static func from(json: String, - decoder: JSONDecoder? = nil) throws -> Self { - let resolvedDecoder: JSONDecoder - if let decoder = decoder { - resolvedDecoder = decoder + static func from( + json: String, + decoder: JSONDecoder? = nil + ) throws -> Self { + let resolvedDecoder: JSONDecoder = if let decoder { + decoder } else { - resolvedDecoder = JSONDecoder(dateDecodingStrategy: ModelDateFormatting.decodingStrategy) + JSONDecoder(dateDecodingStrategy: ModelDateFormatting.decodingStrategy) } return try resolvedDecoder.decode(Self.self, from: Data(json.utf8)) @@ -47,7 +48,7 @@ extension Model where Self: Codable { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public static func from(dictionary: [String: Any]) throws -> Self { + static func from(dictionary: [String: Any]) throws -> Self { let data = try JSONSerialization.data(withJSONObject: dictionary) let decoder = JSONDecoder(dateDecodingStrategy: ModelDateFormatting.decodingStrategy) return try decoder.decode(Self.self, from: data) @@ -63,7 +64,7 @@ extension Model where Self: Codable { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public func toJSON(encoder: JSONEncoder? = nil) throws -> String { + func toJSON(encoder: JSONEncoder? = nil) throws -> String { var resolvedEncoder = encoder ?? JSONEncoder( dateEncodingStrategy: ModelDateFormatting.encodingStrategy ) diff --git a/Amplify/Categories/DataStore/Model/Internal/Model+DateFormatting.swift b/Amplify/Categories/DataStore/Model/Internal/Model+DateFormatting.swift index 8540f066a9..489f9d108e 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Model+DateFormatting.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Model+DateFormatting.swift @@ -11,7 +11,7 @@ import Foundation /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. -public struct ModelDateFormatting { +public enum ModelDateFormatting { public static let decodingStrategy: JSONDecoder.DateDecodingStrategy = { let strategy = JSONDecoder.DateDecodingStrategy.custom { decoder -> Date in diff --git a/Amplify/Categories/DataStore/Model/Internal/Model+Subscript.swift b/Amplify/Categories/DataStore/Model/Internal/Model+Subscript.swift index 97aed1b40c..4b5eff6930 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Model+Subscript.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Model+Subscript.swift @@ -10,13 +10,13 @@ /// ```swift /// let id = model["id"] /// ``` -extension Model { +public extension Model { /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public subscript(_ key: String) -> Any?? { + subscript(_ key: String) -> Any?? { if let jsonModel = self as? JSONValueHolder { let value = jsonModel.jsonValue(for: key) diff --git a/Amplify/Categories/DataStore/Model/Internal/ModelListDecoder.swift b/Amplify/Categories/DataStore/Model/Internal/ModelListDecoder.swift index f3d30371f4..1cf2a88816 100644 --- a/Amplify/Categories/DataStore/Model/Internal/ModelListDecoder.swift +++ b/Amplify/Categories/DataStore/Model/Internal/ModelListDecoder.swift @@ -14,7 +14,7 @@ import Foundation /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a breaking /// change. -public struct ModelListDecoderRegistry { +public enum ModelListDecoderRegistry { public static var listDecoders = AtomicValue(initialValue: [ModelListDecoder.Type]()) /// Register a decoder during plugin configuration time, to allow runtime retrievals of list providers. diff --git a/Amplify/Categories/DataStore/Model/Internal/ModelProvider.swift b/Amplify/Categories/DataStore/Model/Internal/ModelProvider.swift index 98c93dfa00..384dffda7f 100644 --- a/Amplify/Categories/DataStore/Model/Internal/ModelProvider.swift +++ b/Amplify/Categories/DataStore/Model/Internal/ModelProvider.swift @@ -6,6 +6,7 @@ // import Foundation + // swiftlint:disable type_name /// Protocol used as a marker to detect when the type is a `LazyReference`. /// Used to retrieve either the `reference` or the `identifiers` of the Model directly, without having load a not diff --git a/Amplify/Categories/DataStore/Model/Internal/ModelProviderDecoder.swift b/Amplify/Categories/DataStore/Model/Internal/ModelProviderDecoder.swift index 8470cba587..0b14cefbad 100644 --- a/Amplify/Categories/DataStore/Model/Internal/ModelProviderDecoder.swift +++ b/Amplify/Categories/DataStore/Model/Internal/ModelProviderDecoder.swift @@ -14,7 +14,7 @@ import Foundation /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a breaking /// change. -public struct ModelProviderRegistry { +public enum ModelProviderRegistry { static var decoders = AtomicValue(initialValue: [ModelProviderDecoder.Type]()) /// Register a decoder during plugin configuration time, to allow runtime retrievals of model providers. @@ -33,8 +33,8 @@ extension ModelProviderRegistry { public extension ModelProviderRegistry { /// Static decoder sources that will be referenced to initialize different type of decoders having source as - /// a metadata. - struct DecoderSource { + /// a metadata. + enum DecoderSource { public static let dataStore = "DataStore" public static let appSync = "AppSync" } diff --git a/Amplify/Categories/DataStore/Model/Internal/ModelRegistry.swift b/Amplify/Categories/DataStore/Model/Internal/ModelRegistry.swift index ff3fd6ef1c..6d6b5a4979 100644 --- a/Amplify/Categories/DataStore/Model/Internal/ModelRegistry.swift +++ b/Amplify/Categories/DataStore/Model/Internal/ModelRegistry.swift @@ -9,9 +9,11 @@ import Foundation /// - Warning: Although this has `public` access, it is intended for internal use and should not be used directly /// by host applications. The behavior of this may change without warning. -public struct ModelRegistry { - private static let concurrencyQueue = DispatchQueue(label: "com.amazonaws.ModelRegistry.concurrency", - target: DispatchQueue.global()) +public enum ModelRegistry { + private static let concurrencyQueue = DispatchQueue( + label: "com.amazonaws.ModelRegistry.concurrency", + target: DispatchQueue.global() + ) /// ModelDecoders are used to decode untyped model data, looking up by model name private typealias ModelDecoder = (String, JSONDecoder?) throws -> Model @@ -35,16 +37,20 @@ public struct ModelRegistry { } public static func register(modelType: Model.Type) { - register(modelType: modelType, - modelSchema: modelType.schema) { (jsonString, jsonDecoder) -> Model in + register( + modelType: modelType, + modelSchema: modelType.schema + ) { jsonString, jsonDecoder -> Model in let model = try modelType.from(json: jsonString, decoder: jsonDecoder) return model } } - public static func register(modelType: Model.Type, - modelSchema: ModelSchema, - jsonDecoder: @escaping (String, JSONDecoder?) throws -> Model) { + public static func register( + modelType: Model.Type, + modelSchema: ModelSchema, + jsonDecoder: @escaping (String, JSONDecoder?) throws -> Model + ) { concurrencyQueue.sync { let modelDecoder: ModelDecoder = { jsonString, decoder in return try jsonDecoder(jsonString, decoder) @@ -75,9 +81,11 @@ public struct ModelRegistry { } } - public static func decode(modelName: ModelName, - from jsonString: String, - jsonDecoder: JSONDecoder? = nil) throws -> Model { + public static func decode( + modelName: ModelName, + from jsonString: String, + jsonDecoder: JSONDecoder? = nil + ) throws -> Model { try concurrencyQueue.sync { guard let decoder = modelDecoders[modelName] else { throw DataStoreError.decodingError( @@ -85,7 +93,8 @@ public struct ModelRegistry { """ There is no decoder registered for the model named \(modelName). \ Register models with `ModelRegistry.register(modelName:)` at startup. - """) + """ + ) } return try decoder(jsonString, jsonDecoder) diff --git a/Amplify/Categories/DataStore/Model/Internal/Persistable.swift b/Amplify/Categories/DataStore/Model/Internal/Persistable.swift index b7a53acf5a..abd424443a 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Persistable.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Persistable.swift @@ -30,7 +30,7 @@ extension Temporal.Date: Persistable {} extension Temporal.DateTime: Persistable {} extension Temporal.Time: Persistable {} -struct PersistableHelper { +enum PersistableHelper { /// Polymorphic utility that allows two persistable references to be checked /// for equality regardless of their concrete type. diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/AuthRule.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/AuthRule.swift index 8a5c6b4aeb..f50034b4d0 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/AuthRule.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/AuthRule.swift @@ -50,14 +50,16 @@ public struct AuthRule { public let operations: [ModelOperation] public let provider: AuthRuleProvider? - public init(allow: AuthStrategy, - ownerField: String? = nil, - identityClaim: String? = nil, - groupClaim: String? = nil, - groups: [String] = [], - groupsField: String? = nil, - provider: AuthRuleProvider? = nil, - operations: [ModelOperation] = []) { + public init( + allow: AuthStrategy, + ownerField: String? = nil, + identityClaim: String? = nil, + groupClaim: String? = nil, + groups: [String] = [], + groupsField: String? = nil, + provider: AuthRuleProvider? = nil, + operations: [ModelOperation] = [] + ) { self.allow = allow self.ownerField = ownerField self.identityClaim = identityClaim diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/Model+Schema.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/Model+Schema.swift index 7a09d82580..4139e01560 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/Model+Schema.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/Model+Schema.swift @@ -7,13 +7,13 @@ import Foundation -extension Model { +public extension Model { /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public static var schema: ModelSchema { + static var schema: ModelSchema { // TODO load schema from JSON when this it not overridden by specific models ModelSchema(name: modelName, fields: [:]) } @@ -22,7 +22,7 @@ extension Model { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var schema: ModelSchema { + var schema: ModelSchema { type(of: self).schema } @@ -46,32 +46,40 @@ extension Model { /// - Returns: a valid `ModelSchema` instance /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. - public static func defineSchema(name: String? = nil, - attributes: ModelAttribute..., - define: (inout ModelSchemaDefinition) -> Void) -> ModelSchema { - var definition = ModelSchemaDefinition(name: name ?? modelName, - attributes: attributes) + static func defineSchema( + name: String? = nil, + attributes: ModelAttribute..., + define: (inout ModelSchemaDefinition) -> Void + ) -> ModelSchema { + var definition = ModelSchemaDefinition( + name: name ?? modelName, + attributes: attributes + ) define(&definition) return definition.build() } /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. - public static func rule(allow: AuthStrategy, - ownerField: String? = nil, - identityClaim: String? = nil, - groupClaim: String? = nil, - groups: [String] = [], - groupsField: String? = nil, - provider: AuthRuleProvider? = nil, - operations: [ModelOperation] = []) -> AuthRule { - return AuthRule(allow: allow, - ownerField: ownerField, - identityClaim: identityClaim, - groupClaim: groupClaim, - groups: groups, - groupsField: groupsField, - provider: provider, - operations: operations) + static func rule( + allow: AuthStrategy, + ownerField: String? = nil, + identityClaim: String? = nil, + groupClaim: String? = nil, + groups: [String] = [], + groupsField: String? = nil, + provider: AuthRuleProvider? = nil, + operations: [ModelOperation] = [] + ) -> AuthRule { + return AuthRule( + allow: allow, + ownerField: ownerField, + identityClaim: identityClaim, + groupClaim: groupClaim, + groups: groups, + groupsField: groupsField, + provider: provider, + operations: operations + ) } } diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelField+Association.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelField+Association.swift index 4ebe4bcb5a..c8031a8933 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelField+Association.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelField+Association.swift @@ -104,7 +104,7 @@ public enum ModelAssociation { ) -> ModelAssociation { return .hasMany( associatedFieldName: associatedWith?.stringValue, - associatedFieldNames: associatedFields.map { $0.stringValue } + associatedFieldNames: associatedFields.map(\.stringValue) ) } @@ -117,11 +117,13 @@ public enum ModelAssociation { public static func hasOne( associatedWith: CodingKey? = nil, associatedFields: [CodingKey] = [], - targetNames: [String] = []) -> ModelAssociation { + targetNames: [String] = [] + ) -> ModelAssociation { return .hasOne( associatedFieldName: associatedWith?.stringValue, - associatedFieldNames: associatedFields.map { $0.stringValue }, - targetNames: targetNames) + associatedFieldNames: associatedFields.map(\.stringValue), + targetNames: targetNames + ) } @available(*, deprecated, message: "Use belongsTo(associatedWith:targetNames:)") @@ -136,13 +138,13 @@ public enum ModelAssociation { } -extension ModelField { +public extension ModelField { /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var hasAssociation: Bool { + var hasAssociation: Bool { return association != nil } @@ -156,7 +158,7 @@ extension ModelField { @available(*, deprecated, message: """ Use of associated model type is deprecated, use `associatedModelName` instead. """) - public var associatedModel: Model.Type? { + var associatedModel: Model.Type? { switch type { case .model(let modelName), .collection(let modelName): return ModelRegistry.modelType(from: modelName) @@ -172,7 +174,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var associatedModelName: ModelName? { + var associatedModelName: ModelName? { switch type { case .model(let modelName), .collection(let modelName): return modelName @@ -196,7 +198,7 @@ extension ModelField { Use of requiredAssociatedModel with Model.Type is deprecated, use `requiredAssociatedModelName` that return ModelName instead. """) - public var requiredAssociatedModel: Model.Type { + var requiredAssociatedModel: Model.Type { guard let modelType = associatedModel else { return Fatal.preconditionFailure(""" Model fields that are foreign keys must be connected to another Model. @@ -217,7 +219,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var requiredAssociatedModelName: ModelName { + var requiredAssociatedModelName: ModelName { guard let modelName = associatedModelName else { return Fatal.preconditionFailure(""" Model fields that are foreign keys must be connected to another Model. @@ -231,7 +233,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var isAssociationOwner: Bool { + var isAssociationOwner: Bool { guard case .belongsTo = association else { return false } @@ -242,7 +244,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var _isBelongsToOrHasOne: Bool { // swiftlint:disable:this identifier_name + var _isBelongsToOrHasOne: Bool { // swiftlint:disable:this identifier_name switch association { case .belongsTo, .hasOne: return true @@ -255,7 +257,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var associatedField: ModelField? { + var associatedField: ModelField? { if hasAssociation { let associatedModel = requiredAssociatedModelName switch association { @@ -277,10 +279,10 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var associatedFieldNames: [String] { + var associatedFieldNames: [String] { switch association { case .hasMany(let associatedKey, let associatedKeys): - if associatedKeys.isEmpty, let associatedKey = associatedKey { + if associatedKeys.isEmpty, let associatedKey { return [associatedKey] } return associatedKeys @@ -300,7 +302,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var isOneToOne: Bool { + var isOneToOne: Bool { if case .hasOne = association { return true } @@ -314,7 +316,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var isOneToMany: Bool { + var isOneToMany: Bool { if case .hasMany = association, case .belongsTo = associatedField?.association { return true } @@ -325,7 +327,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var isManyToOne: Bool { + var isManyToOne: Bool { if case .belongsTo = association, case .hasMany = associatedField?.association { return true } @@ -339,7 +341,7 @@ extension ModelField { @available(*, deprecated, message: """ Use `embeddedType` is deprecated, use `embeddedTypeSchema` instead. """) - public var embeddedType: Embeddable.Type? { + var embeddedType: Embeddable.Type? { switch type { case .embedded(let type, _), .embeddedCollection(let type, _): if let embeddedType = type as? Embeddable.Type { @@ -355,7 +357,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var embeddedTypeSchema: ModelSchema? { + var embeddedTypeSchema: ModelSchema? { switch type { case .embedded(_, let modelSchema), .embeddedCollection(_, let modelSchema): return modelSchema @@ -368,7 +370,7 @@ extension ModelField { /// directly by host applications. The behavior of this may change without warning. Though it is not used by host /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. - public var isEmbeddedType: Bool { + var isEmbeddedType: Bool { switch type { case .embedded, .embeddedCollection: return true diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelPrimaryKey.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelPrimaryKey.swift index 38d8ccec63..cb38c40fa6 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelPrimaryKey.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelPrimaryKey.swift @@ -13,18 +13,22 @@ public struct ModelPrimaryKey { fields.count > 1 } - init?(allFields: ModelFields, - attributes: [ModelAttribute], - primaryKeyFieldKeys: [String] = []) { - self.fields = resolvePrimaryKeyFields(allFields: allFields, - attributes: attributes, - primaryKeyFieldKeys: primaryKeyFieldKeys) + init?( + allFields: ModelFields, + attributes: [ModelAttribute], + primaryKeyFieldKeys: [String] = [] + ) { + self.fields = resolvePrimaryKeyFields( + allFields: allFields, + attributes: attributes, + primaryKeyFieldKeys: primaryKeyFieldKeys + ) if fields.isEmpty { return nil } - self.fieldsLookup = Set(fields.map { $0.name }) + self.fieldsLookup = Set(fields.map(\.name)) } /// Returns the list of fields that make up the primary key for the model. @@ -49,9 +53,11 @@ public struct ModelPrimaryKey { /// It returns an array of fields as custom and composite primary keys are supported. /// - Parameter fields: schema model fields /// - Returns: an array of model fields - func resolvePrimaryKeyFields(allFields: ModelFields, - attributes: [ModelAttribute], - primaryKeyFieldKeys: [String]) -> [ModelField] { + func resolvePrimaryKeyFields( + allFields: ModelFields, + attributes: [ModelAttribute], + primaryKeyFieldKeys: [String] + ) -> [ModelField] { var primaryKeyFields: [ModelField] = [] if !primaryKeyFieldKeys.isEmpty { @@ -64,8 +70,8 @@ public struct ModelPrimaryKey { /// if indexes aren't defined most likely the model has a default `id` as PK /// so we have to rely on the `.primaryKey` attribute of each individual field - } else if attributes.indexes.filter({ $0.isPrimaryKeyIndex }).isEmpty { - primaryKeyFields = allFields.values.filter { $0.isPrimaryKey } + } else if attributes.indexes.filter(\.isPrimaryKeyIndex).isEmpty { + primaryKeyFields = allFields.values.filter(\.isPrimaryKey) /// Use the array of fields with a primary key index } else if let fieldNames = primaryFieldsFromIndexes(attributes: attributes) { diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+AuthRulesByOperation.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+AuthRulesByOperation.swift index d7d02d2b6a..f65b31c77f 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+AuthRulesByOperation.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+AuthRulesByOperation.swift @@ -7,7 +7,7 @@ import Foundation -public extension Array where Element == AuthRule { +public extension [AuthRule] { /// Returns all the `AuthRule` that apply to a given a `ModelOperation` /// - Parameter operation: `ModelOperation` operation diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+Definition.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+Definition.swift index 35e6f1210d..febe4cfc87 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+Definition.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema+Definition.swift @@ -123,7 +123,7 @@ public enum ModelFieldNullability { /// directly by host applications. The behavior of this may change without warning. public struct ModelSchemaDefinition { - internal let name: String + let name: String @available(*, deprecated, message: "Use of pluralName is deprecated, use syncPluralName instead.") public var pluralName: String? @@ -132,16 +132,18 @@ public struct ModelSchemaDefinition { public var syncPluralName: String? public var authRules: AuthRules - internal var fields: ModelFields - internal var primarykeyFields: [ModelFieldName] - internal var attributes: [ModelAttribute] - - init(name: String, - pluralName: String? = nil, - listPluralName: String? = nil, - syncPluralName: String? = nil, - authRules: AuthRules = [], - attributes: [ModelAttribute] = []) { + var fields: ModelFields + var primarykeyFields: [ModelFieldName] + var attributes: [ModelAttribute] + + init( + name: String, + pluralName: String? = nil, + listPluralName: String? = nil, + syncPluralName: String? = nil, + authRules: AuthRules = [], + attributes: [ModelAttribute] = [] + ) { self.name = name self.pluralName = pluralName self.listPluralName = listPluralName @@ -153,7 +155,7 @@ public struct ModelSchemaDefinition { } public mutating func fields(_ fields: ModelFieldDefinition...) { - fields.forEach { definition in + for definition in fields { let field = definition.modelField self.fields[field.name] = field } @@ -174,43 +176,51 @@ public struct ModelSchemaDefinition { primarykeyFields = primaryKeyDefinition.first ?? [] } - internal func build() -> ModelSchema { - return ModelSchema(name: name, - pluralName: pluralName, - listPluralName: listPluralName, - syncPluralName: syncPluralName, - authRules: authRules, - attributes: attributes, - fields: fields, - primaryKeyFieldKeys: primarykeyFields) + func build() -> ModelSchema { + return ModelSchema( + name: name, + pluralName: pluralName, + listPluralName: listPluralName, + syncPluralName: syncPluralName, + authRules: authRules, + attributes: attributes, + fields: fields, + primaryKeyFieldKeys: primarykeyFields + ) } } /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. public enum ModelFieldDefinition { - case field(name: String, - type: ModelFieldType, - nullability: ModelFieldNullability, - isReadOnly: Bool, - association: ModelAssociation?, - attributes: [ModelFieldAttribute], - authRules: AuthRules) - - public static func field(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: ModelFieldType = .string, - attributes: [ModelFieldAttribute] = [], - association: ModelAssociation? = nil, - authRules: AuthRules = []) -> ModelFieldDefinition { - return .field(name: key.stringValue, - type: type, - nullability: nullability, - isReadOnly: isReadOnly, - association: association, - attributes: attributes, - authRules: authRules) + case field( + name: String, + type: ModelFieldType, + nullability: ModelFieldNullability, + isReadOnly: Bool, + association: ModelAssociation?, + attributes: [ModelFieldAttribute], + authRules: AuthRules + ) + + public static func field( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: ModelFieldType = .string, + attributes: [ModelFieldAttribute] = [], + association: ModelAssociation? = nil, + authRules: AuthRules = [] + ) -> ModelFieldDefinition { + return .field( + name: key.stringValue, + type: type, + nullability: nullability, + isReadOnly: isReadOnly, + association: association, + attributes: attributes, + authRules: authRules + ) } @available(*, deprecated, message: "Use .primaryKey(fields:)") @@ -220,123 +230,160 @@ public enum ModelFieldDefinition { @available(*, deprecated, message: "Use .primaryKey(fields:)") public static func id(_ name: String = "id") -> ModelFieldDefinition { - return .field(name: name, - type: .string, - nullability: .required, - isReadOnly: false, - association: nil, - attributes: [.primaryKey], - authRules: []) + return .field( + name: name, + type: .string, + nullability: .required, + isReadOnly: false, + association: nil, + attributes: [.primaryKey], + authRules: [] + ) } - public static func hasMany(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedWith associatedKey: CodingKey) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .collection(of: type), - association: .hasMany(associatedWith: associatedKey)) + public static func hasMany( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedWith associatedKey: CodingKey + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .collection(of: type), + association: .hasMany(associatedWith: associatedKey) + ) } - public static func hasMany(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedFields associatedKeys: [CodingKey]) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .collection(of: type), - association: .hasMany(associatedWith: associatedKeys.first, associatedFields: associatedKeys)) + public static func hasMany( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedFields associatedKeys: [CodingKey] + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .collection(of: type), + association: .hasMany(associatedWith: associatedKeys.first, associatedFields: associatedKeys) + ) } - public static func hasOne(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedWith associatedKey: CodingKey, - targetName: String? = nil) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .model(type: type), - association: .hasOne(associatedWith: associatedKey, targetNames: targetName.map { [$0] } ?? [])) + public static func hasOne( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedWith associatedKey: CodingKey, + targetName: String? = nil + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .model(type: type), + association: .hasOne(associatedWith: associatedKey, targetNames: targetName.map { [$0] } ?? []) + ) } - public static func hasOne(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedWith associatedKey: CodingKey, - targetNames: [String]) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .model(type: type), - association: .hasOne(associatedWith: associatedKey, targetNames: targetNames)) + public static func hasOne( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedWith associatedKey: CodingKey, + targetNames: [String] + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .model(type: type), + association: .hasOne(associatedWith: associatedKey, targetNames: targetNames) + ) } - public static func hasOne(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedFields associatedKeys: [CodingKey], - targetNames: [String] = []) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .model(type: type), - association: .hasOne(associatedWith: associatedKeys.first, - associatedFields: associatedKeys, - targetNames: targetNames)) + public static func hasOne( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedFields associatedKeys: [CodingKey], + targetNames: [String] = [] + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .model(type: type), + association: .hasOne( + associatedWith: associatedKeys.first, + associatedFields: associatedKeys, + targetNames: targetNames + ) + ) } - public static func belongsTo(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedWith associatedKey: CodingKey? = nil, - targetName: String? = nil) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .model(type: type), - association: .belongsTo(associatedWith: associatedKey, targetNames: targetName.map { [$0] } ?? [])) + public static func belongsTo( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedWith associatedKey: CodingKey? = nil, + targetName: String? = nil + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .model(type: type), + association: .belongsTo(associatedWith: associatedKey, targetNames: targetName.map { [$0] } ?? []) + ) } - public static func belongsTo(_ key: CodingKey, - is nullability: ModelFieldNullability = .required, - isReadOnly: Bool = false, - ofType type: Model.Type, - associatedWith associatedKey: CodingKey? = nil, - targetNames: [String]) -> ModelFieldDefinition { - return .field(key, - is: nullability, - isReadOnly: isReadOnly, - ofType: .model(type: type), - association: .belongsTo(associatedWith: associatedKey, targetNames: targetNames)) + public static func belongsTo( + _ key: CodingKey, + is nullability: ModelFieldNullability = .required, + isReadOnly: Bool = false, + ofType type: Model.Type, + associatedWith associatedKey: CodingKey? = nil, + targetNames: [String] + ) -> ModelFieldDefinition { + return .field( + key, + is: nullability, + isReadOnly: isReadOnly, + ofType: .model(type: type), + association: .belongsTo(associatedWith: associatedKey, targetNames: targetNames) + ) } public var modelField: ModelField { - guard case let .field(name, - type, - nullability, - isReadOnly, - association, - attributes, - authRules) = self else { + guard case let .field( + name, + type, + nullability, + isReadOnly, + association, + attributes, + authRules + ) = self + else { return Fatal.preconditionFailure("Unexpected enum value found: \(String(describing: self))") } - return ModelField(name: name, - type: type, - isRequired: nullability.isRequired, - isReadOnly: isReadOnly, - isArray: type.isArray, - attributes: attributes, - association: association, - authRules: authRules) + return ModelField( + name: name, + type: type, + isRequired: nullability.isRequired, + isReadOnly: isReadOnly, + isArray: type.isArray, + attributes: attributes, + association: association, + authRules: authRules + ) } } diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema.swift index ac1045e523..f2ae1142fb 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelSchema.swift @@ -24,7 +24,7 @@ public enum ModelAttribute: Equatable { /// Convenience factory method to initialize a `.primaryKey` attribute by /// using the model coding keys public static func primaryKey(fields: [CodingKey]) -> ModelAttribute { - return .primaryKey(fields: fields.map { $0.stringValue }) + return .primaryKey(fields: fields.map(\.stringValue)) } } @@ -53,14 +53,16 @@ public struct ModelField { return attributes.contains { $0 == .primaryKey } } - public init(name: String, - type: ModelFieldType, - isRequired: Bool = false, - isReadOnly: Bool = false, - isArray: Bool = false, - attributes: [ModelFieldAttribute] = [], - association: ModelAssociation? = nil, - authRules: AuthRules = []) { + public init( + name: String, + type: ModelFieldType, + isRequired: Bool = false, + isReadOnly: Bool = false, + isArray: Bool = false, + attributes: [ModelFieldAttribute] = [], + association: ModelAssociation? = nil, + authRules: AuthRules = [] + ) { self.name = name self.type = type self.isRequired = isRequired @@ -106,14 +108,16 @@ public struct ModelSchema { return primaryKey } - public init(name: String, - pluralName: String? = nil, - listPluralName: String? = nil, - syncPluralName: String? = nil, - authRules: AuthRules = [], - attributes: [ModelAttribute] = [], - fields: ModelFields = [:], - primaryKeyFieldKeys: [ModelFieldName] = []) { + public init( + name: String, + pluralName: String? = nil, + listPluralName: String? = nil, + syncPluralName: String? = nil, + authRules: AuthRules = [], + attributes: [ModelAttribute] = [], + fields: ModelFields = [:], + primaryKeyFieldKeys: [ModelFieldName] = [] + ) { self.name = name self.pluralName = pluralName self.listPluralName = listPluralName @@ -122,9 +126,11 @@ public struct ModelSchema { self.attributes = attributes self.fields = fields self.indexes = attributes.indexes - self._primaryKey = ModelPrimaryKey(allFields: fields, - attributes: attributes, - primaryKeyFieldKeys: primaryKeyFieldKeys) + self._primaryKey = ModelPrimaryKey( + allFields: fields, + attributes: attributes, + primaryKeyFieldKeys: primaryKeyFieldKeys + ) let indexOfPrimaryKeyField = _primaryKey?.indexOfField ?? { (_: String) in nil } self.sortedFields = fields.sortedFields(indexOfPrimaryKeyField: indexOfPrimaryKeyField) @@ -150,7 +156,7 @@ extension ModelAttribute { /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used /// directly by host applications. The behavior of this may change without warning. -extension Array where Element == ModelAttribute { +extension [ModelAttribute] { var indexes: [ModelAttribute] { filter { switch $0 { @@ -179,7 +185,7 @@ public extension ModelSchema { // MARK: - Dictionary + ModelField -extension Dictionary where Key == String, Value == ModelField { +extension [String: ModelField] { /// Returns an array of the values sorted by some pre-defined rules: /// diff --git a/Amplify/Categories/DataStore/Model/Lazy/ArrayLiteralListProvider.swift b/Amplify/Categories/DataStore/Model/Lazy/ArrayLiteralListProvider.swift index 7c8e128853..8fc5fbf235 100644 --- a/Amplify/Categories/DataStore/Model/Lazy/ArrayLiteralListProvider.swift +++ b/Amplify/Categories/DataStore/Model/Lazy/ArrayLiteralListProvider.swift @@ -35,15 +35,19 @@ public struct ArrayLiteralListProvider: ModelListProvider { } public func getNextPage(completion: @escaping (Result, CoreError>) -> Void) { - completion(.failure(CoreError.clientValidation("No pagination on an array literal", - "Don't call this method", - nil))) + completion(.failure(CoreError.clientValidation( + "No pagination on an array literal", + "Don't call this method", + nil + ))) } public func getNextPage() async throws -> List { - throw CoreError.clientValidation("No pagination on an array literal", - "Don't call this method", - nil) + throw CoreError.clientValidation( + "No pagination on an array literal", + "Don't call this method", + nil + ) } public func encode(to encoder: Encoder) throws { diff --git a/Amplify/Categories/DataStore/Model/Lazy/LazyReference.swift b/Amplify/Categories/DataStore/Model/Lazy/LazyReference.swift index 343b059225..33e51c990a 100644 --- a/Amplify/Categories/DataStore/Model/Lazy/LazyReference.swift +++ b/Amplify/Categories/DataStore/Model/Lazy/LazyReference.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Combine +import Foundation /// A Codable struct to hold key value pairs representing the identifier's field name and value. /// Useful for maintaining order for key-value pairs when used as an Array type. @@ -20,8 +20,8 @@ public struct LazyReferenceIdentifier: Codable { } } -extension Array where Element == LazyReferenceIdentifier { - public var stringValue: String { +public extension [LazyReferenceIdentifier] { + var stringValue: String { var fields = [(String, Persistable)]() for id in self { fields.append((id.name, id.value)) @@ -88,7 +88,7 @@ public class LazyReference: Codable, _LazyReferenceValue { // MARK: - Codable implementation /// Decodable implementation is delegated to the ModelProviders. - required convenience public init(from decoder: Decoder) throws { + public required convenience init(from decoder: Decoder) throws { for modelDecoder in ModelProviderRegistry.decoders.get() { if let modelProvider = modelDecoder.decode(modelType: ModelType.self, decoder: decoder) { self.init(modelProvider: modelProvider) @@ -129,7 +129,7 @@ public class LazyReference: Codable, _LazyReferenceValue { switch loadedState { case .notLoaded: let element = try await modelProvider.load() - self.loadedState = .loaded(element) + loadedState = .loaded(element) return element case .loaded(let element): return element @@ -148,10 +148,10 @@ public class LazyReference: Codable, _LazyReferenceValue { guard let element = try await modelProvider.load() else { throw CoreError.clientValidation("Data is required but underlying data source successfully loaded no data. ", "") } - self.loadedState = .loaded(element) + loadedState = .loaded(element) return element case .loaded(let element): - guard let element = element else { + guard let element else { throw CoreError.clientValidation("Data is required but containing LazyReference is loaded with no data.", "") } return element diff --git a/Amplify/Categories/DataStore/Model/Lazy/List+Combine.swift b/Amplify/Categories/DataStore/Model/Lazy/List+Combine.swift index 271608fa2f..df6701cdff 100644 --- a/Amplify/Categories/DataStore/Model/Lazy/List+Combine.swift +++ b/Amplify/Categories/DataStore/Model/Lazy/List+Combine.swift @@ -8,9 +8,9 @@ #if canImport(Combine) import Combine -extension List { +public extension List { - public typealias LazyListPublisher = AnyPublisher<[Element], DataStoreError> + typealias LazyListPublisher = AnyPublisher<[Element], DataStoreError> } #endif diff --git a/Amplify/Categories/DataStore/Model/Lazy/List+LazyLoad.swift b/Amplify/Categories/DataStore/Model/Lazy/List+LazyLoad.swift index 71b833c976..8e40946bc4 100644 --- a/Amplify/Categories/DataStore/Model/Lazy/List+LazyLoad.swift +++ b/Amplify/Categories/DataStore/Model/Lazy/List+LazyLoad.swift @@ -10,7 +10,7 @@ import Foundation /// This extension adds lazy load logic to the `List`. Lazy loading means /// the contents of a list that represents an association between two models will only be /// loaded when it's needed. -extension List { +public extension List { // MARK: - Asynchronous API @@ -26,12 +26,12 @@ extension List { /// /// If you have directly created this list object (for example, by calling `List(elements:)`) then the collection /// has already been initialized and calling this method will have no effect. - public func fetch() async throws { + func fetch() async throws { guard case .notLoaded = loadedState else { return } do { - self.elements = try await listProvider.load() + elements = try await listProvider.load() } catch { throw error } diff --git a/Amplify/Categories/DataStore/Model/Lazy/List+Model.swift b/Amplify/Categories/DataStore/Model/Lazy/List+Model.swift index 283cc53ff7..af9965888f 100644 --- a/Amplify/Categories/DataStore/Model/Lazy/List+Model.swift +++ b/Amplify/Categories/DataStore/Model/Lazy/List+Model.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Combine +import Foundation /// `List` is a custom `Collection` that is capable of loading records from a data source. This is especially /// useful when dealing with Model associations that need to be lazy loaded. Lazy loading is performed when you access @@ -89,7 +89,7 @@ public class List: Collection, Codable, ExpressibleByArrayLite // MARK: - ExpressibleByArrayLiteral - required convenience public init(arrayLiteral elements: Element...) { + public required convenience init(arrayLiteral elements: Element...) { self.init(elements: elements) } @@ -150,7 +150,7 @@ public class List: Collection, Codable, ExpressibleByArrayLite /// implementations of a `ModelListProvider` for `List`. The decoders should be added to the registry by the /// plugin as part of its configuration steps. By delegating responsibility to the `ModelListDecoder`, it is up to /// the plugin to successfully return an instance of `ModelListProvider`. - required convenience public init(from decoder: Decoder) throws { + public required convenience init(from decoder: Decoder) throws { for listDecoder in ModelListDecoderRegistry.listDecoders.get() { if let listProvider = listDecoder.decode(modelType: ModelType.self, decoder: decoder) { self.init(listProvider: listProvider) diff --git a/Amplify/Categories/DataStore/Model/Lazy/List+Pagination.swift b/Amplify/Categories/DataStore/Model/Lazy/List+Pagination.swift index 28d6fb2d02..da7c312bf1 100644 --- a/Amplify/Categories/DataStore/Model/Lazy/List+Pagination.swift +++ b/Amplify/Categories/DataStore/Model/Lazy/List+Pagination.swift @@ -7,12 +7,12 @@ import Foundation -extension List { +public extension List { /// Check if there is subsequent data to retrieve. If true, the next page can be retrieved using /// `getNextPage(completion:)`. Calling `hasNextPage()` will load the underlying elements from the data source if not yet /// loaded before. - public func hasNextPage() -> Bool { + func hasNextPage() -> Bool { switch loadedState { case .loaded: return listProvider.hasNextPage() @@ -26,7 +26,7 @@ extension List { /// Retrieve the next page as a new in-memory List object. Calling `getNextPage(completion:)` will load the /// underlying elements of the receiver from the data source if not yet loaded before - public func getNextPage() async throws -> List { + func getNextPage() async throws -> List { switch loadedState { case .loaded: return try await listProvider.getNextPage() diff --git a/Amplify/Categories/DataStore/Model/Model+ModelName.swift b/Amplify/Categories/DataStore/Model/Model+ModelName.swift index ac6b893d12..df69c900f1 100644 --- a/Amplify/Categories/DataStore/Model/Model+ModelName.swift +++ b/Amplify/Categories/DataStore/Model/Model+ModelName.swift @@ -5,13 +5,13 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Model { +public extension Model { - public static var modelName: String { + static var modelName: String { return String(describing: self) } - public var modelName: String { + var modelName: String { return type(of: self).modelName } } diff --git a/Amplify/Categories/DataStore/Model/Model.swift b/Amplify/Categories/DataStore/Model/Model.swift index 85b6c1a822..102997c672 100644 --- a/Amplify/Categories/DataStore/Model/Model.swift +++ b/Amplify/Categories/DataStore/Model/Model.swift @@ -38,15 +38,15 @@ public protocol Model: Codable { var identifier: String { get } } -extension Model { - public var identifier: String { +public extension Model { + var identifier: String { guard let schema = ModelRegistry.modelSchema(from: modelName) else { preconditionFailure("Schema not found for \(modelName).") } return identifier(schema: schema).stringValue } - public func identifier(schema modelSchema: ModelSchema) -> ModelIdentifierProtocol { + func identifier(schema modelSchema: ModelSchema) -> ModelIdentifierProtocol { // resolve current instance identifier fields let fields: ModelIdentifierProtocol.Fields = modelSchema.primaryKey.fields.map { guard let fieldValue = self[$0.name] else { @@ -77,5 +77,5 @@ extension Model { /// The `rootPath` is set to `nil` by default. Specific models should override this /// behavior and provide the proper path reference when available. - public static var rootPath: PropertyContainerPath? { nil } + static var rootPath: PropertyContainerPath? { nil } } diff --git a/Amplify/Categories/DataStore/Model/ModelIdentifiable.swift b/Amplify/Categories/DataStore/Model/ModelIdentifiable.swift index 141a7ff03d..9946e0878a 100644 --- a/Amplify/Categories/DataStore/Model/ModelIdentifiable.swift +++ b/Amplify/Categories/DataStore/Model/ModelIdentifiable.swift @@ -62,11 +62,11 @@ public extension ModelIdentifierProtocol { } var keys: [String] { - fields.map { $0.name } + fields.map(\.name) } var values: [Persistable] { - fields.map { $0.value } + fields.map(\.value) } var predicate: QueryPredicate { @@ -97,11 +97,11 @@ public extension ModelIdentifier where F == ModelIdentifierFormat.Custom { /// Convenience type for a ModelIdentifier with a `ModelIdentifierFormat.Default` format public typealias DefaultModelIdentifier = ModelIdentifier -extension DefaultModelIdentifier { +public extension DefaultModelIdentifier { /// Factory to instantiate a `DefaultModelIdentifier`. /// - Parameter id: model id value /// - Returns: an instance of `ModelIdentifier` for the given model type - public static func makeDefault(id: String) -> ModelIdentifier { + static func makeDefault(id: String) -> ModelIdentifier { ModelIdentifier(fields: [ (name: ModelIdentifierFormat.Default.name, value: id) ]) @@ -110,7 +110,7 @@ extension DefaultModelIdentifier { /// Convenience factory to instantiate a `DefaultModelIdentifier` from a given model /// - Parameter model: model /// - Returns: an instance of `ModelIdentifier` for the given model type - public static func makeDefault(fromModel model: M) -> ModelIdentifier { + static func makeDefault(fromModel model: M) -> ModelIdentifier { guard let idValue = model[ModelIdentifierFormat.Default.name] as? String else { fatalError("Couldn't find default identifier for model \(model)") } @@ -121,19 +121,18 @@ extension DefaultModelIdentifier { // MARK: - Persistable + stringValue private extension Persistable { var stringValue: String { - var value: String - switch self { + var value: String = switch self { case let self as Temporal.Date: - value = self.iso8601String + self.iso8601String case let self as Temporal.DateTime: - value = self.iso8601String + self.iso8601String case let self as Temporal.Time: - value = self.iso8601String + self.iso8601String default: - value = "\(self)" + "\(self)" } return value } diff --git a/Amplify/Categories/DataStore/Model/PropertyPath.swift b/Amplify/Categories/DataStore/Model/PropertyPath.swift index 212430f56d..ad67734a66 100644 --- a/Amplify/Categories/DataStore/Model/PropertyPath.swift +++ b/Amplify/Categories/DataStore/Model/PropertyPath.swift @@ -34,7 +34,7 @@ public protocol PropertyPath { /// - SeeAlso: `ModelPath` public protocol PropertyContainerPath: PropertyPath { - /// + /// func getKeyPath() -> String /// Must return a reference to the type containing the properties @@ -42,9 +42,9 @@ public protocol PropertyContainerPath: PropertyPath { } -extension PropertyContainerPath { +public extension PropertyContainerPath { - public func getKeyPath() -> String { + func getKeyPath() -> String { var metadata = getMetadata() var path = [String]() while let parent = metadata.parent { diff --git a/Amplify/Categories/DataStore/Model/Temporal/DataStoreError+Temporal.swift b/Amplify/Categories/DataStore/Model/Temporal/DataStoreError+Temporal.swift index 4cbec5437c..ef2ba29487 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/DataStoreError+Temporal.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/DataStoreError+Temporal.swift @@ -7,9 +7,9 @@ import Foundation -extension DataStoreError { +public extension DataStoreError { - public static func invalidDateFormat(_ value: String) -> DataStoreError { + static func invalidDateFormat(_ value: String) -> DataStoreError { return DataStoreError.decodingError( """ Could not parse \(value) as a Date using the ISO8601 format. @@ -17,7 +17,8 @@ extension DataStoreError { """ Check if the format used to parse the date is the correct one. Check `TemporalFormat` for all the options. - """) + """ + ) } } diff --git a/Amplify/Categories/DataStore/Model/Temporal/Date+Operation.swift b/Amplify/Categories/DataStore/Model/Temporal/Date+Operation.swift index 5bf0f19b4f..637b5b5e96 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Date+Operation.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Date+Operation.swift @@ -92,7 +92,7 @@ public protocol DateUnitOperable { static func - (left: Self, right: DateUnit) -> Self } -extension TemporalSpec where Self: DateUnitOperable { +public extension TemporalSpec where Self: DateUnitOperable { /// Add a `DateUnit` to a `Temporal.Date` or `Temporal.DateTime` /// @@ -102,7 +102,7 @@ extension TemporalSpec where Self: DateUnitOperable { /// - left: `Temporal.Date` or `Temporal.DateTime` /// - right: `DateUnit` to add to `left` /// - Returns: A new `Temporal.Date` or `Temporal.DateTime` the `DateUnit` was added to. - public static func + (left: Self, right: DateUnit) -> Self { + static func + (left: Self, right: DateUnit) -> Self { return left.add(value: right.value, to: right.calendarComponent) } @@ -114,7 +114,7 @@ extension TemporalSpec where Self: DateUnitOperable { /// - left: `Temporal.Date` or `Temporal.DateTime` /// - right: `DateUnit` to subtract from `left` /// - Returns: A new `Temporal.Date` or `Temporal.DateTime` the `DateUnit` was subtracted from. - public static func - (left: Self, right: DateUnit) -> Self { + static func - (left: Self, right: DateUnit) -> Self { return left.add(value: -right.value, to: right.calendarComponent) } } diff --git a/Amplify/Categories/DataStore/Model/Temporal/Date.swift b/Amplify/Categories/DataStore/Model/Temporal/Date.swift index 9b27c313e0..0c955fee9e 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Date.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Date.swift @@ -7,7 +7,7 @@ import Foundation -extension Temporal { +public extension Temporal { /// `Temporal.Date` represents a `Date` with specific allowable formats. /// @@ -17,7 +17,7 @@ extension Temporal { /// * `.full` => `yyyy-MM-ddZZZZZ` /// /// - Note: `.medium`, `.long`, and `.full` are the same date format. - public struct Date: TemporalSpec { + struct Date: TemporalSpec { // Inherits documentation from `TemporalSpec` public let foundationDate: Foundation.Date diff --git a/Amplify/Categories/DataStore/Model/Temporal/DateTime.swift b/Amplify/Categories/DataStore/Model/Temporal/DateTime.swift index 95c65e5f6e..b694f094b3 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/DateTime.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/DateTime.swift @@ -7,14 +7,14 @@ import Foundation -extension Temporal { +public extension Temporal { /// `Temporal.DateTime` represents a `DateTime` with specific allowable formats. /// /// * `.short` => `yyyy-MM-dd'T'HH:mm` /// * `.medium` => `yyyy-MM-dd'T'HH:mm:ss` /// * `.long` => `yyyy-MM-dd'T'HH:mm:ssZZZZZ` /// * `.full` => `yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ` - public struct DateTime: TemporalSpec { + struct DateTime: TemporalSpec { // Inherits documentation from `TemporalSpec` public let foundationDate: Foundation.Date @@ -42,7 +42,7 @@ extension Temporal { self.timeZone = timeZone - foundationDate = calendar + self.foundationDate = calendar .date(from: components) ?? date } diff --git a/Amplify/Categories/DataStore/Model/Temporal/SpecBasedDateConverting.swift b/Amplify/Categories/DataStore/Model/Temporal/SpecBasedDateConverting.swift index 5aaa135d8d..26612ab195 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/SpecBasedDateConverting.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/SpecBasedDateConverting.swift @@ -10,12 +10,12 @@ import Foundation /// Internal generic method to reduce code reuse in the `init`s of `TemporalSpec` /// conforming types @usableFromInline -internal struct SpecBasedDateConverting { +struct SpecBasedDateConverting { @usableFromInline - internal typealias DateConverter = (_ string: String, _ format: TemporalFormat?) throws -> (Date, TimeZone) + typealias DateConverter = (_ string: String, _ format: TemporalFormat?) throws -> (Date, TimeZone) @usableFromInline - internal let convert: DateConverter + let convert: DateConverter @inlinable @inline(never) @@ -25,13 +25,13 @@ internal struct SpecBasedDateConverting { @inlinable @inline(never) - internal static func `default`( + static func `default`( iso8601String: String, format: TemporalFormat? = nil ) throws -> (Date, TimeZone) { let date: Foundation.Date - let tz: TimeZone = TimeZone(iso8601DateString: iso8601String) ?? .utc - if let format = format { + let tz = TimeZone(iso8601DateString: iso8601String) ?? .utc + if let format { date = try Temporal.date( from: iso8601String, with: [format(for: Spec.self)] diff --git a/Amplify/Categories/DataStore/Model/Temporal/Temporal+Cache.swift b/Amplify/Categories/DataStore/Model/Temporal/Temporal+Cache.swift index cb3b7b051f..05ba4b6b28 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Temporal+Cache.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Temporal+Cache.swift @@ -19,7 +19,7 @@ extension Temporal { /// /// `identifier` is `.iso8601` /// `timeZome` is `.utc` a.k.a. `TimeZone(abbreviation: "UTC")` - internal static let iso8601Calendar: Calendar = { + static let iso8601Calendar: Calendar = { var calendar = Calendar(identifier: .iso8601) calendar.timeZone = .utc return calendar @@ -37,7 +37,7 @@ extension Temporal { /// - format: The `DateFormatter().dateFormat` /// - timeZone: The `DateFormatter().timeZone` /// - Returns: A `DateFormatter` - internal static func formatter( + static func formatter( for format: String, in timeZone: TimeZone ) -> DateFormatter { @@ -111,7 +111,7 @@ extension Temporal { /// Default is `.utc` a.k.a. `TimeZone(abbreviation: "UTC")` /// - Returns: A `Foundation.Date` if conversion was successful. /// - Throws: `DataStoreError.invalidDateFormat(_:)` if conversion was unsuccessful. - internal static func date( + static func date( from string: String, with formats: [String], in timeZone: TimeZone = .utc @@ -134,7 +134,7 @@ extension Temporal { /// - timeZone: The `TimeZone` used by the `DateFormatter` when converted. /// Default is `.utc` a.k.a. `TimeZone(abbreviation: "UTC")` /// - Returns: The `String` representation of the `date` formatted according to the `format` argument.. - internal static func string( + static func string( from date: Foundation.Date, with format: String, in timeZone: TimeZone = .utc diff --git a/Amplify/Categories/DataStore/Model/Temporal/Temporal+Codable.swift b/Amplify/Categories/DataStore/Model/Temporal/Temporal+Codable.swift index 024b534d2d..15db66b141 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Temporal+Codable.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Temporal+Codable.swift @@ -7,14 +7,14 @@ import Foundation -extension TemporalSpec where Self: Codable { - public init(from decoder: Decoder) throws { +public extension TemporalSpec where Self: Codable { + init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() let value = try container.decode(String.self) try self.init(iso8601String: value) } - public func encode(to encoder: Encoder) throws { + func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encode(iso8601String) } diff --git a/Amplify/Categories/DataStore/Model/Temporal/Temporal+Comparable.swift b/Amplify/Categories/DataStore/Model/Temporal/Temporal+Comparable.swift index bc9e9e47e0..a577817edf 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Temporal+Comparable.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Temporal+Comparable.swift @@ -12,14 +12,14 @@ import Foundation /// takes care of deriving the other operations from those two. /// /// - Note: the implementation simply delegates to the `iso8601String` formatted date. -extension TemporalSpec where Self: Comparable { +public extension TemporalSpec where Self: Comparable { - public static func == (lhs: Self, rhs: Self) -> Bool { + static func == (lhs: Self, rhs: Self) -> Bool { return lhs.iso8601FormattedString(format: .full, timeZone: .utc) == rhs.iso8601FormattedString(format: .full, timeZone: .utc) } - public static func < (lhs: Self, rhs: Self) -> Bool { + static func < (lhs: Self, rhs: Self) -> Bool { return lhs.iso8601FormattedString(format: .full, timeZone: .utc) < rhs.iso8601FormattedString(format: .full, timeZone: .utc) } diff --git a/Amplify/Categories/DataStore/Model/Temporal/Temporal.swift b/Amplify/Categories/DataStore/Model/Temporal/Temporal.swift index e92f4f9435..ad6256d21c 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Temporal.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Temporal.swift @@ -72,7 +72,7 @@ public protocol TemporalSpec { func iso8601FormattedString(format: TemporalFormat, timeZone: TimeZone) -> String } -extension TemporalSpec { +public extension TemporalSpec { /// Create an iso8601 `String` with the desired format option for this spec. /// - Parameters: @@ -80,7 +80,7 @@ extension TemporalSpec { /// - timeZone: `TimeZone` that the `DateFormatter` will use in conversion. /// Default is `.utc` a.k.a. `TimeZone(abbreviation: "UTC")` /// - Returns: A `String` formatted according to the `format` and `timeZone` arguments. - public func iso8601FormattedString( + func iso8601FormattedString( format: TemporalFormat, timeZone: TimeZone = .utc ) -> String { @@ -93,12 +93,12 @@ extension TemporalSpec { /// The ISO8601 representation of the scalar using `.full` as the format and `.utc` as `TimeZone`. /// - SeeAlso: `iso8601FormattedString(format:timeZone:)` - public var iso8601String: String { + var iso8601String: String { iso8601FormattedString(format: .full, timeZone: timeZone ?? .utc) } @inlinable - public init(iso8601String: String, format: TemporalFormat) throws { + init(iso8601String: String, format: TemporalFormat) throws { let (date, tz) = try SpecBasedDateConverting() .convert(iso8601String, format) @@ -106,7 +106,7 @@ extension TemporalSpec { } @inlinable - public init( + init( iso8601String: String ) throws { let (date, tz) = try SpecBasedDateConverting() @@ -116,9 +116,9 @@ extension TemporalSpec { } } -extension TimeZone { +public extension TimeZone { /// Utility UTC ("Coordinated Universal Time") TimeZone instance. - public static var utc: TimeZone { + static var utc: TimeZone { TimeZone(abbreviation: "UTC")! } } diff --git a/Amplify/Categories/DataStore/Model/Temporal/TemporalFormat.swift b/Amplify/Categories/DataStore/Model/Temporal/TemporalFormat.swift index d9cc9ca6f7..d593ea216b 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/TemporalFormat.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/TemporalFormat.swift @@ -64,35 +64,34 @@ public struct TemporalFormat { ] private func keyPath(for type: TemporalSpec.Type) -> KeyPath { - let keyPath: KeyPath - if type == Temporal.Time.self { - keyPath = \TemporalFormat.timeFormat + let keyPath: KeyPath = if type == Temporal.Time.self { + \TemporalFormat.timeFormat } else if type == Temporal.Date.self { - keyPath = \TemporalFormat.dateFormat + \TemporalFormat.dateFormat } else { - keyPath = \TemporalFormat.dateTimeFormat + \TemporalFormat.dateTimeFormat } return keyPath } @usableFromInline - internal static func sortedFormats(for type: TemporalSpec.Type) -> [String] { + static func sortedFormats(for type: TemporalSpec.Type) -> [String] { let formats: [String] // If the TemporalSpec is `Date`, let's only return `.full` and `.short` // because `.medium`, `.long`, and `.full` are all the same format. // If the formats ever differ, this needs to be updated. - if type == Temporal.Date.self { - formats = [TemporalFormat.full, .short] + = if type == Temporal.Date.self { + [TemporalFormat.full, .short] .map { $0(for: type) } } else { - formats = Self.allCases + Self.allCases .map { $0(for: type) } } return formats } @usableFromInline - internal func callAsFunction(for type: TemporalSpec.Type) -> String { + func callAsFunction(for type: TemporalSpec.Type) -> String { self[keyPath: keyPath(for: type)] } } diff --git a/Amplify/Categories/DataStore/Model/Temporal/Time+Operation.swift b/Amplify/Categories/DataStore/Model/Temporal/Time+Operation.swift index 83166eb39a..803345bf15 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Time+Operation.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Time+Operation.swift @@ -109,14 +109,14 @@ public protocol TimeUnitOperable { static func - (left: Self, right: TimeUnit) -> Self } -extension TemporalSpec where Self: TimeUnitOperable { +public extension TemporalSpec where Self: TimeUnitOperable { /// Add a `TimeUnit` to a `Temporal.Time` or `Temporal.DateTime` /// - Parameters: /// - left: `Temporal.Time` or `Temporal.DateTime` /// - right: `TimeUnit` to add to `left` /// - Returns: A new `Temporal.Time` or `Temporal.DateTime` the `TimeUnit` was added to. - public static func + (left: Self, right: TimeUnit) -> Self { + static func + (left: Self, right: TimeUnit) -> Self { return left.add(value: right.value, to: right.calendarComponent) } @@ -125,7 +125,7 @@ extension TemporalSpec where Self: TimeUnitOperable { /// - left: `Temporal.Time` or `Temporal.DateTime` /// - right: `TimeUnit` to subtract from `left` /// - Returns: A new `Temporal.Time` or `Temporal.DateTime` the `TimeUnit` was subtracted from. - public static func - (left: Self, right: TimeUnit) -> Self { + static func - (left: Self, right: TimeUnit) -> Self { return left.add(value: -right.value, to: right.calendarComponent) } } diff --git a/Amplify/Categories/DataStore/Model/Temporal/Time.swift b/Amplify/Categories/DataStore/Model/Temporal/Time.swift index d4185e874d..b263b715a2 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/Time.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/Time.swift @@ -7,14 +7,14 @@ import Foundation -extension Temporal { +public extension Temporal { /// `Temporal.Time` represents a `Time` with specific allowable formats. /// /// * `.short` => `HH:mm` /// * `.medium` => `HH:mm:ss` /// * `.long` => `HH:mm:ss.SSS` /// * `.full` => `HH:mm:ss.SSSZZZZZ` - public struct Time: TemporalSpec { + struct Time: TemporalSpec { // Inherits documentation from `TemporalSpec` public let foundationDate: Foundation.Date diff --git a/Amplify/Categories/DataStore/Model/Temporal/TimeZone+Extension.swift b/Amplify/Categories/DataStore/Model/Temporal/TimeZone+Extension.swift index efbbbfb673..530cd27063 100644 --- a/Amplify/Categories/DataStore/Model/Temporal/TimeZone+Extension.swift +++ b/Amplify/Categories/DataStore/Model/Temporal/TimeZone+Extension.swift @@ -10,7 +10,7 @@ import Foundation extension TimeZone { @usableFromInline - internal init?(iso8601DateString: String) { + init?(iso8601DateString: String) { switch ISO8601TimeZonePart.from(iso8601DateString: iso8601DateString) { case .some(.utc): self.init(abbreviation: "UTC") diff --git a/Amplify/Categories/DataStore/Query/ModelKey.swift b/Amplify/Categories/DataStore/Query/ModelKey.swift index 8096bfc9c7..aa143e45cf 100644 --- a/Amplify/Categories/DataStore/Query/ModelKey.swift +++ b/Amplify/Categories/DataStore/Query/ModelKey.swift @@ -34,106 +34,106 @@ import Foundation /// ``` public protocol ModelKey: CodingKey, CaseIterable, QueryFieldOperation {} -extension CodingKey where Self: ModelKey { +public extension CodingKey where Self: ModelKey { // MARK: - beginsWith - public func beginsWith(_ value: String) -> QueryPredicateOperation { + func beginsWith(_ value: String) -> QueryPredicateOperation { return field(stringValue).beginsWith(value) } // MARK: - between - public func between(start: Persistable, end: Persistable) -> QueryPredicateOperation { + func between(start: Persistable, end: Persistable) -> QueryPredicateOperation { return field(stringValue).between(start: start, end: end) } // MARK: - contains - public func contains(_ value: String) -> QueryPredicateOperation { + func contains(_ value: String) -> QueryPredicateOperation { return field(stringValue).contains(value) } - public static func ~= (key: Self, value: String) -> QueryPredicateOperation { + static func ~= (key: Self, value: String) -> QueryPredicateOperation { return key.contains(value) } // MARK: - not contains - public func notContains(_ value: String) -> QueryPredicateOperation { + func notContains(_ value: String) -> QueryPredicateOperation { return field(stringValue).notContains(value) } // MARK: - eq - public func eq(_ value: Persistable?) -> QueryPredicateOperation { + func eq(_ value: Persistable?) -> QueryPredicateOperation { return field(stringValue).eq(value) } - public func eq(_ value: EnumPersistable) -> QueryPredicateOperation { + func eq(_ value: EnumPersistable) -> QueryPredicateOperation { return field(stringValue).eq(value) } - public static func == (key: Self, value: Persistable?) -> QueryPredicateOperation { + static func == (key: Self, value: Persistable?) -> QueryPredicateOperation { return key.eq(value) } - public static func == (key: Self, value: EnumPersistable) -> QueryPredicateOperation { + static func == (key: Self, value: EnumPersistable) -> QueryPredicateOperation { return key.eq(value) } // MARK: - ge - public func ge(_ value: Persistable) -> QueryPredicateOperation { + func ge(_ value: Persistable) -> QueryPredicateOperation { return field(stringValue).ge(value) } - public static func >= (key: Self, value: Persistable) -> QueryPredicateOperation { + static func >= (key: Self, value: Persistable) -> QueryPredicateOperation { return key.ge(value) } // MARK: - gt - public func gt(_ value: Persistable) -> QueryPredicateOperation { + func gt(_ value: Persistable) -> QueryPredicateOperation { return field(stringValue).gt(value) } - public static func > (key: Self, value: Persistable) -> QueryPredicateOperation { + static func > (key: Self, value: Persistable) -> QueryPredicateOperation { return key.gt(value) } // MARK: - le - public func le(_ value: Persistable) -> QueryPredicateOperation { + func le(_ value: Persistable) -> QueryPredicateOperation { return field(stringValue).le(value) } - public static func <= (key: Self, value: Persistable) -> QueryPredicateOperation { + static func <= (key: Self, value: Persistable) -> QueryPredicateOperation { return key.le(value) } // MARK: - lt - public func lt(_ value: Persistable) -> QueryPredicateOperation { + func lt(_ value: Persistable) -> QueryPredicateOperation { return field(stringValue).lt(value) } - public static func < (key: Self, value: Persistable) -> QueryPredicateOperation { + static func < (key: Self, value: Persistable) -> QueryPredicateOperation { return key.lt(value) } // MARK: - ne - public func ne(_ value: Persistable?) -> QueryPredicateOperation { + func ne(_ value: Persistable?) -> QueryPredicateOperation { return field(stringValue).ne(value) } - public func ne(_ value: EnumPersistable) -> QueryPredicateOperation { + func ne(_ value: EnumPersistable) -> QueryPredicateOperation { return field(stringValue).ne(value) } - public static func != (key: Self, value: Persistable?) -> QueryPredicateOperation { + static func != (key: Self, value: Persistable?) -> QueryPredicateOperation { return key.ne(value) } - public static func != (key: Self, value: EnumPersistable) -> QueryPredicateOperation { + static func != (key: Self, value: EnumPersistable) -> QueryPredicateOperation { return key.ne(value) } diff --git a/Amplify/Categories/DataStore/Query/QueryOperator.swift b/Amplify/Categories/DataStore/Query/QueryOperator.swift index 2fcb50ccd2..5328fd9417 100644 --- a/Amplify/Categories/DataStore/Query/QueryOperator.swift +++ b/Amplify/Categories/DataStore/Query/QueryOperator.swift @@ -65,12 +65,12 @@ public enum QueryOperator: Encodable { switch self { case .notEqual(let value): try container.encode("notEqual", forKey: .type) - if let value = value { + if let value { try container.encode(value, forKey: .value) } case .equals(let value): try container.encode("equals", forKey: .type) - if let value = value { + if let value { try container.encode(value, forKey: .value) } case .lessOrEqual(let value): diff --git a/Amplify/Categories/DataStore/Query/QueryPaginationInput.swift b/Amplify/Categories/DataStore/Query/QueryPaginationInput.swift index 75b46ffbac..dd665aa475 100644 --- a/Amplify/Categories/DataStore/Query/QueryPaginationInput.swift +++ b/Amplify/Categories/DataStore/Query/QueryPaginationInput.swift @@ -21,7 +21,7 @@ public struct QueryPaginationInput { } -extension QueryPaginationInput { +public extension QueryPaginationInput { /// Creates a `QueryPaginationInput` in an expressive way, enabling a short /// and developer friendly access to an instance of `QueryPaginationInput`. @@ -30,18 +30,20 @@ extension QueryPaginationInput { /// - page: the page number (starting at 0) /// - limit: the page size (defaults to `QueryPaginationInput.defaultLimit`) /// - Returns: a new instance of `QueryPaginationInput` - public static func page(_ page: UInt, - limit: UInt = QueryPaginationInput.defaultLimit) -> QueryPaginationInput { + static func page( + _ page: UInt, + limit: UInt = QueryPaginationInput.defaultLimit + ) -> QueryPaginationInput { return QueryPaginationInput(page: page, limit: limit) } /// Utility that created a `QueryPaginationInput` with `page` 0 and `limit` 1 - public static var firstResult: QueryPaginationInput { + static var firstResult: QueryPaginationInput { .page(0, limit: 1) } /// Utility that created a `QueryPaginationInput` with `page` 0 and the default `limit` - public static var firstPage: QueryPaginationInput { + static var firstPage: QueryPaginationInput { .page(0) } diff --git a/Amplify/Categories/DataStore/Query/QueryPredicate.swift b/Amplify/Categories/DataStore/Query/QueryPredicate.swift index 78bdf9f051..76946f17ad 100644 --- a/Amplify/Categories/DataStore/Query/QueryPredicate.swift +++ b/Amplify/Categories/DataStore/Query/QueryPredicate.swift @@ -19,7 +19,7 @@ public enum QueryPredicateGroupType: String, Encodable { /// The `not` function is used to wrap a `QueryPredicate` in a `QueryPredicateGroup` of type `.not`. /// - Parameter predicate: the `QueryPredicate` (either operation or group) /// - Returns: `QueryPredicateGroup` of type `.not` -public func not(_ predicate: Predicate) -> QueryPredicateGroup { +public func not(_ predicate: some QueryPredicate) -> QueryPredicateGroup { return QueryPredicateGroup(type: .not, predicates: [predicate]) } @@ -37,8 +37,10 @@ public class QueryPredicateGroup: QueryPredicate, Encodable { public internal(set) var type: QueryPredicateGroupType public internal(set) var predicates: [QueryPredicate] - public init(type: QueryPredicateGroupType = .and, - predicates: [QueryPredicate] = []) { + public init( + type: QueryPredicateGroupType = .and, + predicates: [QueryPredicate] = [] + ) { self.type = type self.predicates = predicates } @@ -104,7 +106,7 @@ public class QueryPredicateGroup: QueryPredicate, Encodable { private let _encode: (Encoder) throws -> Void init(_ base: QueryPredicate) { - _encode = base.encode + self._encode = base.encode } func encode(to encoder: Encoder) throws { diff --git a/Amplify/Categories/DataStore/Subscribe/DataStoreCategory+Subscribe.swift b/Amplify/Categories/DataStore/Subscribe/DataStoreCategory+Subscribe.swift index ae669c73f9..2c59c95f17 100644 --- a/Amplify/Categories/DataStore/Subscribe/DataStoreCategory+Subscribe.swift +++ b/Amplify/Categories/DataStore/Subscribe/DataStoreCategory+Subscribe.swift @@ -8,13 +8,15 @@ import Combine extension DataStoreCategory: DataStoreSubscribeBehavior { - public func observe(_ modelType: M.Type) -> AmplifyAsyncThrowingSequence { + public func observe(_ modelType: (some Model).Type) -> AmplifyAsyncThrowingSequence { return plugin.observe(modelType) } - public func observeQuery(for modelType: M.Type, - where predicate: QueryPredicate? = nil, - sort sortInput: QuerySortInput? = nil) + public func observeQuery( + for modelType: M.Type, + where predicate: QueryPredicate? = nil, + sort sortInput: QuerySortInput? = nil + ) -> AmplifyAsyncThrowingSequence> { return plugin.observeQuery(for: modelType, where: predicate, sort: sortInput) } diff --git a/Amplify/Categories/DataStore/Subscribe/MutationEvent+Model.swift b/Amplify/Categories/DataStore/Subscribe/MutationEvent+Model.swift index 332376b096..8e5f29e973 100644 --- a/Amplify/Categories/DataStore/Subscribe/MutationEvent+Model.swift +++ b/Amplify/Categories/DataStore/Subscribe/MutationEvent+Model.swift @@ -5,35 +5,43 @@ // SPDX-License-Identifier: Apache-2.0 // -extension MutationEvent { +public extension MutationEvent { - public init(untypedModel model: Model, - mutationType: MutationType, - version: Int? = nil) throws { + init( + untypedModel model: Model, + mutationType: MutationType, + version: Int? = nil + ) throws { guard let modelType = ModelRegistry.modelType(from: model.modelName) else { let dataStoreError = DataStoreError.invalidModelName(model.modelName) throw dataStoreError } - try self.init(untypedModel: model, - modelName: modelType.schema.name, - mutationType: mutationType, - version: version) + try self.init( + untypedModel: model, + modelName: modelType.schema.name, + mutationType: mutationType, + version: version + ) } - public init(untypedModel model: Model, - modelName: ModelName, - mutationType: MutationType, - version: Int? = nil) throws { + init( + untypedModel model: Model, + modelName: ModelName, + mutationType: MutationType, + version: Int? = nil + ) throws { let json = try model.toJSON() guard let modelSchema = ModelRegistry.modelSchema(from: modelName) else { let dataStoreError = DataStoreError.invalidModelName(modelName) throw dataStoreError } - self.init(modelId: model.identifier(schema: modelSchema).stringValue, - modelName: modelName, - json: json, - mutationType: mutationType, - version: version) + self.init( + modelId: model.identifier(schema: modelSchema).stringValue, + modelName: modelName, + json: json, + mutationType: mutationType, + version: version + ) } } diff --git a/Amplify/Categories/DataStore/Subscribe/MutationEvent+Schema.swift b/Amplify/Categories/DataStore/Subscribe/MutationEvent+Schema.swift index 7f6f92af7a..88fa14a35f 100644 --- a/Amplify/Categories/DataStore/Subscribe/MutationEvent+Schema.swift +++ b/Amplify/Categories/DataStore/Subscribe/MutationEvent+Schema.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension MutationEvent { +public extension MutationEvent { // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { + enum CodingKeys: String, ModelKey { case id case modelId case modelName @@ -20,11 +20,11 @@ extension MutationEvent { case graphQLFilterJSON } - public static let keys = CodingKeys.self + static let keys = CodingKeys.self // MARK: - ModelSchema - public static let schema = defineSchema { definition in + static let schema = defineSchema { definition in let mutation = MutationEvent.keys definition.listPluralName = "MutationEvents" diff --git a/Amplify/Categories/DataStore/Subscribe/MutationEvent.swift b/Amplify/Categories/DataStore/Subscribe/MutationEvent.swift index 988ba31994..d9f82cba89 100644 --- a/Amplify/Categories/DataStore/Subscribe/MutationEvent.swift +++ b/Amplify/Categories/DataStore/Subscribe/MutationEvent.swift @@ -21,15 +21,17 @@ public struct MutationEvent: Model { public var inProcess: Bool public var graphQLFilterJSON: String? - public init(id: EventIdentifier = UUID().uuidString, - modelId: ModelId, - modelName: String, - json: String, - mutationType: MutationType, - createdAt: Temporal.DateTime = .now(), - version: Int? = nil, - inProcess: Bool = false, - graphQLFilterJSON: String? = nil) { + public init( + id: EventIdentifier = UUID().uuidString, + modelId: ModelId, + modelName: String, + json: String, + mutationType: MutationType, + createdAt: Temporal.DateTime = .now(), + version: Int? = nil, + inProcess: Bool = false, + graphQLFilterJSON: String? = nil + ) { self.id = id self.modelId = modelId self.modelName = modelName @@ -41,18 +43,22 @@ public struct MutationEvent: Model { self.graphQLFilterJSON = graphQLFilterJSON } - public init(model: M, - modelSchema: ModelSchema, - mutationType: MutationType, - version: Int? = nil, - graphQLFilterJSON: String? = nil) throws { + public init( + model: some Model, + modelSchema: ModelSchema, + mutationType: MutationType, + version: Int? = nil, + graphQLFilterJSON: String? = nil + ) throws { let json = try model.toJSON() - self.init(modelId: model.identifier(schema: modelSchema).stringValue, - modelName: modelSchema.name, - json: json, - mutationType: mutationType, - version: version, - graphQLFilterJSON: graphQLFilterJSON) + self.init( + modelId: model.identifier(schema: modelSchema).stringValue, + modelName: modelSchema.name, + json: json, + mutationType: mutationType, + version: version, + graphQLFilterJSON: graphQLFilterJSON + ) } @@ -60,15 +66,19 @@ public struct MutationEvent: Model { Initializing from a model without a ModelSchema is deprecated. Use init(model:modelSchema:mutationType:version:graphQLFilterJSON:) instead. """) - public init(model: M, - mutationType: MutationType, - version: Int? = nil, - graphQLFilterJSON: String? = nil) throws { - try self.init(model: model, - modelSchema: model.schema, - mutationType: mutationType, - version: version, - graphQLFilterJSON: graphQLFilterJSON) + public init( + model: M, + mutationType: MutationType, + version: Int? = nil, + graphQLFilterJSON: String? = nil + ) throws { + try self.init( + model: model, + modelSchema: model.schema, + mutationType: mutationType, + version: version, + graphQLFilterJSON: graphQLFilterJSON + ) } @@ -89,7 +99,8 @@ public struct MutationEvent: Model { it is a valid \(modelType.modelName) instance: \(json) - """) + """ + ) } return typedModel diff --git a/Amplify/Categories/Geo/GeoCategory+ClientBehavior.swift b/Amplify/Categories/Geo/GeoCategory+ClientBehavior.swift index b435e6931c..9427bf2cf1 100644 --- a/Amplify/Categories/Geo/GeoCategory+ClientBehavior.swift +++ b/Amplify/Categories/Geo/GeoCategory+ClientBehavior.swift @@ -22,8 +22,10 @@ extension GeoCategory: GeoCategoryBehavior { /// `Geo.Error.networkError` if request failed or network unavailable /// `Geo.Error.pluginError` if encapsulated error received by a dependent plugin /// `Geo.Error.unknown` if error is unknown - public func search(for text: String, - options: Geo.SearchForTextOptions? = nil) async throws -> [Geo.Place] { + public func search( + for text: String, + options: Geo.SearchForTextOptions? = nil + ) async throws -> [Geo.Place] { return try await plugin.search(for: text, options: options) } @@ -41,8 +43,10 @@ extension GeoCategory: GeoCategoryBehavior { /// `Geo.Error.networkError` if request failed or network unavailable /// `Geo.Error.pluginError` if encapsulated error received by a dependent plugin /// `Geo.Error.unknown` if error is unknown - public func search(for coordinates: Geo.Coordinates, - options: Geo.SearchForCoordinatesOptions? = nil) async throws -> [Geo.Place] { + public func search( + for coordinates: Geo.Coordinates, + options: Geo.SearchForCoordinatesOptions? = nil + ) async throws -> [Geo.Place] { return try await plugin.search(for: coordinates, options: options) } diff --git a/Amplify/Categories/Geo/GeoCategory.swift b/Amplify/Categories/Geo/GeoCategory.swift index aa9579a9bb..6059187ae4 100644 --- a/Amplify/Categories/Geo/GeoCategory.swift +++ b/Amplify/Categories/Geo/GeoCategory.swift @@ -6,7 +6,7 @@ // /// The Geo category enables you to interact with geospacial services. -final public class GeoCategory: Category { +public final class GeoCategory: Category { /// Geo category type public let categoryType = CategoryType.geo @@ -56,7 +56,8 @@ final public class GeoCategory: Category { let pluginDescription = String(describing: plugin) let error = Geo.Error.invalidConfiguration( "Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -81,7 +82,8 @@ final public class GeoCategory: Category { let keys = plugins.keys.joined(separator: ", ") let error = Geo.Error.invalidConfiguration( "No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/Geo/GeoCategoryBehavior.swift b/Amplify/Categories/Geo/GeoCategoryBehavior.swift index 29fe16bf57..ee0a854ff8 100644 --- a/Amplify/Categories/Geo/GeoCategoryBehavior.swift +++ b/Amplify/Categories/Geo/GeoCategoryBehavior.swift @@ -25,8 +25,10 @@ public protocol GeoCategoryBehavior { /// `Geo.Error.networkError` if request failed or network unavailable /// `Geo.Error.pluginError` if encapsulated error received by a dependent plugin /// `Geo.Error.unknown` if error is unknown - func search(for text: String, - options: Geo.SearchForTextOptions?) async throws -> [Geo.Place] + func search( + for text: String, + options: Geo.SearchForTextOptions? + ) async throws -> [Geo.Place] /// Reverse geocodes a given pair of coordinates and returns a list of Places /// closest to the specified position. @@ -42,8 +44,10 @@ public protocol GeoCategoryBehavior { /// `Geo.Error.networkError` if request failed or network unavailable /// `Geo.Error.pluginError` if encapsulated error received by a dependent plugin /// `Geo.Error.unknown` if error is unknown - func search(for coordinates: Geo.Coordinates, - options: Geo.SearchForCoordinatesOptions?) async throws -> [Geo.Place] + func search( + for coordinates: Geo.Coordinates, + options: Geo.SearchForCoordinatesOptions? + ) async throws -> [Geo.Place] // MARK: - Maps diff --git a/Amplify/Categories/Geo/Types/CLocationCoordinate2D+Geo.Coordinates.swift b/Amplify/Categories/Geo/Types/CLocationCoordinate2D+Geo.Coordinates.swift index a67ce4c3a1..d016d5e25b 100644 --- a/Amplify/Categories/Geo/Types/CLocationCoordinate2D+Geo.Coordinates.swift +++ b/Amplify/Categories/Geo/Types/CLocationCoordinate2D+Geo.Coordinates.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import CoreLocation +import Foundation public extension CLLocationCoordinate2D { /// Initialize a Location from a CLLocationCoordinate2D diff --git a/Amplify/Categories/Geo/Types/Geo+Coordinates.swift b/Amplify/Categories/Geo/Types/Geo+Coordinates.swift index b374b42e4f..0e30837097 100644 --- a/Amplify/Categories/Geo/Types/Geo+Coordinates.swift +++ b/Amplify/Categories/Geo/Types/Geo+Coordinates.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import CoreLocation +import Foundation public extension Geo { /// A pair of coordinates to represent a location (point). diff --git a/Amplify/Categories/Geo/Types/Geo+Error.swift b/Amplify/Categories/Geo/Types/Geo+Error.swift index d7e6b81615..abd91e40d2 100644 --- a/Amplify/Categories/Geo/Types/Geo+Error.swift +++ b/Amplify/Categories/Geo/Types/Geo+Error.swift @@ -27,9 +27,11 @@ public extension Geo { extension Geo.Error: AmplifyError { /// Initializer - public init(errorDescription: ErrorDescription = "An unknown error occurred", - recoverySuggestion: RecoverySuggestion = "See `underlyingError` for more details", - error: Error) { + public init( + errorDescription: ErrorDescription = "An unknown error occurred", + recoverySuggestion: RecoverySuggestion = "See `underlyingError` for more details", + error: Error + ) { if let error = error as? Self { self = error } else if error.isOperationCancelledError { diff --git a/Amplify/Categories/Geo/Types/Geo+Place.swift b/Amplify/Categories/Geo/Types/Geo+Place.swift index 18d6e4c2dd..ebfedd6fc9 100644 --- a/Amplify/Categories/Geo/Types/Geo+Place.swift +++ b/Amplify/Categories/Geo/Types/Geo+Place.swift @@ -34,16 +34,18 @@ public extension Geo { public let country: String? /// Initializer - public init(coordinates: Coordinates, - label: String?, - addressNumber: String?, - street: String?, - municipality: String?, - neighborhood: String?, - region: String?, - subRegion: String?, - postalCode: String?, - country: String?) { + public init( + coordinates: Coordinates, + label: String?, + addressNumber: String?, + street: String?, + municipality: String?, + neighborhood: String?, + region: String?, + subRegion: String?, + postalCode: String?, + country: String? + ) { self.coordinates = coordinates self.label = label self.addressNumber = addressNumber diff --git a/Amplify/Categories/Geo/Types/Geo+SearchArea.swift b/Amplify/Categories/Geo/Types/Geo+SearchArea.swift index c0a3b3c124..13c5c7a816 100644 --- a/Amplify/Categories/Geo/Types/Geo+SearchArea.swift +++ b/Amplify/Categories/Geo/Types/Geo+SearchArea.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import CoreLocation +import Foundation public extension Geo { /// The area to search. diff --git a/Amplify/Categories/Geo/Types/Geo+SearchOptions.swift b/Amplify/Categories/Geo/Types/Geo+SearchOptions.swift index 88f683c5b9..5353d90fef 100644 --- a/Amplify/Categories/Geo/Types/Geo+SearchOptions.swift +++ b/Amplify/Categories/Geo/Types/Geo+SearchOptions.swift @@ -21,10 +21,12 @@ public extension Geo { /// functionality. See plugin documentation for expected key/values. public var pluginOptions: Any? - public init(area: Geo.SearchArea? = nil, - countries: [Geo.Country]? = nil, - maxResults: Int? = nil, - pluginOptions: Any? = nil) { + public init( + area: Geo.SearchArea? = nil, + countries: [Geo.Country]? = nil, + maxResults: Int? = nil, + pluginOptions: Any? = nil + ) { self.area = area self.countries = countries self.maxResults = maxResults @@ -43,8 +45,10 @@ public extension Geo { /// functionality. See plugin documentation for expected key/values. public var pluginOptions: Any? - public init(maxResults: Int? = nil, - pluginOptions: Any? = nil) { + public init( + maxResults: Int? = nil, + pluginOptions: Any? = nil + ) { self.maxResults = maxResults self.pluginOptions = pluginOptions } diff --git a/Amplify/Categories/Hub/HubCategory+ClientBehavior.swift b/Amplify/Categories/Hub/HubCategory+ClientBehavior.swift index 14afd3581d..ced73c0d02 100644 --- a/Amplify/Categories/Hub/HubCategory+ClientBehavior.swift +++ b/Amplify/Categories/Hub/HubCategory+ClientBehavior.swift @@ -18,15 +18,19 @@ extension HubCategory: HubCategoryBehavior { plugin.dispatch(to: channel, payload: payload) } - public func listen(to channel: HubChannel, - eventName: HubPayloadEventName, - listener: @escaping HubListener) -> UnsubscribeToken { + public func listen( + to channel: HubChannel, + eventName: HubPayloadEventName, + listener: @escaping HubListener + ) -> UnsubscribeToken { plugin.listen(to: channel, eventName: eventName, listener: listener) } - public func listen(to channel: HubChannel, - isIncluded filter: HubFilter? = nil, - listener: @escaping HubListener) -> UnsubscribeToken { + public func listen( + to channel: HubChannel, + isIncluded filter: HubFilter? = nil, + listener: @escaping HubListener + ) -> UnsubscribeToken { plugin.listen(to: channel, isIncluded: filter, listener: listener) } diff --git a/Amplify/Categories/Hub/HubCategory.swift b/Amplify/Categories/Hub/HubCategory.swift index d12e45323a..e82135caae 100644 --- a/Amplify/Categories/Hub/HubCategory.swift +++ b/Amplify/Categories/Hub/HubCategory.swift @@ -10,7 +10,7 @@ /// between modules and components in your app. Hub enables different categories to /// communicate with one another when specific events occur, such as authentication /// events like a user sign-in or notification of a file download. -final public class HubCategory: Category { +public final class HubCategory: Category { enum ConfigurationState { /// Default configuration at initialization @@ -87,8 +87,10 @@ final public class HubCategory: Category { let key = plugin.key guard !key.isEmpty else { let pluginDescription = String(describing: plugin) - let error = HubError.configuration("Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + let error = HubError.configuration( + "Plugin \(pluginDescription) has an empty `key`.", + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -102,8 +104,10 @@ final public class HubCategory: Category { public func getPlugin(for key: PluginKey) throws -> HubCategoryPlugin { guard let plugin = plugins[key] else { let keys = plugins.keys.joined(separator: ", ") - let error = HubError.configuration("No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + let error = HubError.configuration( + "No plugin has been added for '\(key)'.", + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/Hub/HubCategoryBehavior.swift b/Amplify/Categories/Hub/HubCategoryBehavior.swift index 45b577f670..d969bbface 100644 --- a/Amplify/Categories/Hub/HubCategoryBehavior.swift +++ b/Amplify/Categories/Hub/HubCategoryBehavior.swift @@ -23,9 +23,11 @@ public protocol HubCategoryBehavior { /// - Parameter channel: The channel to listen for messages on /// - Parameter eventName: Only hub payloads with this event name will be dispatched to the listener /// - Parameter listener: The closure to invoke with the received message - func listen(to channel: HubChannel, - eventName: HubPayloadEventName, - listener: @escaping HubListener) -> UnsubscribeToken + func listen( + to channel: HubChannel, + eventName: HubPayloadEventName, + listener: @escaping HubListener + ) -> UnsubscribeToken /// Listen to Hub messages on a particular channel, optionally filtering message prior to dispatching them /// @@ -33,9 +35,11 @@ public protocol HubCategoryBehavior { /// - Parameter filter: If specified, candidate messages will be passed to this closure prior to dispatching to /// the `listener`. Only messages for which the filter returns `true` will be dispatched. /// - Parameter listener: The closure to invoke with the received message - func listen(to channel: HubChannel, - isIncluded filter: HubFilter?, - listener: @escaping HubListener) -> UnsubscribeToken + func listen( + to channel: HubChannel, + isIncluded filter: HubFilter?, + listener: @escaping HubListener + ) -> UnsubscribeToken /// Removes the listener identified by `token` /// - Parameter token: The UnsubscribeToken returned by `listen` diff --git a/Amplify/Categories/Hub/HubChannel.swift b/Amplify/Categories/Hub/HubChannel.swift index 0979ac95c3..7315944c12 100644 --- a/Amplify/Categories/Hub/HubChannel.swift +++ b/Amplify/Categories/Hub/HubChannel.swift @@ -75,8 +75,8 @@ extension HubChannel: Equatable { } } -extension HubChannel { - public init(from categoryType: CategoryType) { +public extension HubChannel { + init(from categoryType: CategoryType) { switch categoryType { case .analytics: self = .analytics diff --git a/Amplify/Categories/Hub/HubFilter.swift b/Amplify/Categories/Hub/HubFilter.swift index afaff5ba77..85cf24c493 100644 --- a/Amplify/Categories/Hub/HubFilter.swift +++ b/Amplify/Categories/Hub/HubFilter.swift @@ -11,7 +11,7 @@ import Foundation public typealias HubFilter = (HubPayload) -> Bool /// Convenience filters for common filtering use cases -public struct HubFilters { +public enum HubFilters { /// True if all filters evaluate to true public static func all(filters: HubFilter...) -> HubFilter { @@ -31,8 +31,8 @@ public struct HubFilters { /// Returns a HubFilter that is `true` if the event's `context` property has a UUID that matches `operation.id` /// - Parameter operation: The operation to match - public static func forOperation - (_ operation: AmplifyOperation) -> HubFilter { + public static func forOperation + (_ operation: AmplifyOperation) -> HubFilter { let operationId = operation.id let filter: HubFilter = { payload in guard let context = payload.context as? AmplifyOperationContext else { diff --git a/Amplify/Categories/Hub/HubPayload.swift b/Amplify/Categories/Hub/HubPayload.swift index 3c89b0d73c..52b9746a42 100644 --- a/Amplify/Categories/Hub/HubPayload.swift +++ b/Amplify/Categories/Hub/HubPayload.swift @@ -24,9 +24,11 @@ public struct HubPayload { /// AmplifyOperations, this field will be the Operation's associated OperationResult. public let data: Any? - public init(eventName: String, - context: Any? = nil, - data: Any? = nil) { + public init( + eventName: String, + context: Any? = nil, + data: Any? = nil + ) { self.eventName = eventName self.context = context self.data = data diff --git a/Amplify/Categories/Logging/Internal/LoggingCategory+CategoryConfigurable.swift b/Amplify/Categories/Logging/Internal/LoggingCategory+CategoryConfigurable.swift index 67a9c69899..0d716cb3d2 100644 --- a/Amplify/Categories/Logging/Internal/LoggingCategory+CategoryConfigurable.swift +++ b/Amplify/Categories/Logging/Internal/LoggingCategory+CategoryConfigurable.swift @@ -26,9 +26,9 @@ extension LoggingCategory: CategoryConfigurable { } try plugin.configure(using: configuration?.plugins[plugin.key]) - self.plugins[plugin.key] = plugin + plugins[plugin.key] = plugin - if plugin.key != AWSUnifiedLoggingPlugin.key, let consolePlugin = try? self.getPlugin(for: AWSUnifiedLoggingPlugin.key) { + if plugin.key != AWSUnifiedLoggingPlugin.key, let consolePlugin = try? getPlugin(for: AWSUnifiedLoggingPlugin.key) { try consolePlugin.configure(using: configuration?.plugins[consolePlugin.key]) } @@ -57,9 +57,9 @@ extension LoggingCategory: CategoryConfigurable { } try plugin.configure(using: amplifyOutputs) - self.plugins[plugin.key] = plugin + plugins[plugin.key] = plugin - if plugin.key != AWSUnifiedLoggingPlugin.key, let consolePlugin = try? self.getPlugin(for: AWSUnifiedLoggingPlugin.key) { + if plugin.key != AWSUnifiedLoggingPlugin.key, let consolePlugin = try? getPlugin(for: AWSUnifiedLoggingPlugin.key) { try consolePlugin.configure(using: amplifyOutputs) } diff --git a/Amplify/Categories/Logging/LoggingCategory.swift b/Amplify/Categories/Logging/LoggingCategory.swift index b1dbd0e159..e23bba2c81 100644 --- a/Amplify/Categories/Logging/LoggingCategory.swift +++ b/Amplify/Categories/Logging/LoggingCategory.swift @@ -8,7 +8,7 @@ import Foundation /// AWS Amplify writes console logs through Logger. You can use Logger in your apps for the same purpose. -final public class LoggingCategory: Category { +public final class LoggingCategory: Category { enum ConfigurationState { /// Default configuration at initialization case `default` @@ -81,8 +81,10 @@ final public class LoggingCategory: Category { let key = plugin.key guard !key.isEmpty else { let pluginDescription = String(describing: plugin) - let error = LoggingError.configuration("Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + let error = LoggingError.configuration( + "Plugin \(pluginDescription) has an empty `key`.", + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -95,8 +97,10 @@ final public class LoggingCategory: Category { /// - Returns: The wrapped plugin public func getPlugin(for key: PluginKey) throws -> LoggingCategoryPlugin { guard let plugin = plugins.first(where: { $0.key == key})?.value else { - let error = LoggingError.configuration("No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use the installed plugin, which has the key '\(key)'") + let error = LoggingError.configuration( + "No plugin has been added for '\(key)'.", + "Either add a plugin for '\(key)', or use the installed plugin, which has the key '\(key)'" + ) throw error } return plugin diff --git a/Amplify/Categories/Notifications/NotificationsCategory.swift b/Amplify/Categories/Notifications/NotificationsCategory.swift index 02c4122b6f..e0e6371fec 100644 --- a/Amplify/Categories/Notifications/NotificationsCategory.swift +++ b/Amplify/Categories/Notifications/NotificationsCategory.swift @@ -19,6 +19,6 @@ public final class NotificationsCategory { Push ] - return allSubcategories.filter { $0.isConfigured } + return allSubcategories.filter(\.isConfigured) } } diff --git a/Amplify/Categories/Notifications/PushNotifications/PushNotificationsCategory.swift b/Amplify/Categories/Notifications/PushNotifications/PushNotificationsCategory.swift index 2b81b046d7..7c675fdb10 100644 --- a/Amplify/Categories/Notifications/PushNotifications/PushNotificationsCategory.swift +++ b/Amplify/Categories/Notifications/PushNotifications/PushNotificationsCategory.swift @@ -55,7 +55,8 @@ public final class PushNotificationsCategory: Category { let pluginDescription = String(describing: plugin) let error = PushNotificationsError.configuration( "Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -80,7 +81,8 @@ public final class PushNotificationsCategory: Category { let keys = plugins.keys.joined(separator: ", ") let error = PushNotificationsError.configuration( "No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+Types.swift b/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+Types.swift index 5f2cf0966f..eaf7dc2f6e 100644 --- a/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+Types.swift +++ b/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+Types.swift @@ -7,6 +7,6 @@ import Foundation -extension Notifications { - public enum Push {} +public extension Notifications { + enum Push {} } diff --git a/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+UserInfo.swift b/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+UserInfo.swift index 4f513bdfbf..ccdfaab613 100644 --- a/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+UserInfo.swift +++ b/Amplify/Categories/Notifications/PushNotifications/Types/PushNotificationsCategory+UserInfo.swift @@ -7,12 +7,12 @@ import Foundation -extension Notifications.Push { +public extension Notifications.Push { #if canImport(UIKit) /// A dictionary that contains information related to the remote notification - public typealias UserInfo = [AnyHashable: Any] + typealias UserInfo = [AnyHashable: Any] #elseif canImport(AppKit) /// A dictionary that contains information related to the remote notification - public typealias UserInfo = [String: Any] + typealias UserInfo = [String: Any] #endif } diff --git a/Amplify/Categories/Predictions/Error/PredictionsError+ClientError.swift b/Amplify/Categories/Predictions/Error/PredictionsError+ClientError.swift index d801ad26ff..23c390d934 100644 --- a/Amplify/Categories/Predictions/Error/PredictionsError+ClientError.swift +++ b/Amplify/Categories/Predictions/Error/PredictionsError+ClientError.swift @@ -7,8 +7,8 @@ import Foundation -extension PredictionsError { - public struct ClientError: Equatable { +public extension PredictionsError { + struct ClientError: Equatable { public static func == (lhs: PredictionsError.ClientError, rhs: PredictionsError.ClientError) -> Bool { lhs.description == rhs.description && lhs.recoverySuggestion == rhs.recoverySuggestion @@ -30,48 +30,48 @@ extension PredictionsError { } } -extension PredictionsError.ClientError { - public static let imageNotFound = Self( +public extension PredictionsError.ClientError { + static let imageNotFound = Self( description: "Something was wrong with the image file, make sure it exists.", recoverySuggestion: "Try choosing an image and sending it again." ) - public static let invalidRegion = Self( + static let invalidRegion = Self( description: "Invalid region", recoverySuggestion: "Ensure that you provide a valid region in your configuration" ) - public static let missingSourceLanguage = Self( + static let missingSourceLanguage = Self( description: "Source language is not provided", recoverySuggestion: "Provide a supported source language" ) - public static let missingTargetLanguage = Self( + static let missingTargetLanguage = Self( description: "Target language is not provided", recoverySuggestion: "Provide a supported target language" ) - public static let onlineIdentityServiceUnavailable = Self( + static let onlineIdentityServiceUnavailable = Self( description: "Online identify service is not available", recoverySuggestion: "Please check if the values are proprely initialized" ) - public static let offlineIdentityServiceUnavailable = Self( + static let offlineIdentityServiceUnavailable = Self( description: "Offline identify service is not available", recoverySuggestion: "Please check if the values are proprely initialized" ) - public static let onlineInterpretServiceUnavailable = Self( + static let onlineInterpretServiceUnavailable = Self( description: "Online interpret service is not available", recoverySuggestion: "Please check if the values are proprely initialized" ) - public static let offlineInterpretServiceUnavailable = Self( + static let offlineInterpretServiceUnavailable = Self( description: "Offline interpret service is not available", recoverySuggestion: "Please check if the values are proprely initialized" ) - public static let unableToInterpretText = Self( + static let unableToInterpretText = Self( description: "No result found for the text", recoverySuggestion: "Interpret text did not produce any result" ) diff --git a/Amplify/Categories/Predictions/Error/PredictionsError+ServiceError.swift b/Amplify/Categories/Predictions/Error/PredictionsError+ServiceError.swift index 173705b27d..34f694b322 100644 --- a/Amplify/Categories/Predictions/Error/PredictionsError+ServiceError.swift +++ b/Amplify/Categories/Predictions/Error/PredictionsError+ServiceError.swift @@ -7,8 +7,8 @@ import Foundation -extension PredictionsError { - public struct ServiceError: Equatable { +public extension PredictionsError { + struct ServiceError: Equatable { public static func == (lhs: PredictionsError.ServiceError, rhs: PredictionsError.ServiceError) -> Bool { lhs.description == rhs.description && lhs.recoverySuggestion == rhs.recoverySuggestion @@ -33,8 +33,8 @@ extension PredictionsError { } } -extension PredictionsError.ServiceError { - public static let translationFailed = Self( +public extension PredictionsError.ServiceError { + static let translationFailed = Self( description: "No result was found.", recoverySuggestion: """ Please make sure a text string was sent over and @@ -42,7 +42,7 @@ extension PredictionsError.ServiceError { """ ) - public static let internalServerError = Self( + static let internalServerError = Self( description: "An internal server error occurred.", recoverySuggestion: """ This shouldn't never happen. There is a possibility that there is a bug if this error persists. @@ -51,27 +51,27 @@ extension PredictionsError.ServiceError { """ ) - public static let detectedLanguageLowConfidence = Self( + static let detectedLanguageLowConfidence = Self( description: "A language was detected but with very low confidence.", recoverySuggestion: "Please make sure you use one of the available languages." ) - public static let invalidRequest = Self( + static let invalidRequest = Self( description: "An invalid request was sent.", recoverySuggestion: "Please check your request and try again." ) - public static let resourceNotFound = Self( + static let resourceNotFound = Self( description: "The specified resource doesn't exist.", recoverySuggestion: "Please make sure you configured the resource properly." ) - public static let textSizeLimitExceeded = Self( + static let textSizeLimitExceeded = Self( description: "The size of the text string exceeded the limit.", recoverySuggestion: "Please send a shorter text string." ) - public static let unsupportedLanguagePair = Self( + static let unsupportedLanguagePair = Self( description: "Your target language and source language are an unsupported language pair.", recoverySuggestion: """ Please ensure the service supports translating from the specified source @@ -79,22 +79,22 @@ extension PredictionsError.ServiceError { """ ) - public static let throttling = Self( + static let throttling = Self( description: "Your rate of request increase is too fast.", recoverySuggestion: "Slow down your request rate and gradually increase it." ) - public static let unsupportedLanguage = Self( + static let unsupportedLanguage = Self( description: "The language specified is not currently supported by the service.", recoverySuggestion: "Choose a new language that is supported." ) - public static let invalidSampleRate = Self( + static let invalidSampleRate = Self( description: "The specified sample rate is not valid.", recoverySuggestion: "" ) - public static let accessDenied = Self( + static let accessDenied = Self( description: "Access denied", recoverySuggestion: """ Please check that your Cognito IAM role has permissions diff --git a/Amplify/Categories/Predictions/Models/Attribute.swift b/Amplify/Categories/Predictions/Models/Attribute.swift index 0948c46ae5..d388cd6b56 100644 --- a/Amplify/Categories/Predictions/Models/Attribute.swift +++ b/Amplify/Categories/Predictions/Models/Attribute.swift @@ -7,9 +7,9 @@ import Foundation -extension Predictions { +public extension Predictions { /// Attribute of an entity identified as a result of identify() API - public struct Attribute { + struct Attribute { public let name: String public let value: Bool public let confidence: Double diff --git a/Amplify/Categories/Predictions/Models/BoundedKeyValue.swift b/Amplify/Categories/Predictions/Models/BoundedKeyValue.swift index 2bfc072ebb..b49bb59824 100644 --- a/Amplify/Categories/Predictions/Models/BoundedKeyValue.swift +++ b/Amplify/Categories/Predictions/Models/BoundedKeyValue.swift @@ -7,11 +7,11 @@ import CoreGraphics -extension Predictions { +public extension Predictions { /// Describes the data extracted as key-value pair in /// an image/document resulting from identify() API /// e.g The text "Name: John Doe" present in an image/document - public struct BoundedKeyValue { + struct BoundedKeyValue { public let key: String public let value: String public let isSelected: Bool diff --git a/Amplify/Categories/Predictions/Models/Celebrity+Metadata.swift b/Amplify/Categories/Predictions/Models/Celebrity+Metadata.swift index 9ec8bb99b4..2b30975a87 100644 --- a/Amplify/Categories/Predictions/Models/Celebrity+Metadata.swift +++ b/Amplify/Categories/Predictions/Models/Celebrity+Metadata.swift @@ -7,9 +7,9 @@ import Foundation -extension Predictions.Celebrity { +public extension Predictions.Celebrity { /// Celebrity metadata identified as a result of identify() API - public struct Metadata { + struct Metadata { public let name: String public let identifier: String public let urls: [URL] diff --git a/Amplify/Categories/Predictions/Models/Celebrity.swift b/Amplify/Categories/Predictions/Models/Celebrity.swift index 300955d199..2504a1f24a 100644 --- a/Amplify/Categories/Predictions/Models/Celebrity.swift +++ b/Amplify/Categories/Predictions/Models/Celebrity.swift @@ -5,14 +5,14 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import CoreGraphics +import Foundation -extension Predictions { +public extension Predictions { /// Describes a celebrity identified in an image /// with information about its location(bounding box) and /// facial features(landmarks) - public struct Celebrity { + struct Celebrity { public let metadata: Metadata public let boundingBox: CGRect public let landmarks: [Landmark] diff --git a/Amplify/Categories/Predictions/Models/Emotion+Kind.swift b/Amplify/Categories/Predictions/Models/Emotion+Kind.swift index 543d497456..64add5328a 100644 --- a/Amplify/Categories/Predictions/Models/Emotion+Kind.swift +++ b/Amplify/Categories/Predictions/Models/Emotion+Kind.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Emotion { +public extension Predictions.Emotion { /// Different emotion types returned as a result of /// identify() API call - public struct Kind: Equatable { + struct Kind: Equatable { let id: UInt8 public static let unknown = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/Emotion.swift b/Amplify/Categories/Predictions/Models/Emotion.swift index 1f593ccbc4..367db2004e 100644 --- a/Amplify/Categories/Predictions/Models/Emotion.swift +++ b/Amplify/Categories/Predictions/Models/Emotion.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Emotion identified in an entity(faces/celebrities) /// as a result of identify() API with associated `EmotionType` /// and confidence value - public struct Emotion { + struct Emotion { public let emotion: Kind public let confidence: Double diff --git a/Amplify/Categories/Predictions/Models/Entity+DetectionResult.swift b/Amplify/Categories/Predictions/Models/Entity+DetectionResult.swift index c61656c954..21a7032dbf 100644 --- a/Amplify/Categories/Predictions/Models/Entity+DetectionResult.swift +++ b/Amplify/Categories/Predictions/Models/Entity+DetectionResult.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Entity { +public extension Predictions.Entity { /// Describes the result of interpret() API when the analyzed text /// contains a person/place - public struct DetectionResult { + struct DetectionResult { public let type: Predictions.Entity.Kind public let targetText: String public let score: Float? diff --git a/Amplify/Categories/Predictions/Models/Entity+Kind.swift b/Amplify/Categories/Predictions/Models/Entity+Kind.swift index 1d66a50ac7..4bd6d98c61 100644 --- a/Amplify/Categories/Predictions/Models/Entity+Kind.swift +++ b/Amplify/Categories/Predictions/Models/Entity+Kind.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Entity { +public extension Predictions.Entity { /// Different entity types detected in a text as a result of /// interpret() API - public struct Kind: Equatable, Hashable { + struct Kind: Equatable, Hashable { let id: UInt8 public static let unknown = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/Entity+Match.swift b/Amplify/Categories/Predictions/Models/Entity+Match.swift index c101004b9b..c1e6b3d0e5 100644 --- a/Amplify/Categories/Predictions/Models/Entity+Match.swift +++ b/Amplify/Categories/Predictions/Models/Entity+Match.swift @@ -7,10 +7,10 @@ import CoreGraphics -extension Predictions.Entity { +public extension Predictions.Entity { /// Describes the result for an entity matched in an entity collection /// created on AWS Rekogniton and detected from identify() API call - public struct Match { + struct Match { public let boundingBox: CGRect public let metadata: Metadata @@ -23,8 +23,8 @@ extension Predictions.Entity { } } } -extension Predictions.Entity.Match { - public struct Metadata { +public extension Predictions.Entity.Match { + struct Metadata { public let externalImageId: String? public let similarity: Double diff --git a/Amplify/Categories/Predictions/Models/Entity+Metadata.swift b/Amplify/Categories/Predictions/Models/Entity+Metadata.swift index 6c91db35b8..b81eccf7b3 100644 --- a/Amplify/Categories/Predictions/Models/Entity+Metadata.swift +++ b/Amplify/Categories/Predictions/Models/Entity+Metadata.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Entity { - public struct Metadata { +public extension Predictions.Entity { + struct Metadata { public let confidence: Double public let pose: Predictions.Pose diff --git a/Amplify/Categories/Predictions/Models/Entity.swift b/Amplify/Categories/Predictions/Models/Entity.swift index 273ec38fbf..b5dc15902a 100644 --- a/Amplify/Categories/Predictions/Models/Entity.swift +++ b/Amplify/Categories/Predictions/Models/Entity.swift @@ -7,10 +7,10 @@ import CoreGraphics -extension Predictions { +public extension Predictions { /// Result returned as part of identify() API call with /// `IdentifyAction.detectEntities` type parameter - public struct Entity { + struct Entity { public let boundingBox: CGRect public let landmarks: [Landmark] public let ageRange: ClosedRange? diff --git a/Amplify/Categories/Predictions/Models/Gender.swift b/Amplify/Categories/Predictions/Models/Gender.swift index 0889c9b767..7007246777 100644 --- a/Amplify/Categories/Predictions/Models/Gender.swift +++ b/Amplify/Categories/Predictions/Models/Gender.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Describes gender of an entity identified as a result of /// identify() API - public struct Gender { + struct Gender { let id: UInt8 public static let unknown = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/GenderAttribute.swift b/Amplify/Categories/Predictions/Models/GenderAttribute.swift index c7c6849efb..4c658b9b98 100644 --- a/Amplify/Categories/Predictions/Models/GenderAttribute.swift +++ b/Amplify/Categories/Predictions/Models/GenderAttribute.swift @@ -7,10 +7,10 @@ import Foundation -extension Predictions { +public extension Predictions { /// Gender of an entity(face/celebrity) identified with /// associated confidence value - public struct GenderAttribute { + struct GenderAttribute { public var gender: Gender public var confidence: Double diff --git a/Amplify/Categories/Predictions/Models/IdentifiedLine.swift b/Amplify/Categories/Predictions/Models/IdentifiedLine.swift index eaabadcd72..854f231b9a 100644 --- a/Amplify/Categories/Predictions/Models/IdentifiedLine.swift +++ b/Amplify/Categories/Predictions/Models/IdentifiedLine.swift @@ -7,10 +7,10 @@ import CoreGraphics -extension Predictions { +public extension Predictions { /// Describes a line of text identified in an image as a result of /// identify() API call - public struct IdentifiedLine: IdentifiedText { + struct IdentifiedLine: IdentifiedText { public let text: String public let boundingBox: CGRect public let polygon: Polygon? diff --git a/Amplify/Categories/Predictions/Models/IdentifiedWord.swift b/Amplify/Categories/Predictions/Models/IdentifiedWord.swift index 12a3b9d5ef..12e9fccce6 100644 --- a/Amplify/Categories/Predictions/Models/IdentifiedWord.swift +++ b/Amplify/Categories/Predictions/Models/IdentifiedWord.swift @@ -7,10 +7,10 @@ import CoreGraphics -extension Predictions { +public extension Predictions { /// Describes a word identified in an image as a result of /// identify() API call - public struct IdentifiedWord: IdentifiedText { + struct IdentifiedWord: IdentifiedText { public let text: String public let boundingBox: CGRect public let polygon: Polygon? diff --git a/Amplify/Categories/Predictions/Models/KeyPhrase.swift b/Amplify/Categories/Predictions/Models/KeyPhrase.swift index 656125ddb4..332983d2c1 100644 --- a/Amplify/Categories/Predictions/Models/KeyPhrase.swift +++ b/Amplify/Categories/Predictions/Models/KeyPhrase.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Describes a key phrase identified in a text as /// a result of interpret() API call - public struct KeyPhrase { + struct KeyPhrase { public let score: Float? public let text: String public let range: Range diff --git a/Amplify/Categories/Predictions/Models/LabelType.swift b/Amplify/Categories/Predictions/Models/LabelType.swift index 0aff10defa..6223654af4 100644 --- a/Amplify/Categories/Predictions/Models/LabelType.swift +++ b/Amplify/Categories/Predictions/Models/LabelType.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { - public struct LabelType: Equatable { +public extension Predictions { + struct LabelType: Equatable { let id: UInt8 public static let all = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/Landmark.swift b/Amplify/Categories/Predictions/Models/Landmark.swift index 4a00fdeba6..8376bb1a5a 100644 --- a/Amplify/Categories/Predictions/Models/Landmark.swift +++ b/Amplify/Categories/Predictions/Models/Landmark.swift @@ -7,10 +7,10 @@ import CoreGraphics -extension Predictions { +public extension Predictions { /// Describes the facial feature in a celebrity/entity /// identified as a result of identify() API - public struct Landmark { + struct Landmark { public let kind: Kind public let points: [CGPoint] @@ -24,9 +24,9 @@ extension Predictions { } } -extension Predictions.Landmark { +public extension Predictions.Landmark { /// different types of facial features - public struct Kind { + struct Kind { let id: UInt8 public static let allPoints = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/Language+DetectionResult.swift b/Amplify/Categories/Predictions/Models/Language+DetectionResult.swift index d31598288e..79635f7434 100644 --- a/Amplify/Categories/Predictions/Models/Language+DetectionResult.swift +++ b/Amplify/Categories/Predictions/Models/Language+DetectionResult.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Language { +public extension Predictions.Language { /// Result describing language identified in a text /// from interpret() API call - public struct DetectionResult { + struct DetectionResult { public let languageCode: Predictions.Language public let score: Double? diff --git a/Amplify/Categories/Predictions/Models/Language.swift b/Amplify/Categories/Predictions/Models/Language.swift index 484ef1ac1e..83073d49fa 100644 --- a/Amplify/Categories/Predictions/Models/Language.swift +++ b/Amplify/Categories/Predictions/Models/Language.swift @@ -7,9 +7,9 @@ import Foundation -extension Predictions { +public extension Predictions { // swiftlint:disable file_length type_body_length - public struct Language: Equatable, Decodable { + struct Language: Equatable, Decodable { public let code: String public init(code: String) { @@ -2396,8 +2396,8 @@ extension Predictions { } } -extension Predictions.Language { - public init(locale: Locale) { +public extension Predictions.Language { + init(locale: Locale) { guard let languageCode = locale.languageCode else { self = .undetermined return diff --git a/Amplify/Categories/Predictions/Models/PartOfSpeech+DetectionResult.swift b/Amplify/Categories/Predictions/Models/PartOfSpeech+DetectionResult.swift index 4104e9db10..a1e23aa397 100644 --- a/Amplify/Categories/Predictions/Models/PartOfSpeech+DetectionResult.swift +++ b/Amplify/Categories/Predictions/Models/PartOfSpeech+DetectionResult.swift @@ -7,9 +7,9 @@ import Foundation -extension Predictions.PartOfSpeech { +public extension Predictions.PartOfSpeech { /// Part of speech identified in a text from interpret() API - public struct DetectionResult { + struct DetectionResult { public let partOfSpeech: Predictions.PartOfSpeech public let score: Float? diff --git a/Amplify/Categories/Predictions/Models/PartOfSpeech.swift b/Amplify/Categories/Predictions/Models/PartOfSpeech.swift index a7db69909c..66849b9143 100644 --- a/Amplify/Categories/Predictions/Models/PartOfSpeech.swift +++ b/Amplify/Categories/Predictions/Models/PartOfSpeech.swift @@ -7,9 +7,9 @@ import Foundation -extension Predictions { +public extension Predictions { /// Part of speech identified in a text from interpret() API - public struct PartOfSpeech: Equatable { + struct PartOfSpeech: Equatable { let description: String public static let adjective = Self(description: "adjective") diff --git a/Amplify/Categories/Predictions/Models/Polygon.swift b/Amplify/Categories/Predictions/Models/Polygon.swift index bb38da8f64..f84ac8fd95 100644 --- a/Amplify/Categories/Predictions/Models/Polygon.swift +++ b/Amplify/Categories/Predictions/Models/Polygon.swift @@ -7,8 +7,8 @@ import CoreGraphics -extension Predictions { - public struct Polygon { +public extension Predictions { + struct Polygon { public let points: [CGPoint] public init(points: [CGPoint]) { diff --git a/Amplify/Categories/Predictions/Models/Pose.swift b/Amplify/Categories/Predictions/Models/Pose.swift index 8aa116ba7b..57a0ecdb76 100644 --- a/Amplify/Categories/Predictions/Models/Pose.swift +++ b/Amplify/Categories/Predictions/Models/Pose.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Describes the pose of a person identified in an image from identify() API - public struct Pose { + struct Pose { public let pitch: Double public let roll: Double public let yaw: Double diff --git a/Amplify/Categories/Predictions/Models/Selection.swift b/Amplify/Categories/Predictions/Models/Selection.swift index d80fe53343..849104d849 100644 --- a/Amplify/Categories/Predictions/Models/Selection.swift +++ b/Amplify/Categories/Predictions/Models/Selection.swift @@ -7,8 +7,8 @@ import CoreGraphics -extension Predictions { - public struct Selection { +public extension Predictions { + struct Selection { public let boundingBox: CGRect public let polygon: Polygon public let isSelected: Bool diff --git a/Amplify/Categories/Predictions/Models/Sentiment+Kind.swift b/Amplify/Categories/Predictions/Models/Sentiment+Kind.swift index dbe46443db..d7e62b3282 100644 --- a/Amplify/Categories/Predictions/Models/Sentiment+Kind.swift +++ b/Amplify/Categories/Predictions/Models/Sentiment+Kind.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Sentiment { - public struct Kind: Equatable, Hashable { +public extension Predictions.Sentiment { + struct Kind: Equatable, Hashable { let id: UInt8 public static let unknown = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/Sentiment.swift b/Amplify/Categories/Predictions/Models/Sentiment.swift index 58a6e2dc70..5869e22aba 100644 --- a/Amplify/Categories/Predictions/Models/Sentiment.swift +++ b/Amplify/Categories/Predictions/Models/Sentiment.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Sentiment Analysis result for Predictions category - public struct Sentiment { + struct Sentiment { public let predominantSentiment: Kind public let sentimentScores: [Kind: Double]? diff --git a/Amplify/Categories/Predictions/Models/SyntaxToken.swift b/Amplify/Categories/Predictions/Models/SyntaxToken.swift index 56163d7960..b1048766d4 100644 --- a/Amplify/Categories/Predictions/Models/SyntaxToken.swift +++ b/Amplify/Categories/Predictions/Models/SyntaxToken.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Describes syntactical information resulting from text interpretation as /// a result of interpret() API - public struct SyntaxToken { + struct SyntaxToken { public let tokenId: Int public let text: String public let range: Range diff --git a/Amplify/Categories/Predictions/Models/Table.swift b/Amplify/Categories/Predictions/Models/Table.swift index 82e9a812dd..06f2bb8acc 100644 --- a/Amplify/Categories/Predictions/Models/Table.swift +++ b/Amplify/Categories/Predictions/Models/Table.swift @@ -7,8 +7,8 @@ import CoreGraphics -extension Predictions { - public struct Table { +public extension Predictions { + struct Table { public var rows: Int public var columns: Int public var cells: [Cell] @@ -21,8 +21,8 @@ extension Predictions { } } -extension Predictions.Table { - public struct Cell { +public extension Predictions.Table { + struct Cell { public let text: String /// The location of the recognized text on the image. It includes an axis-aligned, diff --git a/Amplify/Categories/Predictions/Models/TextFormatType.swift b/Amplify/Categories/Predictions/Models/TextFormatType.swift index 7fa380acf9..4b6ea00915 100644 --- a/Amplify/Categories/Predictions/Models/TextFormatType.swift +++ b/Amplify/Categories/Predictions/Models/TextFormatType.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { +public extension Predictions { /// Describes different text formats passed a type parameter /// to identify(). - public struct TextFormatType: Equatable { + struct TextFormatType: Equatable { let id: UInt8 public static let all = Self(id: 0) diff --git a/Amplify/Categories/Predictions/Models/Voice.swift b/Amplify/Categories/Predictions/Models/Voice.swift index 5cc73e87f4..ab72988572 100644 --- a/Amplify/Categories/Predictions/Models/Voice.swift +++ b/Amplify/Categories/Predictions/Models/Voice.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions { - public struct Voice { +public extension Predictions { + struct Voice { public let id: String public init(id: String) { diff --git a/Amplify/Categories/Predictions/PredictionsCategory+ClientBehavior.swift b/Amplify/Categories/Predictions/PredictionsCategory+ClientBehavior.swift index f9628e0b7d..1b0c2c2830 100644 --- a/Amplify/Categories/Predictions/PredictionsCategory+ClientBehavior.swift +++ b/Amplify/Categories/Predictions/PredictionsCategory+ClientBehavior.swift @@ -16,8 +16,8 @@ extension PredictionsCategory: PredictionsCategoryBehavior { try await plugin.identify(request, in: image, options: options) } - public func convert( - _ request: Predictions.Convert.Request, + public func convert( + _ request: Predictions.Convert.Request, options: Options? = nil ) async throws -> Output { try await plugin.convert(request, options: options) diff --git a/Amplify/Categories/Predictions/PredictionsCategory.swift b/Amplify/Categories/Predictions/PredictionsCategory.swift index 7a47cdfd82..2964626bfd 100644 --- a/Amplify/Categories/Predictions/PredictionsCategory.swift +++ b/Amplify/Categories/Predictions/PredictionsCategory.swift @@ -7,7 +7,7 @@ public enum Predictions {} -final public class PredictionsCategory: Category { +public final class PredictionsCategory: Category { public let categoryType = CategoryType.predictions diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+Lift.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+Lift.swift index 9f450dc17c..38bd3e3d18 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+Lift.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+Lift.swift @@ -7,9 +7,9 @@ import Foundation -extension Predictions.Convert.Request.Kind { +public extension Predictions.Convert.Request.Kind { @_spi(PredictionsConvertRequestKind) - public struct Lift< + struct Lift< SpecificInput, GenericInput, SpecificOptions, diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Options.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Options.swift index b1a6f3a526..34d69c4aeb 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Options.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Options.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Convert.SpeechToText { - public struct Options { +public extension Predictions.Convert.SpeechToText { + struct Options { /// The default NetworkPolicy for the operation. The default value will be `auto`. public let defaultNetworkPolicy: DefaultNetworkPolicy diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Request.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Request.swift index d20625afc6..e7e15606a2 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Request.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Request.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Convert.SpeechToText { - public struct Request { +public extension Predictions.Convert.SpeechToText { + struct Request { /// The text to synthesize to speech public let speechToText: URL diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Result.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Result.swift index bc597ec3ba..fdcbdc5c62 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Result.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText+Result.swift @@ -7,10 +7,10 @@ import Foundation -extension Predictions.Convert.SpeechToText { +public extension Predictions.Convert.SpeechToText { /// Results are mapped to SpeechToTextResult when convert() API is /// called to convert a text to audio - public struct Result { + struct Result { /// Resulting string from speech to text conversion public let transcription: String diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText.swift index c60d368d9c..d73222aa2c 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+SpeechToText.swift @@ -7,16 +7,16 @@ import Foundation -extension Predictions.Convert { - public enum SpeechToText {} +public extension Predictions.Convert { + enum SpeechToText {} } -extension Predictions.Convert.Request where +public extension Predictions.Convert.Request where Input == URL, Options == Predictions.Convert.SpeechToText.Options, Output == AsyncThrowingStream { - public static func speechToText(url: URL) -> Self { + static func speechToText(url: URL) -> Self { .init(input: url, kind: .speechToText(.lift)) } } diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Options.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Options.swift index 59d0ea93f1..e05c3e594f 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Options.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Options.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Convert.TextToSpeech { - public struct Options { +public extension Predictions.Convert.TextToSpeech { + struct Options { /// The default NetworkPolicy for the operation. The default value will be `auto`. public let defaultNetworkPolicy: DefaultNetworkPolicy diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Request.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Request.swift index fa38c3fd28..6b5f61ae2d 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Request.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Request.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Convert.TextToSpeech { - public struct Request { +public extension Predictions.Convert.TextToSpeech { + struct Request { /// The text to synthesize to speech public let textToSpeech: String diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Result.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Result.swift index d1ee3019d5..91fec245dc 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Result.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech+Result.swift @@ -7,10 +7,10 @@ import Foundation -extension Predictions.Convert.TextToSpeech { +public extension Predictions.Convert.TextToSpeech { /// Results are mapped to TextToSpeechResult when convert() API is /// called to convert a text to audio - public struct Result { + struct Result { /// Resulting audio from text to speech conversion public let audioData: Data diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech.swift index d15b83fa4b..a76d055201 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TextToSpeech.swift @@ -7,16 +7,16 @@ import Foundation -extension Predictions.Convert { - public enum TextToSpeech {} +public extension Predictions.Convert { + enum TextToSpeech {} } -extension Predictions.Convert.Request where +public extension Predictions.Convert.Request where Input == String, Options == Predictions.Convert.TextToSpeech.Options, Output == Predictions.Convert.TextToSpeech.Result { - public static func textToSpeech(_ text: String) -> Self { + static func textToSpeech(_ text: String) -> Self { .init(input: text, kind: .textToSpeech(.lift)) } } diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Options.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Options.swift index b26b75d33e..a8f28ed6c2 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Options.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Options.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Convert.TranslateText { - public struct Options { +public extension Predictions.Convert.TranslateText { + struct Options { /// The default NetworkPolicy for the operation. The default value will be `auto`. public let defaultNetworkPolicy: DefaultNetworkPolicy diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Request.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Request.swift index e8832751e5..2f8080ef27 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Request.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Request.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Convert.TranslateText { - public struct Request { +public extension Predictions.Convert.TranslateText { + struct Request { /// The text to translate. public let textToTranslate: String diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Result.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Result.swift index 920eff83ba..ed49a4fb06 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Result.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText+Result.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Convert.TranslateText { +public extension Predictions.Convert.TranslateText { /// Results are mapped to TranslateTextResult when convert() API is /// called to translate a text into another language - public struct Result { + struct Result { /// Translated text public let text: String diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText.swift b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText.swift index 572bb3c46c..22554b8e42 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert+TranslateText.swift @@ -7,16 +7,16 @@ import Foundation -extension Predictions.Convert { - public enum TranslateText {} +public extension Predictions.Convert { + enum TranslateText {} } -extension Predictions.Convert.Request where +public extension Predictions.Convert.Request where Input == (String, Predictions.Language?, Predictions.Language?), Options == Predictions.Convert.TranslateText.Options, Output == Predictions.Convert.TranslateText.Result { - public static func translateText( + static func translateText( _ text: String, from: Predictions.Language? = nil, to: Predictions.Language? = nil diff --git a/Amplify/Categories/Predictions/Request/Convert/Convert.swift b/Amplify/Categories/Predictions/Request/Convert/Convert.swift index 019bf95255..4f69f8682a 100644 --- a/Amplify/Categories/Predictions/Request/Convert/Convert.swift +++ b/Amplify/Categories/Predictions/Request/Convert/Convert.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions { - public enum Convert { +public extension Predictions { + enum Convert { public struct Request { public let input: Input @_spi(PredictionsConvertRequestKind) @@ -17,32 +17,32 @@ extension Predictions { } } -extension Predictions.Convert.Request { +public extension Predictions.Convert.Request { @_spi(PredictionsConvertRequestKind) - public enum Kind { + enum Kind { public typealias BidirectionalLift = ((T) -> U, (U) -> T) case textToSpeech( Lift< - String, Input, - Predictions.Convert.TextToSpeech.Options?, Options?, - Predictions.Convert.TextToSpeech.Result, Output + String, Input, + Predictions.Convert.TextToSpeech.Options?, Options?, + Predictions.Convert.TextToSpeech.Result, Output > ) case speechToText( Lift< - URL, Input, - Predictions.Convert.SpeechToText.Options?, Options?, - AsyncThrowingStream, Output + URL, Input, + Predictions.Convert.SpeechToText.Options?, Options?, + AsyncThrowingStream, Output > ) case textToTranslate( Lift< - (String, Predictions.Language?, Predictions.Language?), Input, - Predictions.Convert.TranslateText.Options?, Options?, - Predictions.Convert.TranslateText.Result, Output + (String, Predictions.Language?, Predictions.Language?), Input, + Predictions.Convert.TranslateText.Options?, Options?, + Predictions.Convert.TranslateText.Result, Output > ) } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities+Result.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities+Result.swift index 8da0888ba6..77d3a23747 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities+Result.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities+Result.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Identify.Celebrities { +public extension Predictions.Identify.Celebrities { /// Results are mapped to IdentifyCelebritiesResult when .detectCelebrity in passed in the type: field /// in identify() API - public struct Result { + struct Result { public let celebrities: [Predictions.Celebrity] public init(celebrities: [Predictions.Celebrity]) { diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities.swift index 05cf69b606..375c2333b4 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Celebrities.swift @@ -7,12 +7,12 @@ import Foundation -extension Predictions.Identify { - public enum Celebrities {} +public extension Predictions.Identify { + enum Celebrities {} } -extension Predictions.Identify.Request where Output == Predictions.Identify.Celebrities.Result { - public static let celebrities = Self( +public extension Predictions.Identify.Request where Output == Predictions.Identify.Celebrities.Result { + static let celebrities = Self( kind: .detectCelebrities(.lift) ) } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Document.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Document.swift index d8217fdc6a..8137ab7693 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Document.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Document.swift @@ -7,12 +7,12 @@ import Foundation -extension Predictions.Identify { - public enum DocumentText {} +public extension Predictions.Identify { + enum DocumentText {} } -extension Predictions.Identify.Request where Output == Predictions.Identify.DocumentText.Result { - public static func textInDocument(textFormatType: Predictions.TextFormatType) -> Self { +public extension Predictions.Identify.Request where Output == Predictions.Identify.DocumentText.Result { + static func textInDocument(textFormatType: Predictions.TextFormatType) -> Self { .init(kind: .detectTextInDocument(textFormatType, .lift)) } } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+DocumentText+Result.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+DocumentText+Result.swift index 430667429a..bc7a4b6686 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+DocumentText+Result.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+DocumentText+Result.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Identify.DocumentText { +public extension Predictions.Identify.DocumentText { /// Results are mapped to IdentifyDocumentTextResult when .form, .table /// or .all is passed for .detectText in the type: field /// in identify() API - public struct Result { + struct Result { public let fullText: String public let words: [Predictions.IdentifiedWord] public let rawLineText: [String] diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Entities+Result.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Entities+Result.swift index ba7d2041ea..e90d6d26a3 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Entities+Result.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Entities+Result.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Identify.Entities { +public extension Predictions.Identify.Entities { /// Results are mapped to IdentifyEntitiesResult when .detectEntities is /// passed to type: field in identify() API and general entities like facial features, landmarks etc. /// are needed to be detected - public struct Result { + struct Result { /// List of 'Entity' as a result of Identify query public let entities: [Predictions.Entity] diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Entities.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Entities.swift index ad2fe77840..86f9e22e03 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Entities.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Entities.swift @@ -7,12 +7,12 @@ import Foundation -extension Predictions.Identify { - public enum Entities {} +public extension Predictions.Identify { + enum Entities {} } -extension Predictions.Identify.Request where Output == Predictions.Identify.Entities.Result { - public static let entities = Self( +public extension Predictions.Identify.Request where Output == Predictions.Identify.Entities.Result { + static let entities = Self( kind: .detectEntities(.lift) ) } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches+Result.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches+Result.swift index 57878acea0..d2e19ff011 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches+Result.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches+Result.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Identify.EntityMatches { +public extension Predictions.Identify.EntityMatches { /// Results are mapped to IdentifyEntityMatchesResult when .detectEntities is /// passed to type: field in identify() API and matches from your Rekognition Collection /// need to be identified - public struct Result { + struct Result { /// List of matched `Entity.Match` public let entities: [Predictions.Entity.Match] diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches.swift index c31b8f1ed8..4f03705d68 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+EntityMatches.swift @@ -7,12 +7,12 @@ import Foundation -extension Predictions.Identify { - public enum EntityMatches {} +public extension Predictions.Identify { + enum EntityMatches {} } -extension Predictions.Identify.Request where Output == Predictions.Identify.EntityMatches.Result { - public static func entitiesFromCollection(withID collectionID: String) -> Self { +public extension Predictions.Identify.Request where Output == Predictions.Identify.EntityMatches.Result { + static func entitiesFromCollection(withID collectionID: String) -> Self { .init(kind: .detectEntitiesCollection(collectionID, .lift)) } } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Labels+Result.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Labels+Result.swift index 245a2f14da..b5eb9e4e8d 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Labels+Result.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Labels+Result.swift @@ -7,10 +7,10 @@ import CoreGraphics -extension Predictions.Identify.Labels { +public extension Predictions.Identify.Labels { /// Results are mapped to IdentifyLabelsResult when .labels in passed to .detectLabels /// in the type: field in identify() API - public struct Result { + struct Result { public let labels: [Predictions.Label] public let unsafeContent: Bool? @@ -21,9 +21,9 @@ extension Predictions.Identify.Labels { } } -extension Predictions { +public extension Predictions { /// Describes a real world object (e.g., chair, desk) identified in an image - public struct Label { + struct Label { public let name: String public let metadata: Metadata? public let boundingBoxes: [CGRect]? @@ -39,7 +39,7 @@ extension Predictions { } } - public struct Parent { + struct Parent { public let name: String public init(name: String) { @@ -48,8 +48,8 @@ extension Predictions { } } -extension Predictions.Label { - public struct Metadata { +public extension Predictions.Label { + struct Metadata { public let confidence: Double public let parents: [Predictions.Parent]? diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Labels.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Labels.swift index 51698b50b9..a3724c9a27 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Labels.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Labels.swift @@ -7,12 +7,12 @@ import Foundation -extension Predictions.Identify { - public enum Labels {} +public extension Predictions.Identify { + enum Labels {} } -extension Predictions.Identify.Request where Output == Predictions.Identify.Labels.Result { - public static func labels(type: Predictions.LabelType = .labels) -> Self { +public extension Predictions.Identify.Request where Output == Predictions.Identify.Labels.Result { + static func labels(type: Predictions.LabelType = .labels) -> Self { .init(kind: .detectLabels(type, .lift)) } } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Lift.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Lift.swift index 09654ba367..a6cb98736f 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Lift.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Lift.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions.Identify.Request.Kind { - public struct Lift< +public extension Predictions.Identify.Request.Kind { + struct Lift< SpecificOutput, GenericOutput > { diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Text+Result.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Text+Result.swift index 39f66964a0..1bfb2858e5 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Text+Result.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Text+Result.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Identify.Text { +public extension Predictions.Identify.Text { /// Results are mapped to IdentifyTextResult when .plain is passed for .detectText in the type: field /// in identify() API - public struct Result { + struct Result { public let fullText: String? public let words: [Predictions.IdentifiedWord]? public let rawLineText: [String]? diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify+Text.swift b/Amplify/Categories/Predictions/Request/Identify/Identify+Text.swift index 4db181e3bf..c0f5d4e0ee 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify+Text.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify+Text.swift @@ -7,12 +7,12 @@ import Foundation -extension Predictions.Identify { - public enum Text {} +public extension Predictions.Identify { + enum Text {} } -extension Predictions.Identify.Request where Output == Predictions.Identify.Text.Result { - public static let text = Self( +public extension Predictions.Identify.Request where Output == Predictions.Identify.Text.Result { + static let text = Self( kind: .detectText(.lift) ) } diff --git a/Amplify/Categories/Predictions/Request/Identify/Identify.swift b/Amplify/Categories/Predictions/Request/Identify/Identify.swift index d033b26965..cacd204ae5 100644 --- a/Amplify/Categories/Predictions/Request/Identify/Identify.swift +++ b/Amplify/Categories/Predictions/Request/Identify/Identify.swift @@ -9,8 +9,8 @@ import Foundation /// Identification criteria provided to /// type parameter in identify() API -extension Predictions { - public enum Identify { +public extension Predictions { + enum Identify { public struct Request { @_spi(PredictionsIdentifyRequestKind) public let kind: Kind @@ -37,9 +37,9 @@ extension Predictions { } } -extension Predictions.Identify.Request { +public extension Predictions.Identify.Request { @_spi(PredictionsIdentifyRequestKind) - public enum Kind { + enum Kind { public typealias Lifting = ((T) -> Output, (Output) -> T) case detectCelebrities( diff --git a/Amplify/Categories/Predictions/Request/Interpret/Interpret+Result.swift b/Amplify/Categories/Predictions/Request/Interpret/Interpret+Result.swift index 127cdc41a5..9da7d8b2a1 100644 --- a/Amplify/Categories/Predictions/Request/Interpret/Interpret+Result.swift +++ b/Amplify/Categories/Predictions/Request/Interpret/Interpret+Result.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Predictions.Interpret { - public struct Result { +public extension Predictions.Interpret { + struct Result { public let keyPhrases: [Predictions.KeyPhrase]? public let sentiment: Predictions.Sentiment? public let entities: [Predictions.Entity.DetectionResult]? diff --git a/Amplify/Categories/Predictions/Request/Interpret/Interpret.swift b/Amplify/Categories/Predictions/Request/Interpret/Interpret.swift index fddb1095d6..0973f21c6d 100644 --- a/Amplify/Categories/Predictions/Request/Interpret/Interpret.swift +++ b/Amplify/Categories/Predictions/Request/Interpret/Interpret.swift @@ -7,8 +7,8 @@ import Foundation -extension Predictions { - public enum Interpret {} +public extension Predictions { + enum Interpret {} } public extension Predictions.Interpret { @@ -21,8 +21,10 @@ public extension Predictions.Interpret { /// key/values public let pluginOptions: Any? - public init(defaultNetworkPolicy: DefaultNetworkPolicy = .auto, - pluginOptions: Any? = nil) { + public init( + defaultNetworkPolicy: DefaultNetworkPolicy = .auto, + pluginOptions: Any? = nil + ) { self.defaultNetworkPolicy = defaultNetworkPolicy self.pluginOptions = pluginOptions } diff --git a/Amplify/Categories/Storage/Operation/Request/StorageDownloadDataRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageDownloadDataRequest.swift index 1a8ed260b9..9320bec9b6 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageDownloadDataRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageDownloadDataRequest.swift @@ -17,7 +17,7 @@ public struct StorageDownloadDataRequest: AmplifyOperationRequest { /// /// - Tag: StorageDownloadFileRequest.path public let path: (any StoragePath)? - + /// The unique identifier for the object in storage /// /// - Tag: StorageDownloadDataRequest.key @@ -91,9 +91,11 @@ public extension StorageDownloadDataRequest { /// /// - Tag: StorageDownloadDataRequestOptions.init @available(*, deprecated, message: "Use init(pluginOptions)") - public init(accessLevel: StorageAccessLevel = .guest, - targetIdentityId: String? = nil, - pluginOptions: Any? = nil) { + public init( + accessLevel: StorageAccessLevel = .guest, + targetIdentityId: String? = nil, + pluginOptions: Any? = nil + ) { self.accessLevel = accessLevel self.targetIdentityId = targetIdentityId self.pluginOptions = pluginOptions diff --git a/Amplify/Categories/Storage/Operation/Request/StorageDownloadFileRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageDownloadFileRequest.swift index 7ec34c222f..e225695dd5 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageDownloadFileRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageDownloadFileRequest.swift @@ -80,9 +80,11 @@ public extension StorageDownloadFileRequest { /// - Tag: StorageDownloadFileRequestOptions.init @available(*, deprecated, message: "Use init(pluginOptions)") - public init(accessLevel: StorageAccessLevel = .guest, - targetIdentityId: String? = nil, - pluginOptions: Any? = nil) { + public init( + accessLevel: StorageAccessLevel = .guest, + targetIdentityId: String? = nil, + pluginOptions: Any? = nil + ) { self.accessLevel = accessLevel self.targetIdentityId = targetIdentityId self.pluginOptions = pluginOptions diff --git a/Amplify/Categories/Storage/Operation/Request/StorageGetURLRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageGetURLRequest.swift index e8ffd22c00..81cf116526 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageGetURLRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageGetURLRequest.swift @@ -84,10 +84,12 @@ public extension StorageGetURLRequest { /// - Tag: StorageGetURLRequest.Options.init @available(*, deprecated, message: "Use init(expires:pluginOptions)") - public init(accessLevel: StorageAccessLevel = .guest, - targetIdentityId: String? = nil, - expires: Int = Options.defaultExpireInSeconds, - pluginOptions: Any? = nil) { + public init( + accessLevel: StorageAccessLevel = .guest, + targetIdentityId: String? = nil, + expires: Int = Options.defaultExpireInSeconds, + pluginOptions: Any? = nil + ) { self.accessLevel = accessLevel self.targetIdentityId = targetIdentityId self.expires = expires @@ -95,8 +97,10 @@ public extension StorageGetURLRequest { } /// - Tag: StorageGetURLRequest.Options.init - public init(expires: Int = Options.defaultExpireInSeconds, - pluginOptions: Any? = nil) { + public init( + expires: Int = Options.defaultExpireInSeconds, + pluginOptions: Any? = nil + ) { self.expires = expires self.pluginOptions = pluginOptions self.accessLevel = .guest diff --git a/Amplify/Categories/Storage/Operation/Request/StorageListRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageListRequest.swift index 71119f71f8..3a729152b4 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageListRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageListRequest.swift @@ -96,13 +96,15 @@ public extension StorageListRequest { public let pluginOptions: Any? /// - Tag: StorageListRequestOptions.init - public init(accessLevel: StorageAccessLevel = .guest, - targetIdentityId: String? = nil, - path: String? = nil, - subpathStrategy: SubpathStrategy = .include, - pageSize: UInt = 1000, - nextToken: String? = nil, - pluginOptions: Any? = nil) { + public init( + accessLevel: StorageAccessLevel = .guest, + targetIdentityId: String? = nil, + path: String? = nil, + subpathStrategy: SubpathStrategy = .include, + pageSize: UInt = 1_000, + nextToken: String? = nil, + pluginOptions: Any? = nil + ) { self.accessLevel = accessLevel self.targetIdentityId = targetIdentityId self.path = path diff --git a/Amplify/Categories/Storage/Operation/Request/StorageRemoveRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageRemoveRequest.swift index 31ae1de4f3..df2ef4e551 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageRemoveRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageRemoveRequest.swift @@ -64,8 +64,10 @@ public extension StorageRemoveRequest { public let pluginOptions: Any? /// - Tag: StorageRemoveRequestOptions.init - public init(accessLevel: StorageAccessLevel = .guest, - pluginOptions: Any? = nil) { + public init( + accessLevel: StorageAccessLevel = .guest, + pluginOptions: Any? = nil + ) { self.accessLevel = accessLevel self.pluginOptions = pluginOptions } diff --git a/Amplify/Categories/Storage/Operation/Request/StorageUploadDataRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageUploadDataRequest.swift index 572b160bf8..b9eaffe901 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageUploadDataRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageUploadDataRequest.swift @@ -89,11 +89,12 @@ public extension StorageUploadDataRequest { /// - Tag: StorageUploadDataRequestOptions.init @available(*, deprecated, message: "Use init(metadata:contentType:options)") - public init(accessLevel: StorageAccessLevel = .guest, - targetIdentityId: String? = nil, - metadata: [String: String]? = nil, - contentType: String? = nil, - pluginOptions: Any? = nil + public init( + accessLevel: StorageAccessLevel = .guest, + targetIdentityId: String? = nil, + metadata: [String: String]? = nil, + contentType: String? = nil, + pluginOptions: Any? = nil ) { self.accessLevel = accessLevel self.targetIdentityId = targetIdentityId @@ -103,9 +104,10 @@ public extension StorageUploadDataRequest { } /// - Tag: StorageUploadDataRequestOptions.init - public init(metadata: [String: String]? = nil, - contentType: String? = nil, - pluginOptions: Any? = nil + public init( + metadata: [String: String]? = nil, + contentType: String? = nil, + pluginOptions: Any? = nil ) { self.accessLevel = .guest self.targetIdentityId = nil diff --git a/Amplify/Categories/Storage/Operation/Request/StorageUploadFileRequest.swift b/Amplify/Categories/Storage/Operation/Request/StorageUploadFileRequest.swift index 23c8d159f6..cbda211924 100644 --- a/Amplify/Categories/Storage/Operation/Request/StorageUploadFileRequest.swift +++ b/Amplify/Categories/Storage/Operation/Request/StorageUploadFileRequest.swift @@ -86,11 +86,12 @@ public extension StorageUploadFileRequest { /// - Tag: StorageUploadFileRequestOptions.init @available(*, deprecated, message: "Use init(metadata:contentType:pluginOptions)") - public init(accessLevel: StorageAccessLevel = .guest, - targetIdentityId: String? = nil, - metadata: [String: String]? = nil, - contentType: String? = nil, - pluginOptions: Any? = nil + public init( + accessLevel: StorageAccessLevel = .guest, + targetIdentityId: String? = nil, + metadata: [String: String]? = nil, + contentType: String? = nil, + pluginOptions: Any? = nil ) { self.accessLevel = accessLevel self.targetIdentityId = targetIdentityId @@ -100,9 +101,10 @@ public extension StorageUploadFileRequest { } /// - Tag: StorageUploadFileRequestOptions.init - public init(metadata: [String: String]? = nil, - contentType: String? = nil, - pluginOptions: Any? = nil + public init( + metadata: [String: String]? = nil, + contentType: String? = nil, + pluginOptions: Any? = nil ) { self.accessLevel = .guest self.targetIdentityId = nil diff --git a/Amplify/Categories/Storage/Operation/StorageDownloadDataOperation.swift b/Amplify/Categories/Storage/Operation/StorageDownloadDataOperation.swift index ed608da6de..a6d0880936 100644 --- a/Amplify/Categories/Storage/Operation/StorageDownloadDataOperation.swift +++ b/Amplify/Categories/Storage/Operation/StorageDownloadDataOperation.swift @@ -21,7 +21,9 @@ public extension HubPayload.EventName.Storage { } /// - Tag: StorageDownloadDataTask -public typealias StorageDownloadDataTask = AmplifyInProcessReportingOperationTaskAdapter +public typealias StorageDownloadDataTask = AmplifyInProcessReportingOperationTaskAdapter< + StorageDownloadDataRequest, + Progress, + Data, + StorageError +> diff --git a/Amplify/Categories/Storage/Operation/StorageDownloadFileOperation.swift b/Amplify/Categories/Storage/Operation/StorageDownloadFileOperation.swift index 7d896219dc..8dcfd719ed 100644 --- a/Amplify/Categories/Storage/Operation/StorageDownloadFileOperation.swift +++ b/Amplify/Categories/Storage/Operation/StorageDownloadFileOperation.swift @@ -31,7 +31,9 @@ public extension HubPayload.EventName.Storage { } /// - Tag: StorageDownloadFileTask -public typealias StorageDownloadFileTask = AmplifyInProcessReportingOperationTaskAdapter +public typealias StorageDownloadFileTask = AmplifyInProcessReportingOperationTaskAdapter< + StorageDownloadFileRequest, + Progress, + Void, + StorageError +> diff --git a/Amplify/Categories/Storage/Operation/StorageUploadDataOperation.swift b/Amplify/Categories/Storage/Operation/StorageUploadDataOperation.swift index 5f9fed049f..2bd1de2baf 100644 --- a/Amplify/Categories/Storage/Operation/StorageUploadDataOperation.swift +++ b/Amplify/Categories/Storage/Operation/StorageUploadDataOperation.swift @@ -21,7 +21,9 @@ public extension HubPayload.EventName.Storage { } /// - Tag: StorageUploadDataTask -public typealias StorageUploadDataTask = AmplifyInProcessReportingOperationTaskAdapter +public typealias StorageUploadDataTask = AmplifyInProcessReportingOperationTaskAdapter< + StorageUploadDataRequest, + Progress, + String, + StorageError +> diff --git a/Amplify/Categories/Storage/Operation/StorageUploadFileOperation.swift b/Amplify/Categories/Storage/Operation/StorageUploadFileOperation.swift index 35d62df864..1fb07189cc 100644 --- a/Amplify/Categories/Storage/Operation/StorageUploadFileOperation.swift +++ b/Amplify/Categories/Storage/Operation/StorageUploadFileOperation.swift @@ -21,7 +21,9 @@ public extension HubPayload.EventName.Storage { } /// - Tag: StorageUploadFileTask -public typealias StorageUploadFileTask = AmplifyInProcessReportingOperationTaskAdapter +public typealias StorageUploadFileTask = AmplifyInProcessReportingOperationTaskAdapter< + StorageUploadFileRequest, + Progress, + String, + StorageError +> diff --git a/Amplify/Categories/Storage/Result/StorageListResult.swift b/Amplify/Categories/Storage/Result/StorageListResult.swift index 1adee4ea08..2425bba4d6 100644 --- a/Amplify/Categories/Storage/Result/StorageListResult.swift +++ b/Amplify/Categories/Storage/Result/StorageListResult.swift @@ -33,7 +33,7 @@ public struct StorageListResult { public var items: [Item] - /// Array of excluded subpaths in the Result. + /// Array of excluded subpaths in the Result. /// This field is only populated when [`StorageListRequest.Options.subpathStrategy`](x-source-tag://StorageListRequestOptions.subpathStragegy) is set to [`.exclude()`](x-source-tag://SubpathStrategy.exclude). /// /// - Tag: StorageListResult.excludedSubpaths @@ -49,10 +49,10 @@ public struct StorageListResult { public let nextToken: String? } -extension StorageListResult { +public extension StorageListResult { /// - Tag: StorageListResultItem - public struct Item { + struct Item { /// The path of the object in storage. /// diff --git a/Amplify/Categories/Storage/StorageCategory.swift b/Amplify/Categories/Storage/StorageCategory.swift index 919b127a0c..d8f45d56e6 100644 --- a/Amplify/Categories/Storage/StorageCategory.swift +++ b/Amplify/Categories/Storage/StorageCategory.swift @@ -7,9 +7,9 @@ /// AWS Amplify Storage module provides a simple mechanism for managing user content for your app in public, protected /// or private storage buckets. -/// +/// /// - Tag: StorageCategory -final public class StorageCategory: Category { +public final class StorageCategory: Category { public let categoryType = CategoryType.storage var plugins = [PluginKey: StorageCategoryPlugin]() @@ -54,8 +54,10 @@ final public class StorageCategory: Category { let key = plugin.key guard !key.isEmpty else { let pluginDescription = String(describing: plugin) - let error = StorageError.configuration("Plugin \(pluginDescription) has an empty `key`.", - "Set the `key` property for \(String(describing: plugin))") + let error = StorageError.configuration( + "Plugin \(pluginDescription) has an empty `key`.", + "Set the `key` property for \(String(describing: plugin))" + ) throw error } @@ -78,8 +80,10 @@ final public class StorageCategory: Category { public func getPlugin(for key: PluginKey) throws -> StorageCategoryPlugin { guard let plugin = plugins[key] else { let keys = plugins.keys.joined(separator: ", ") - let error = StorageError.configuration("No plugin has been added for '\(key)'.", - "Either add a plugin for '\(key)', or use one of the known keys: \(keys)") + let error = StorageError.configuration( + "No plugin has been added for '\(key)'.", + "Either add a plugin for '\(key)', or use one of the known keys: \(keys)" + ) throw error } return plugin diff --git a/Amplify/Categories/Storage/StorageCategoryBehavior.swift b/Amplify/Categories/Storage/StorageCategoryBehavior.swift index 0b933d4dfc..125a5baff4 100644 --- a/Amplify/Categories/Storage/StorageCategoryBehavior.swift +++ b/Amplify/Categories/Storage/StorageCategoryBehavior.swift @@ -53,8 +53,10 @@ public protocol StorageCategoryBehavior { /// - Tag: StorageCategoryBehavior.downloadData @available(*, deprecated, message: "Use downloadData(path:options:)") @discardableResult - func downloadData(key: String, - options: StorageDownloadDataOperation.Request.Options?) -> StorageDownloadDataTask + func downloadData( + key: String, + options: StorageDownloadDataOperation.Request.Options? + ) -> StorageDownloadDataTask /// Retrieve the object from storage into memory. /// diff --git a/Amplify/Core/Configuration/AmplifyConfiguration.swift b/Amplify/Core/Configuration/AmplifyConfiguration.swift index 2cb769f981..aacfea1483 100644 --- a/Amplify/Core/Configuration/AmplifyConfiguration.swift +++ b/Amplify/Core/Configuration/AmplifyConfiguration.swift @@ -57,16 +57,18 @@ public struct AmplifyConfiguration: Codable { let storage: StorageCategoryConfiguration? /// - Tag: Amplify.init - public init(analytics: AnalyticsCategoryConfiguration? = nil, - api: APICategoryConfiguration? = nil, - auth: AuthCategoryConfiguration? = nil, - dataStore: DataStoreCategoryConfiguration? = nil, - geo: GeoCategoryConfiguration? = nil, - hub: HubCategoryConfiguration? = nil, - logging: LoggingCategoryConfiguration? = nil, - notifications: NotificationsCategoryConfiguration? = nil, - predictions: PredictionsCategoryConfiguration? = nil, - storage: StorageCategoryConfiguration? = nil) { + public init( + analytics: AnalyticsCategoryConfiguration? = nil, + api: APICategoryConfiguration? = nil, + auth: AuthCategoryConfiguration? = nil, + dataStore: DataStoreCategoryConfiguration? = nil, + geo: GeoCategoryConfiguration? = nil, + hub: HubCategoryConfiguration? = nil, + logging: LoggingCategoryConfiguration? = nil, + notifications: NotificationsCategoryConfiguration? = nil, + predictions: PredictionsCategoryConfiguration? = nil, + storage: StorageCategoryConfiguration? = nil + ) { self.analytics = analytics self.api = api self.auth = auth diff --git a/Amplify/Core/Configuration/AmplifyOutputsData.swift b/Amplify/Core/Configuration/AmplifyOutputsData.swift index 93a2f60e6a..507f730cf4 100644 --- a/Amplify/Core/Configuration/AmplifyOutputsData.swift +++ b/Amplify/Core/Configuration/AmplifyOutputsData.swift @@ -75,28 +75,30 @@ public struct AmplifyOutputsData: Codable { @_spi(InternalAmplifyConfiguration) public enum UsernameAttributes: String, Codable { - case email = "email" + case email case phoneNumber = "phone_number" } @_spi(InternalAmplifyConfiguration) public enum UserVerificationType: String, Codable { - case email = "email" + case email case phoneNumber = "phone_number" } - init(awsRegion: AWSRegion, - userPoolId: String, - userPoolClientId: String, - identityPoolId: String? = nil, - passwordPolicy: PasswordPolicy? = nil, - oauth: OAuth? = nil, - standardRequiredAttributes: [AmazonCognitoStandardAttributes]? = nil, - usernameAttributes: [UsernameAttributes]? = nil, - userVerificationTypes: [UserVerificationType]? = nil, - unauthenticatedIdentitiesEnabled: Bool? = nil, - mfaConfiguration: String? = nil, - mfaMethods: [String]? = nil) { + init( + awsRegion: AWSRegion, + userPoolId: String, + userPoolClientId: String, + identityPoolId: String? = nil, + passwordPolicy: PasswordPolicy? = nil, + oauth: OAuth? = nil, + standardRequiredAttributes: [AmazonCognitoStandardAttributes]? = nil, + usernameAttributes: [UsernameAttributes]? = nil, + userVerificationTypes: [UserVerificationType]? = nil, + unauthenticatedIdentitiesEnabled: Bool? = nil, + mfaConfiguration: String? = nil, + mfaMethods: [String]? = nil + ) { self.awsRegion = awsRegion self.userPoolId = userPoolId self.userPoolClientId = userPoolClientId @@ -154,10 +156,12 @@ public struct AmplifyOutputsData: Codable { } // Internal init used for testing - init(awsRegion: AWSRegion, - maps: Maps? = nil, - searchIndices: SearchIndices? = nil, - geofenceCollections: GeofenceCollections? = nil) { + init( + awsRegion: AWSRegion, + maps: Maps? = nil, + searchIndices: SearchIndices? = nil, + geofenceCollections: GeofenceCollections? = nil + ) { self.awsRegion = awsRegion self.maps = maps self.searchIndices = searchIndices @@ -225,14 +229,16 @@ public struct AmplifyOutputsData: Codable { } // Internal init used for testing - init(version: String = "", - analytics: Analytics? = nil, - auth: Auth? = nil, - data: DataCategory? = nil, - geo: Geo? = nil, - notifications: Notifications? = nil, - storage: Storage? = nil, - custom: CustomOutput? = nil) { + init( + version: String = "", + analytics: Analytics? = nil, + auth: Auth? = nil, + data: DataCategory? = nil, + geo: Geo? = nil, + notifications: Notifications? = nil, + storage: Storage? = nil, + custom: CustomOutput? = nil + ) { self.version = version self.analytics = analytics self.auth = auth @@ -254,11 +260,9 @@ public struct AmplifyOutputs { let resolveConfiguration: () throws -> AmplifyOutputsData /// Resolves configuration with `amplify_outputs.json` in the main bundle. - public static let amplifyOutputs: AmplifyOutputs = { - .init { + public static let amplifyOutputs: AmplifyOutputs = .init { try AmplifyOutputsData(bundle: Bundle.main, resource: "amplify_outputs") } - }() /// Resolves configuration with a data object, from the contents of an `amplify_outputs.json` file. public static func data(_ data: Data) -> AmplifyOutputs { @@ -275,12 +279,12 @@ public struct AmplifyOutputs { } } -extension Amplify { +public extension Amplify { /// API to configure with Amplify CLI Gen2's configuration. /// /// - Parameter with: `AmplifyOutputs` configuration resolver - public static func configure(with amplifyOutputs: AmplifyOutputs) throws { + static func configure(with amplifyOutputs: AmplifyOutputs) throws { do { let resolvedConfiguration = try amplifyOutputs.resolveConfiguration() try configure(resolvedConfiguration) @@ -313,7 +317,7 @@ extension Amplify { /// /// - Tag: Amplify.configure @_spi(InternalAmplifyConfiguration) - public static func configure(_ configuration: AmplifyOutputsData) throws { + static func configure(_ configuration: AmplifyOutputsData) throws { // Always configure logging first since Auth dependings on logging try configure(CategoryType.logging.category, using: configuration) diff --git a/Amplify/Core/Configuration/ConfigurationError.swift b/Amplify/Core/Configuration/ConfigurationError.swift index 36d7d7abab..52ccf00ad9 100644 --- a/Amplify/Core/Configuration/ConfigurationError.swift +++ b/Amplify/Core/Configuration/ConfigurationError.swift @@ -8,7 +8,7 @@ /// Errors associated with configuring and inspecting Amplify Categories /// /// See: [Amplify.configure](x-source-tag://Amplify.configure) -/// +/// /// - Tag: ConfigurationError public enum ConfigurationError { /// The client issued a subsequent call to `Amplify.configure` after the first had already succeeded diff --git a/Amplify/Core/Configuration/Internal/Amplify+Resolve.swift b/Amplify/Core/Configuration/Internal/Amplify+Resolve.swift index 43e2f7cc4b..021ddd963a 100644 --- a/Amplify/Core/Configuration/Internal/Amplify+Resolve.swift +++ b/Amplify/Core/Configuration/Internal/Amplify+Resolve.swift @@ -10,7 +10,7 @@ import Foundation extension Amplify { static func resolve(configuration: AmplifyConfiguration? = nil) throws -> AmplifyConfiguration { - if let configuration = configuration { + if let configuration { return configuration } diff --git a/Amplify/Core/Model/BasicUserProfile.swift b/Amplify/Core/Model/BasicUserProfile.swift index 5d6227c122..9b841429a0 100644 --- a/Amplify/Core/Model/BasicUserProfile.swift +++ b/Amplify/Core/Model/BasicUserProfile.swift @@ -26,11 +26,13 @@ public struct BasicUserProfile: UserProfile { /// - plan: The plan for the user /// - location: Location data about the user /// - customProperties: Properties of the user profile - public init(name: String? = nil, - email: String? = nil, - plan: String? = nil, - location: UserProfileLocation? = nil, - customProperties: [String: UserProfilePropertyValue]? = nil) { + public init( + name: String? = nil, + email: String? = nil, + plan: String? = nil, + location: UserProfileLocation? = nil, + customProperties: [String: UserProfilePropertyValue]? = nil + ) { self.name = name self.email = email self.plan = plan diff --git a/Amplify/Core/Model/UserProfile.swift b/Amplify/Core/Model/UserProfile.swift index 307f045d82..476737369b 100644 --- a/Amplify/Core/Model/UserProfile.swift +++ b/Amplify/Core/Model/UserProfile.swift @@ -54,12 +54,14 @@ public struct UserProfileLocation { /// - city: The user's city /// - region: The user's region /// - country: The user's country - public init(latitude: Double? = nil, - longitude: Double? = nil, - postalCode: String? = nil, - city: String? = nil, - region: String? = nil, - country: String? = nil) { + public init( + latitude: Double? = nil, + longitude: Double? = nil, + postalCode: String? = nil, + city: String? = nil, + region: String? = nil, + country: String? = nil + ) { self.latitude = latitude self.longitude = longitude self.postalCode = postalCode diff --git a/Amplify/Core/Model/UserProfilePropertyValue.swift b/Amplify/Core/Model/UserProfilePropertyValue.swift index 0a992a12eb..f3a4dbe77d 100644 --- a/Amplify/Core/Model/UserProfilePropertyValue.swift +++ b/Amplify/Core/Model/UserProfilePropertyValue.swift @@ -20,4 +20,4 @@ extension String: UserProfilePropertyValue {} extension Int: UserProfilePropertyValue {} extension Double: UserProfilePropertyValue {} extension Bool: UserProfilePropertyValue {} -extension Array: UserProfilePropertyValue where Element == String {} +extension [String]: UserProfilePropertyValue {} diff --git a/Amplify/Core/Support/AccessLevel.swift b/Amplify/Core/Support/AccessLevel.swift index 8e2123e350..0e8d33ce9d 100644 --- a/Amplify/Core/Support/AccessLevel.swift +++ b/Amplify/Core/Support/AccessLevel.swift @@ -6,6 +6,7 @@ // import Foundation + public enum AccessLevel: String { case `public` case protected diff --git a/Amplify/Core/Support/AmplifyAsyncSequence.swift b/Amplify/Core/Support/AmplifyAsyncSequence.swift index 0320b6c9a3..bdc1330b3f 100644 --- a/Amplify/Core/Support/AmplifyAsyncSequence.swift +++ b/Amplify/Core/Support/AmplifyAsyncSequence.swift @@ -17,10 +17,12 @@ public class AmplifyAsyncSequence: AsyncSequence, Cancellable public private(set) var isCancelled: Bool = false - public init(parent: Cancellable? = nil, - bufferingPolicy: AsyncStream.Continuation.BufferingPolicy = .unbounded) { + public init( + parent: Cancellable? = nil, + bufferingPolicy: AsyncStream.Continuation.BufferingPolicy = .unbounded + ) { self.parent = parent - (asyncStream, continuation) = AsyncStream.makeStream(of: Element.self, bufferingPolicy: bufferingPolicy) + (self.asyncStream, self.continuation) = AsyncStream.makeStream(of: Element.self, bufferingPolicy: bufferingPolicy) } public func makeAsyncIterator() -> Iterator { diff --git a/Amplify/Core/Support/AmplifyAsyncThrowingSequence.swift b/Amplify/Core/Support/AmplifyAsyncThrowingSequence.swift index 5ff7d388eb..0f6c166bee 100644 --- a/Amplify/Core/Support/AmplifyAsyncThrowingSequence.swift +++ b/Amplify/Core/Support/AmplifyAsyncThrowingSequence.swift @@ -17,10 +17,12 @@ public class AmplifyAsyncThrowingSequence: AsyncSequence, Can public private(set) var isCancelled: Bool = false - public init(parent: Cancellable? = nil, - bufferingPolicy: AsyncThrowingStream.Continuation.BufferingPolicy = .unbounded) { + public init( + parent: Cancellable? = nil, + bufferingPolicy: AsyncThrowingStream.Continuation.BufferingPolicy = .unbounded + ) { self.parent = parent - (asyncStream, continuation) = AsyncThrowingStream.makeStream(of: Element.self, bufferingPolicy: bufferingPolicy) + (self.asyncStream, self.continuation) = AsyncThrowingStream.makeStream(of: Element.self, bufferingPolicy: bufferingPolicy) } public func makeAsyncIterator() -> Iterator { diff --git a/Amplify/Core/Support/AmplifyError.swift b/Amplify/Core/Support/AmplifyError.swift index 207dbb1835..64be69825b 100644 --- a/Amplify/Core/Support/AmplifyError.swift +++ b/Amplify/Core/Support/AmplifyError.swift @@ -72,7 +72,7 @@ public extension AmplifyError { components.append("Recovery suggestion: \(recoverySuggestion)") } - if let underlyingError = underlyingError { + if let underlyingError { if let underlyingAmplifyError = underlyingError as? AmplifyError { components.append("Caused by:\n\(underlyingAmplifyError.debugDescription)") } else { diff --git a/Amplify/Core/Support/AmplifyErrorMessages.swift b/Amplify/Core/Support/AmplifyErrorMessages.swift index f6632450b8..7c3ec2cab0 100644 --- a/Amplify/Core/Support/AmplifyErrorMessages.swift +++ b/Amplify/Core/Support/AmplifyErrorMessages.swift @@ -8,11 +8,13 @@ /// Commonly used cross-category error messages. /// /// - Tag: AmplifyErrorMessages -public struct AmplifyErrorMessages { +public enum AmplifyErrorMessages { /// - Tag: AmplifyErrorMessages.reportBugToAWS - public static func reportBugToAWS(file: StaticString = #file, - function: StaticString = #function, - line: UInt = #line) -> String { + public static func reportBugToAWS( + file: StaticString = #file, + function: StaticString = #function, + line: UInt = #line + ) -> String { """ There is a possibility that there is a bug if this error persists. Please take a look at \ https://github.com/aws-amplify/amplify-ios/issues to see if there are any existing issues that \ @@ -25,9 +27,11 @@ public struct AmplifyErrorMessages { } /// - Tag: AmplifyErrorMessages.shouldNotHappenReportBugToAWS - public static func shouldNotHappenReportBugToAWS(file: StaticString = #file, - function: StaticString = #function, - line: UInt = #line) -> String { + public static func shouldNotHappenReportBugToAWS( + file: StaticString = #file, + function: StaticString = #function, + line: UInt = #line + ) -> String { "This should not happen. \(reportBugToAWS(file: file, function: function, line: line))" } diff --git a/Amplify/Core/Support/AmplifyInProcessReportingOperation+Combine.swift b/Amplify/Core/Support/AmplifyInProcessReportingOperation+Combine.swift index d2e0b44160..541369c1fe 100644 --- a/Amplify/Core/Support/AmplifyInProcessReportingOperation+Combine.swift +++ b/Amplify/Core/Support/AmplifyInProcessReportingOperation+Combine.swift @@ -6,8 +6,8 @@ // #if canImport(Combine) -import Foundation import Combine +import Foundation extension AmplifyInProcessReportingOperation { /// A Publisher that emits in-process values for an operation, or the associated diff --git a/Amplify/Core/Support/AmplifyInProcessReportingOperation.swift b/Amplify/Core/Support/AmplifyInProcessReportingOperation.swift index f77e99d932..4e218bd3f4 100644 --- a/Amplify/Core/Support/AmplifyInProcessReportingOperation.swift +++ b/Amplify/Core/Support/AmplifyInProcessReportingOperation.swift @@ -34,21 +34,23 @@ open class AmplifyInProcessReportingOperation< var inProcessSubject: PassthroughSubject! #endif - public init(categoryType: CategoryType, - eventName: HubPayloadEventName, - request: Request, - inProcessListener: InProcessListener? = nil, - resultListener: ResultListener? = nil) { + public init( + categoryType: CategoryType, + eventName: HubPayloadEventName, + request: Request, + inProcessListener: InProcessListener? = nil, + resultListener: ResultListener? = nil + ) { super.init(categoryType: categoryType, eventName: eventName, request: request, resultListener: resultListener) #if canImport(Combine) - inProcessSubject = PassthroughSubject() + self.inProcessSubject = PassthroughSubject() #endif // If the inProcessListener is present, we need to register a hub event listener for it, and ensure we // automatically unsubscribe when we receive a completion event for the operation - if let inProcessListener = inProcessListener { + if let inProcessListener { self.inProcessListenerUnsubscribeToken = subscribe(inProcessListener: inProcessListener) } } @@ -74,15 +76,17 @@ open class AmplifyInProcessReportingOperation< } } - inProcessListenerToken = Amplify.Hub.listen(to: channel, - isIncluded: filterById, - listener: inProcessHubListener) + inProcessListenerToken = Amplify.Hub.listen( + to: channel, + isIncluded: filterById, + listener: inProcessHubListener + ) return inProcessListenerToken } /// Classes that override this method must emit a completion to the `inProcessPublisher` upon cancellation - open override func cancel() { + override open func cancel() { super.cancel() #if canImport(Combine) publish(completion: .finished) @@ -94,7 +98,7 @@ open class AmplifyInProcessReportingOperation< /// /// - Parameter result: The OperationResult to dispatch to the hub as part of the /// HubPayload - public override func dispatch(result: OperationResult) { + override public func dispatch(result: OperationResult) { #if canImport(Combine) publish(completion: .finished) #endif @@ -123,7 +127,7 @@ public extension AmplifyInProcessReportingOperation { /// Removes the listener that was registered during operation instantiation func removeInProcessResultListener() { - if let inProcessListenerUnsubscribeToken = inProcessListenerUnsubscribeToken { + if let inProcessListenerUnsubscribeToken { Amplify.Hub.removeListener(inProcessListenerUnsubscribeToken) } } diff --git a/Amplify/Core/Support/AmplifyOperation+Combine.swift b/Amplify/Core/Support/AmplifyOperation+Combine.swift index 5643a32ecd..e6daa89262 100644 --- a/Amplify/Core/Support/AmplifyOperation+Combine.swift +++ b/Amplify/Core/Support/AmplifyOperation+Combine.swift @@ -6,8 +6,8 @@ // #if canImport(Combine) -import Foundation import Combine +import Foundation // Most APIs will return an operation that exposes a `resultPublisher`. The // Storage and API category methods that expose both a result and an in-process diff --git a/Amplify/Core/Support/AmplifyOperation+Hub.swift b/Amplify/Core/Support/AmplifyOperation+Hub.swift index 97636a786e..771b418052 100644 --- a/Amplify/Core/Support/AmplifyOperation+Hub.swift +++ b/Amplify/Core/Support/AmplifyOperation+Hub.swift @@ -33,7 +33,8 @@ public extension HubCategory { func listenForInProcess( to operation: AmplifyInProcessReportingOperation, inProcessListener: @escaping AmplifyInProcessReportingOperation< - Request, InProcess, Success, Failure>.InProcessListener + Request, InProcess, Success, Failure + >.InProcessListener ) -> UnsubscribeToken { return operation.subscribe(inProcessListener: inProcessListener) } diff --git a/Amplify/Core/Support/AmplifyOperation.swift b/Amplify/Core/Support/AmplifyOperation.swift index 07d122d68c..3ae670ab1a 100644 --- a/Amplify/Core/Support/AmplifyOperation.swift +++ b/Amplify/Core/Support/AmplifyOperation.swift @@ -97,10 +97,12 @@ open class AmplifyOperation { self.resultPromise = $0 } + self.resultFuture = Future { self.resultPromise = $0 } #endif - if let resultListener = resultListener { + if let resultListener { self.resultListenerUnsubscribeToken = subscribe(resultListener: resultListener) } } @@ -130,7 +132,7 @@ open class AmplifyOperation: AmplifyTask { +public class AmplifyOperationTaskAdapter< + Request: AmplifyOperationRequest, + Success, + Failure: AmplifyError +>: AmplifyTask { let operation: AmplifyOperation let childTask: ChildTask var resultToken: UnsubscribeToken? @@ -20,13 +22,13 @@ public class AmplifyOperationTaskAdapter) { self.operation = operation self.childTask = ChildTask(parent: operation) - resultToken = operation.subscribe { [weak self] in + self.resultToken = operation.subscribe { [weak self] in self?.resultListener($0) } } deinit { - if let resultToken = resultToken { + if let resultToken { Amplify.Hub.removeListener(resultToken) } } @@ -64,10 +66,12 @@ public class AmplifyOperationTaskAdapter: AmplifyTask, AmplifyInProcessReportingTask { +public class AmplifyInProcessReportingOperationTaskAdapter< + Request: AmplifyOperationRequest, + InProcess, + Success, + Failure: AmplifyError +>: AmplifyTask, AmplifyInProcessReportingTask { let operation: AmplifyInProcessReportingOperation let childTask: ChildTask var resultToken: UnsubscribeToken? @@ -76,21 +80,21 @@ public class AmplifyInProcessReportingOperationTaskAdapter) { self.operation = operation self.childTask = ChildTask(parent: operation) - resultToken = operation.subscribe(resultListener: { [weak self] result in - guard let self = self else { return } - self.resultListener(result) + self.resultToken = operation.subscribe(resultListener: { [weak self] result in + guard let self else { return } + resultListener(result) }) - inProcessToken = operation.subscribe(inProcessListener: { [weak self] inProcess in - guard let self = self else { return } - self.inProcessListener(inProcess) + self.inProcessToken = operation.subscribe(inProcessListener: { [weak self] inProcess in + guard let self else { return } + inProcessListener(inProcess) }) } deinit { - if let resultToken = resultToken { + if let resultToken { Amplify.Hub.removeListener(resultToken) } - if let inProcessToken = inProcessToken { + if let inProcessToken { Amplify.Hub.removeListener(inProcessToken) } } diff --git a/Amplify/Core/Support/AmplifyTaskExecution.swift b/Amplify/Core/Support/AmplifyTaskExecution.swift index ff73c60f26..53cadf9e12 100644 --- a/Amplify/Core/Support/AmplifyTaskExecution.swift +++ b/Amplify/Core/Support/AmplifyTaskExecution.swift @@ -4,6 +4,7 @@ // // SPDX-License-Identifier: Apache-2.0 // + import Foundation /// Task that supports hub with execution of a single unit of work. . diff --git a/Amplify/Core/Support/AmplifyTaskGateway.swift b/Amplify/Core/Support/AmplifyTaskGateway.swift index cca0a94fbc..9e7c48f714 100644 --- a/Amplify/Core/Support/AmplifyTaskGateway.swift +++ b/Amplify/Core/Support/AmplifyTaskGateway.swift @@ -74,9 +74,11 @@ extension AmplifyTaskGateway { // Automatically unsubscribe when event is received unsubscribe?() } - let token = Amplify.Hub.listen(to: channel, - isIncluded: filterById, - listener: resultHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: filterById, + listener: resultHubListener + ) unsubscribe = { Amplify.Hub.removeListener(token) } @@ -99,9 +101,11 @@ extension AmplifyTaskGateway { unsubscribe?() } } - let token = Amplify.Hub.listen(to: channel, - isIncluded: filterById, - listener: inProcessHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: filterById, + listener: inProcessHubListener + ) unsubscribe = { Amplify.Hub.removeListener(token) } diff --git a/Amplify/Core/Support/Array+Extensions.swift b/Amplify/Core/Support/Array+Extensions.swift index fbf50b0dbd..36e7999eec 100644 --- a/Amplify/Core/Support/Array+Extensions.swift +++ b/Amplify/Core/Support/Array+Extensions.swift @@ -8,8 +8,8 @@ import Foundation // Inspired from: https://www.hackingwithswift.com/example-code/language/how-to-split-an-array-into-chunks -extension Array { - public func chunked(into size: Int) -> [[Element]] { +public extension Array { + func chunked(into size: Int) -> [[Element]] { return stride(from: 0, to: count, by: size).map { Array(self[$0 ..< Swift.min($0 + size, count)]) } diff --git a/Amplify/Core/Support/AsychronousOperation.swift b/Amplify/Core/Support/AsychronousOperation.swift index 762b336e39..8d2e2cd2c3 100644 --- a/Amplify/Core/Support/AsychronousOperation.swift +++ b/Amplify/Core/Support/AsychronousOperation.swift @@ -22,8 +22,10 @@ open class AsynchronousOperation: Operation { } /// Synchronizes access to `state`. - private let stateQueue = DispatchQueue(label: "com.amazonaws.amplify.AsynchronousOperation.state", - target: DispatchQueue.global()) + private let stateQueue = DispatchQueue( + label: "com.amazonaws.amplify.AsynchronousOperation.state", + target: DispatchQueue.global() + ) /// Private backing stored property for `state`. private var _state: OperationState = .notExecuting @@ -37,22 +39,22 @@ open class AsynchronousOperation: Operation { // MARK: - Various `Operation` properties /// `true` if the operation is ready to be executed - open override var isReady: Bool { + override open var isReady: Bool { return state == .notExecuting && super.isReady } /// `true` if the operation is currently executing - public final override var isExecuting: Bool { + override public final var isExecuting: Bool { return state == .executing } /// `true` if the operation has completed executing, either successfully or with an error - public final override var isFinished: Bool { + override public final var isFinished: Bool { return state == .finished } /// KVN for dependent properties - open override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set { + override open class func keyPathsForValuesAffectingValue(forKey key: String) -> Set { if ["isReady", "isFinished", "isExecuting"].contains(key) { return [#keyPath(state)] } @@ -61,7 +63,7 @@ open class AsynchronousOperation: Operation { } /// Starts the operation - public final override func start() { + override public final func start() { if isCancelled { state = .finished return @@ -73,7 +75,7 @@ open class AsynchronousOperation: Operation { /// Subclasses must implement this to perform their work and they must not call `super`. /// The default implementation of this function throws an exception. - open override func main() { + override open func main() { fatalError("Subclasses must implement `main`.") } diff --git a/Amplify/Core/Support/AtomicDictionary.swift b/Amplify/Core/Support/AtomicDictionary.swift index fee9411e87..5bafdf4807 100644 --- a/Amplify/Core/Support/AtomicDictionary.swift +++ b/Amplify/Core/Support/AtomicDictionary.swift @@ -52,7 +52,7 @@ public final class AtomicDictionary { getValue(forKey: key) } set { - if let newValue = newValue { + if let newValue { set(value: newValue, forKey: key) } else { removeValue(forKey: key) diff --git a/Amplify/Core/Support/AtomicValue+Bool.swift b/Amplify/Core/Support/AtomicValue+Bool.swift index c8a60002c4..c80e53f175 100644 --- a/Amplify/Core/Support/AtomicValue+Bool.swift +++ b/Amplify/Core/Support/AtomicValue+Bool.swift @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 // -extension AtomicValue where Value == Bool { +public extension AtomicValue where Value == Bool { /// Toggles the boolean's value, and returns the **old** value. /// @@ -15,7 +15,7 @@ extension AtomicValue where Value == Bool { /// print(atomicBool.getAndToggle()) // prints "true" /// print(atomicBool.get()) // prints "false" /// ``` - public func getAndToggle() -> Value { + func getAndToggle() -> Value { lock.execute { let oldValue = value value.toggle() diff --git a/Amplify/Core/Support/AtomicValue+Numeric.swift b/Amplify/Core/Support/AtomicValue+Numeric.swift index a84dfc64a2..d83886aa9f 100644 --- a/Amplify/Core/Support/AtomicValue+Numeric.swift +++ b/Amplify/Core/Support/AtomicValue+Numeric.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -extension AtomicValue where Value: Numeric { +public extension AtomicValue where Value: Numeric { /// Increments the current value by `amount` and returns the incremented value - public func increment(by amount: Value = 1) -> Value { + func increment(by amount: Value = 1) -> Value { lock.execute { value += amount return value @@ -15,7 +15,7 @@ extension AtomicValue where Value: Numeric { } /// Decrements the current value by `amount` and returns the decremented value - public func decrement(by amount: Value = 1) -> Value { + func decrement(by amount: Value = 1) -> Value { lock.execute { value -= amount return value diff --git a/Amplify/Core/Support/AtomicValue+RangeReplaceableCollection.swift b/Amplify/Core/Support/AtomicValue+RangeReplaceableCollection.swift index 84396d9c96..6425cc8cfb 100644 --- a/Amplify/Core/Support/AtomicValue+RangeReplaceableCollection.swift +++ b/Amplify/Core/Support/AtomicValue+RangeReplaceableCollection.swift @@ -5,26 +5,26 @@ // SPDX-License-Identifier: Apache-2.0 // -extension AtomicValue where Value: RangeReplaceableCollection { - public func append(_ newElement: Value.Element) { +public extension AtomicValue where Value: RangeReplaceableCollection { + func append(_ newElement: Value.Element) { lock.execute { value.append(newElement) } } - public func append(contentsOf sequence: S) where S: Sequence, S.Element == Value.Element { + func append(contentsOf sequence: some Sequence) { lock.execute { value.append(contentsOf: sequence) } } - public func removeFirst() -> Value.Element { + func removeFirst() -> Value.Element { lock.execute { value.removeFirst() } } - public subscript(_ key: Value.Index) -> Value.Element { + subscript(_ key: Value.Index) -> Value.Element { lock.execute { value[key] } diff --git a/Amplify/Core/Support/Cancellable.swift b/Amplify/Core/Support/Cancellable.swift index 15f5db5b6a..8a6a0d9fae 100644 --- a/Amplify/Core/Support/Cancellable.swift +++ b/Amplify/Core/Support/Cancellable.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import _Concurrency +import Foundation /// The conforming type supports cancelling an in-process operation. The exact semantics of "canceling" are not defined /// in the protocol. Specifically, there is no guarantee that a `cancel` results in immediate cessation of activity. diff --git a/Amplify/Core/Support/ChildTask.swift b/Amplify/Core/Support/ChildTask.swift index b9fa73adad..e83022094c 100644 --- a/Amplify/Core/Support/ChildTask.swift +++ b/Amplify/Core/Support/ChildTask.swift @@ -19,7 +19,7 @@ actor ChildTask: BufferingSequence { var inProcess: AmplifyAsyncSequence { let channel: AmplifyAsyncSequence - if let inProcessChannel = inProcessChannel { + if let inProcessChannel { channel = inProcessChannel } else { channel = AmplifyAsyncSequence(bufferingPolicy: bufferingPolicy) @@ -63,7 +63,7 @@ actor ChildTask: BufferingSequence { func report(_ inProcess: InProcess?) async throws { if let channel = inProcessChannel { - if let inProcess = inProcess { + if let inProcess { channel.send(inProcess) } else { // nil indicates the sequence is done @@ -77,7 +77,7 @@ actor ChildTask: BufferingSequence { send(result) } // store result for when the value property is used - self.storedResult = result + storedResult = result if let channel = inProcessChannel { channel.finish() } diff --git a/Amplify/Core/Support/DeviceInfo.swift b/Amplify/Core/Support/DeviceInfo.swift index 86ed7ca257..5a1d4d242b 100644 --- a/Amplify/Core/Support/DeviceInfo.swift +++ b/Amplify/Core/Support/DeviceInfo.swift @@ -6,6 +6,7 @@ // import Foundation + // Note: It's important to check for WatchKit first because a stripped-down version of UIKit is also // available on watchOS #if canImport(WatchKit) @@ -34,7 +35,7 @@ public struct DeviceInfo { private init() {} /// - Tag: DeviceInfo.current - public static var current: DeviceInfo = DeviceInfo() + public static var current: DeviceInfo = .init() /// Returns the name of the host or device /// @@ -96,8 +97,10 @@ public struct DeviceInfo { let device = UIDevice.current return (name: device.systemName, version: device.systemVersion) #else - return (name: "macOS", - version: ProcessInfo.processInfo.operatingSystemVersionString) + return ( + name: "macOS", + version: ProcessInfo.processInfo.operatingSystemVersionString + ) #endif } @@ -129,8 +132,10 @@ public struct DeviceInfo { #if canImport(IOKit) private func value(forKey key: String) -> String? { - let service = IOServiceGetMatchingService(kIOMasterPortDefault, - IOServiceMatching("IOPlatformExpertDevice")) + let service = IOServiceGetMatchingService( + kIOMasterPortDefault, + IOServiceMatching("IOPlatformExpertDevice") + ) var modelIdentifier: String? if let modelData = IORegistryEntryCreateCFProperty(service, key as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Data { modelIdentifier = String(data: modelData, encoding: .utf8)?.trimmingCharacters(in: .controlCharacters) diff --git a/Amplify/Core/Support/DispatchSource+MakeOneOff.swift b/Amplify/Core/Support/DispatchSource+MakeOneOff.swift index 0bf038b33b..1e77624d69 100644 --- a/Amplify/Core/Support/DispatchSource+MakeOneOff.swift +++ b/Amplify/Core/Support/DispatchSource+MakeOneOff.swift @@ -7,7 +7,7 @@ import Foundation -extension DispatchSource { +public extension DispatchSource { /// Convenience function to encapsulate creation of a one-off DispatchSourceTimer for different versions of Swift /// /// - Parameters: @@ -15,9 +15,11 @@ extension DispatchSource { /// - queue: The queue on which the timer should perform its block /// - block: The block to invoke when the timer is fired /// - Returns: The unstarted timer - public static func makeOneOffDispatchSourceTimer(interval: DispatchTimeInterval, - queue: DispatchQueue, - block: @escaping () -> Void ) -> DispatchSourceTimer { + static func makeOneOffDispatchSourceTimer( + interval: DispatchTimeInterval, + queue: DispatchQueue, + block: @escaping () -> Void + ) -> DispatchSourceTimer { let deadline = DispatchTime.now() + interval return makeOneOffDispatchSourceTimer(deadline: deadline, queue: queue, block: block) } @@ -27,9 +29,11 @@ extension DispatchSource { /// - deadline: The time to fire the timer /// - queue: The queue on which the timer should perform its block /// - block: The block to invoke when the timer is fired - public static func makeOneOffDispatchSourceTimer(deadline: DispatchTime, - queue: DispatchQueue, - block: @escaping () -> Void ) -> DispatchSourceTimer { + static func makeOneOffDispatchSourceTimer( + deadline: DispatchTime, + queue: DispatchQueue, + block: @escaping () -> Void + ) -> DispatchSourceTimer { let timer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags(rawValue: 0), queue: queue) #if swift(>=4) timer.schedule(deadline: deadline) diff --git a/Amplify/Core/Support/Encodable+AnyEncodable.swift b/Amplify/Core/Support/Encodable+AnyEncodable.swift index 17baadd403..3919a0c36b 100644 --- a/Amplify/Core/Support/Encodable+AnyEncodable.swift +++ b/Amplify/Core/Support/Encodable+AnyEncodable.swift @@ -20,9 +20,9 @@ public struct AnyEncodable: Encodable { } } -extension Encodable { +public extension Encodable { - public func eraseToAnyEncodable() -> AnyEncodable { + func eraseToAnyEncodable() -> AnyEncodable { return AnyEncodable(self) } diff --git a/Amplify/Core/Support/Fatal.swift b/Amplify/Core/Support/Fatal.swift index fa1600351d..1cddd7435a 100644 --- a/Amplify/Core/Support/Fatal.swift +++ b/Amplify/Core/Support/Fatal.swift @@ -15,9 +15,11 @@ import Foundation public enum Fatal { @discardableResult - public static func preconditionFailure(_ message: @autoclosure () -> String = String(), - file: StaticString = #file, - line: UInt = #line) -> T { + public static func preconditionFailure( + _ message: @autoclosure () -> String = String(), + file: StaticString = #file, + line: UInt = #line + ) -> T { guard let instanceFactory = AmplifyTesting.getInstanceFactory() else { Swift.preconditionFailure(message(), file: file, line: line) } @@ -30,9 +32,11 @@ public enum Fatal { /// Die because a default method must be overriden by a /// subtype or extension. - public static func mustOverride(function: StaticString = #function, - file: StaticString = #file, - line: UInt = #line) -> Never { + public static func mustOverride( + function: StaticString = #function, + file: StaticString = #file, + line: UInt = #line + ) -> Never { die(reason: "Must be overridden", extra: String(describing: function), file: file, line: line) } @@ -71,7 +75,7 @@ public enum Fatal { /// context information. private static func die(reason: String, extra: String? = nil, file: StaticString, line: UInt) -> Never { var message = reason - if let extra = extra { + if let extra { message += ": \(extra)" } fatalError(message, file: file, line: line) diff --git a/Amplify/Core/Support/Internal/InternalTask+AsyncSequence.swift b/Amplify/Core/Support/Internal/InternalTask+AsyncSequence.swift index ad66b30b94..fb13416abc 100644 --- a/Amplify/Core/Support/Internal/InternalTask+AsyncSequence.swift +++ b/Amplify/Core/Support/Internal/InternalTask+AsyncSequence.swift @@ -12,12 +12,12 @@ public extension InternalTaskAsyncSequence where Self: InternalTaskRunner { var sequence: AmplifyAsyncSequence { guard let sequence = context.sequence else { let task = Task { [weak self] in - guard let self = self else { return } - try await self.run() + guard let self else { return } + try await run() } let sequence = AmplifyAsyncSequence(parent: self, bufferingPolicy: context.bufferingPolicy) - self.context.task = task + context.task = task context.sequence = sequence return sequence } @@ -42,10 +42,10 @@ public extension InternalTaskAsyncThrowingSequence where Self: InternalTaskRunne context.sequence = sequence let task = Task { [weak self] in - guard let self = self else { return } - try await self.run() + guard let self else { return } + try await run() } - self.context.task = task + context.task = task return sequence } diff --git a/Amplify/Core/Support/Internal/InternalTask+Hub.swift b/Amplify/Core/Support/Internal/InternalTask+Hub.swift index 71bdb20ecb..9ef031e402 100644 --- a/Amplify/Core/Support/Internal/InternalTask+Hub.swift +++ b/Amplify/Core/Support/Internal/InternalTask+Hub.swift @@ -60,9 +60,11 @@ public extension InternalTaskHubResult where Self: InternalTaskIdentifiable & In // Automatically unsubscribe when event is received unsubscribe?() } - let token = Amplify.Hub.listen(to: channel, - isIncluded: idFilter, - listener: resultHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: idFilter, + listener: resultHubListener + ) unsubscribe = { Amplify.Hub.removeListener(token) } @@ -94,9 +96,11 @@ public extension InternalTaskHubInProcess where Self: InternalTaskIdentifiable & return } } - let token = Amplify.Hub.listen(to: channel, - isIncluded: idFilter, - listener: inProcessHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: idFilter, + listener: inProcessHubListener + ) return token } @@ -131,9 +135,11 @@ public extension InternalTaskHubInProcess where Self: InternalTaskIdentifiable & unsubscribe?() } } - let token = Amplify.Hub.listen(to: channel, - isIncluded: idFilter, - listener: inProcessHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: idFilter, + listener: inProcessHubListener + ) unsubscribe = { Amplify.Hub.removeListener(token) } @@ -157,9 +163,11 @@ public extension InternalTaskHubInProcess where Self: InternalTaskIdentifiable { return } } - let token = Amplify.Hub.listen(to: channel, - isIncluded: filterById, - listener: inProcessHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: filterById, + listener: inProcessHubListener + ) return token } @@ -194,9 +202,11 @@ public extension InternalTaskHubInProcess where Self: InternalTaskIdentifiable & unsubscribe?() } } - let token = Amplify.Hub.listen(to: channel, - isIncluded: filterById, - listener: inProcessHubListener) + let token = Amplify.Hub.listen( + to: channel, + isIncluded: filterById, + listener: inProcessHubListener + ) unsubscribe = { Amplify.Hub.removeListener(token) } diff --git a/Amplify/Core/Support/Internal/NSLocking+Execute.swift b/Amplify/Core/Support/Internal/NSLocking+Execute.swift index 87de3b3aba..f29de68a3e 100644 --- a/Amplify/Core/Support/Internal/NSLocking+Execute.swift +++ b/Amplify/Core/Support/Internal/NSLocking+Execute.swift @@ -10,7 +10,7 @@ import Foundation /// - Warning: Although this has `public` access, it is intended for internal use /// and should not be used directly by host applications. The behaviors and names of /// this type may change without warning. -extension NSLocking { +public extension NSLocking { /// Execute `block` after obtaining a lock on `lock`. /// /// - Warning: Although this has `public` access, it is intended for internal use @@ -18,7 +18,7 @@ extension NSLocking { /// this type may change without warning. /// - Parameters: /// - block: The block to execute - public func execute( + func execute( _ block: BasicThrowableClosure ) rethrows { try execute(input: (), block: block) @@ -32,7 +32,7 @@ extension NSLocking { /// this type may change without warning. /// - Parameters: /// - block: The block to execute - public func execute( + func execute( _ block: () throws -> Output ) rethrows -> Output { try execute(input: (), block: block) diff --git a/Amplify/Core/Support/JSONValue+KeyPath.swift b/Amplify/Core/Support/JSONValue+KeyPath.swift index 7e805fb09b..956441fe77 100644 --- a/Amplify/Core/Support/JSONValue+KeyPath.swift +++ b/Amplify/Core/Support/JSONValue+KeyPath.swift @@ -12,8 +12,10 @@ public extension JSONValue { value(at: keyPath, separatedBy: ".") } - func value(at keyPath: String, - separatedBy separator: T) -> JSONValue? { + func value( + at keyPath: String, + separatedBy separator: some StringProtocol + ) -> JSONValue? { let pathComponents = keyPath.components(separatedBy: separator) let value = pathComponents.reduce(self) { currVal, nextVal in currVal?[nextVal] } return value diff --git a/Amplify/Core/Support/JSONValue.swift b/Amplify/Core/Support/JSONValue.swift index afb1a243ad..8c477a78af 100644 --- a/Amplify/Core/Support/JSONValue.swift +++ b/Amplify/Core/Support/JSONValue.swift @@ -107,9 +107,9 @@ extension JSONValue: ExpressibleByStringLiteral { } } -extension JSONValue { +public extension JSONValue { - public var asObject: [String: JSONValue]? { + var asObject: [String: JSONValue]? { if case .object(let object) = self { return object } @@ -117,7 +117,7 @@ extension JSONValue { return nil } - public var asArray: [JSONValue]? { + var asArray: [JSONValue]? { if case .array(let array) = self { return array } @@ -125,7 +125,7 @@ extension JSONValue { return nil } - public var stringValue: String? { + var stringValue: String? { if case .string(let string) = self { return string } @@ -133,7 +133,7 @@ extension JSONValue { return nil } - public var intValue: Int? { + var intValue: Int? { if case .number(let double) = self, double < Double(Int.max) && double >= Double(Int.min) { return Int(double) @@ -141,7 +141,7 @@ extension JSONValue { return nil } - public var doubleValue: Double? { + var doubleValue: Double? { if case .number(let double) = self { return double } @@ -149,7 +149,7 @@ extension JSONValue { return nil } - public var booleanValue: Bool? { + var booleanValue: Bool? { if case .boolean(let bool) = self { return bool } @@ -157,7 +157,7 @@ extension JSONValue { return nil } - public var isNull: Bool { + var isNull: Bool { if case .null = self { return true } diff --git a/Amplify/Core/Support/OperationCancelledError.swift b/Amplify/Core/Support/OperationCancelledError.swift index 6ce876b9a0..113306efad 100644 --- a/Amplify/Core/Support/OperationCancelledError.swift +++ b/Amplify/Core/Support/OperationCancelledError.swift @@ -21,7 +21,7 @@ public struct OperationCancelledError: Error { /// change without warning. public extension AmplifyError { var isOperationCancelledError: Bool { - guard let underlyingError = underlyingError else { + guard let underlyingError else { return false } return underlyingError.isOperationCancelledError diff --git a/Amplify/Core/Support/Operations+Combine.swift b/Amplify/Core/Support/Operations+Combine.swift index f1cf40d789..6b25029018 100644 --- a/Amplify/Core/Support/Operations+Combine.swift +++ b/Amplify/Core/Support/Operations+Combine.swift @@ -6,8 +6,8 @@ // #if canImport(Combine) -import Foundation import Combine +import Foundation public extension AmplifyOperation { /// Publishes the final result of the operation diff --git a/Amplify/Core/Support/Optional+Extension.swift b/Amplify/Core/Support/Optional+Extension.swift index 4efb0d736f..1e064bf32a 100644 --- a/Amplify/Core/Support/Optional+Extension.swift +++ b/Amplify/Core/Support/Optional+Extension.swift @@ -7,13 +7,13 @@ import Foundation -extension Optional { +public extension Optional { /// /// Performing side effect function when data is exist /// - parameters: /// - then: a closure that takes wrapped data as a parameter @_spi(OptionalExtension) - public func ifSome(_ then: (Wrapped) throws -> Void) rethrows { + func ifSome(_ then: (Wrapped) throws -> Void) rethrows { if case .some(let wrapped) = self { try then(wrapped) } diff --git a/Amplify/Core/Support/Result+Void.swift b/Amplify/Core/Support/Result+Void.swift index 5c6060d230..6420112be8 100644 --- a/Amplify/Core/Support/Result+Void.swift +++ b/Amplify/Core/Support/Result+Void.swift @@ -5,6 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 // -extension Result where Success == Void { - public static var successfulVoid: Result { .success(()) } +public extension Result where Success == Void { + static var successfulVoid: Result { .success(()) } } diff --git a/Amplify/Core/Support/String+Extensions.swift b/Amplify/Core/Support/String+Extensions.swift index 995ddcac9d..f95755725d 100644 --- a/Amplify/Core/Support/String+Extensions.swift +++ b/Amplify/Core/Support/String+Extensions.swift @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 // -extension String { +public extension String { /// Converts a "camelCase" value to "PascalCase". This is a very simple /// and naive implementation that assumes the input as a "camelCase" value @@ -15,7 +15,7 @@ extension String { /// - Note: this method simply transforms the first character to uppercase. /// /// - Returns: a string in "PascalCase" converted from "camelCase" - public func pascalCased() -> String { + func pascalCased() -> String { return prefix(1).uppercased() + dropFirst() } @@ -27,12 +27,12 @@ extension String { /// - Note: this method simply transforms the first character to lowercase. /// /// - Returns: a string in "pascalCase" converted from "CamelCase" - public func camelCased() -> String { + func camelCased() -> String { return prefix(1).lowercased() + dropFirst() } /// Appends "s" to the end of the string to represent the pluralized form. - public func pluralize() -> String { + func pluralize() -> String { return self + "s" } } diff --git a/Amplify/Core/Support/TaskQueue.swift b/Amplify/Core/Support/TaskQueue.swift index b7ba5c0553..eef0a6f0d9 100644 --- a/Amplify/Core/Support/TaskQueue.swift +++ b/Amplify/Core/Support/TaskQueue.swift @@ -62,8 +62,8 @@ public class TaskQueue { } } -extension TaskQueue { - public static var log: Logger { +public extension TaskQueue { + static var log: Logger { Amplify.Logging.logger(forNamespace: String(describing: self)) } } diff --git a/Amplify/Core/Support/TimeInterval+Helper.swift b/Amplify/Core/Support/TimeInterval+Helper.swift index b8baf2a3ef..179991e884 100644 --- a/Amplify/Core/Support/TimeInterval+Helper.swift +++ b/Amplify/Core/Support/TimeInterval+Helper.swift @@ -7,25 +7,25 @@ import Foundation -extension TimeInterval { +public extension TimeInterval { - public static func milliseconds(_ value: Double) -> TimeInterval { + static func milliseconds(_ value: Double) -> TimeInterval { return value / 1_000 } - public static func seconds(_ value: Double) -> TimeInterval { + static func seconds(_ value: Double) -> TimeInterval { return value } - public static func minutes(_ value: Double) -> TimeInterval { + static func minutes(_ value: Double) -> TimeInterval { return value * 60 } - public static func hours(_ value: Double) -> TimeInterval { + static func hours(_ value: Double) -> TimeInterval { return value * 60 * 60 } - public static func days(_ value: Double) -> TimeInterval { + static func days(_ value: Double) -> TimeInterval { return value * 60 * 60 * 24 } diff --git a/Amplify/DefaultPlugins/AWSHubPlugin/AWSHubPlugin.swift b/Amplify/DefaultPlugins/AWSHubPlugin/AWSHubPlugin.swift index 33100b2ed8..ad1a688273 100644 --- a/Amplify/DefaultPlugins/AWSHubPlugin/AWSHubPlugin.swift +++ b/Amplify/DefaultPlugins/AWSHubPlugin/AWSHubPlugin.swift @@ -21,7 +21,7 @@ import Foundation /// /// Instead, messages and listener states are guaranteed to be independently self-consistent. Callers can use /// `hasListener(withToken:)` to check that a listener has been registered. -final public class AWSHubPlugin: HubCategoryPlugin { +public final class AWSHubPlugin: HubCategoryPlugin { /// Convenience property. Each instance of `AWSHubPlugin` has the same key public static var key: String { return "awsHubPlugin" @@ -49,16 +49,20 @@ final public class AWSHubPlugin: HubCategoryPlugin { dispatcher.dispatch(to: channel, payload: payload) } - public func listen(to channel: HubChannel, - eventName: HubPayloadEventName, - listener: @escaping HubListener) -> UnsubscribeToken { + public func listen( + to channel: HubChannel, + eventName: HubPayloadEventName, + listener: @escaping HubListener + ) -> UnsubscribeToken { let filter = HubFilters.forEventName(eventName) return listen(to: channel, isIncluded: filter, listener: listener) } - public func listen(to channel: HubChannel, - isIncluded filter: HubFilter? = nil, - listener: @escaping HubListener) -> UnsubscribeToken { + public func listen( + to channel: HubChannel, + isIncluded filter: HubFilter? = nil, + listener: @escaping HubListener + ) -> UnsubscribeToken { let filteredListener = FilteredListener(for: channel, filter: filter, listener: listener) dispatcher.insert(filteredListener) diff --git a/Amplify/DefaultPlugins/AWSHubPlugin/Internal/ConcurrentDispatcher.swift b/Amplify/DefaultPlugins/AWSHubPlugin/Internal/ConcurrentDispatcher.swift index 59dcc97cea..37f278d6b2 100644 --- a/Amplify/DefaultPlugins/AWSHubPlugin/Internal/ConcurrentDispatcher.swift +++ b/Amplify/DefaultPlugins/AWSHubPlugin/Internal/ConcurrentDispatcher.swift @@ -39,7 +39,7 @@ struct ConcurrentDispatcher: Dispatcher { return } - listener.listener(self.payload) + listener.listener(payload) } } } diff --git a/Amplify/DefaultPlugins/AWSHubPlugin/Internal/SerialDispatcher.swift b/Amplify/DefaultPlugins/AWSHubPlugin/Internal/SerialDispatcher.swift index 62a7a16aa2..74d753bd45 100644 --- a/Amplify/DefaultPlugins/AWSHubPlugin/Internal/SerialDispatcher.swift +++ b/Amplify/DefaultPlugins/AWSHubPlugin/Internal/SerialDispatcher.swift @@ -32,17 +32,17 @@ struct SerialDispatcher: Dispatcher { } DispatchQueue.global().async { - guard !self.isCancelled else { + guard !isCancelled else { return } if let filter = filteredListener.filter { - guard filter(self.payload) else { + guard filter(payload) else { return } } - filteredListener.listener(self.payload) + filteredListener.listener(payload) } } } diff --git a/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/AWSUnifiedLoggingPlugin.swift b/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/AWSUnifiedLoggingPlugin.swift index 50f8c484ff..bbf90eed96 100644 --- a/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/AWSUnifiedLoggingPlugin.swift +++ b/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/AWSUnifiedLoggingPlugin.swift @@ -9,7 +9,7 @@ import Foundation import os.log /// A Logging category plugin that forwards calls to the OS's Unified Logging system -final public class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin { +public final class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin { /// Convenience property. Each instance of `AWSUnifiedLoggingPlugin` has the same key public static var key: String { @@ -35,8 +35,10 @@ final public class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin { self.subsystem = Bundle.main.bundleIdentifier ?? "com.amazonaws.amplify.AWSUnifiedLoggingPlugin" let defaultOSLog = OSLog(subsystem: subsystem, category: AWSUnifiedLoggingPlugin.defaultCategory) - let wrapper = OSLogWrapper(osLog: defaultOSLog, - getLogLevel: { Amplify.Logging.logLevel }) + let wrapper = OSLogWrapper( + osLog: defaultOSLog, + getLogLevel: { Amplify.Logging.logLevel } + ) registeredLogs["default"] = wrapper } @@ -49,7 +51,7 @@ final public class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin { /// Look for optional configuration to disable logging, console logging is enabled by default unless configured otherwise public func configure(using configuration: Any?) throws { if let consoleConfiguration = ConsoleLoggingConfiguration(bundle: Bundle.main), consoleConfiguration.enable == false { - self.disable() + disable() } } @@ -72,8 +74,10 @@ final public class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin { } let osLog = OSLog(subsystem: subsystem, category: category) - let wrapper = OSLogWrapper(osLog: osLog, - getLogLevel: { Amplify.Logging.logLevel }) + let wrapper = OSLogWrapper( + osLog: osLog, + getLogLevel: { Amplify.Logging.logLevel } + ) wrapper.enabled = enabled registeredLogs[key] = wrapper return wrapper @@ -85,25 +89,25 @@ final public class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin { } } -extension AWSUnifiedLoggingPlugin { - public var `default`: Logger { +public extension AWSUnifiedLoggingPlugin { + var `default`: Logger { // We register the default logger at initialization, and protect access via a setter method, so this is safe // to force-unwrap registeredLogs["default"]! } - public func logger(forCategory category: String) -> Logger { + func logger(forCategory category: String) -> Logger { let wrapper = logWrapper(for: category) return wrapper } - public func logger(forCategory category: String, logLevel: LogLevel) -> Logger { + func logger(forCategory category: String, logLevel: LogLevel) -> Logger { let wrapper = logWrapper(for: category) wrapper.logLevel = logLevel return wrapper } - public func enable() { + func enable() { enabled = true lock.execute { for (_, logger) in registeredLogs { @@ -112,7 +116,7 @@ extension AWSUnifiedLoggingPlugin { } } - public func disable() { + func disable() { enabled = false lock.execute { for (_, logger) in registeredLogs { @@ -121,12 +125,12 @@ extension AWSUnifiedLoggingPlugin { } } - public func logger(forNamespace namespace: String) -> Logger { + func logger(forNamespace namespace: String) -> Logger { let wrapper = logWrapper(for: namespace) return wrapper } - public func logger(forCategory category: String, forNamespace namespace: String) -> Logger { + func logger(forCategory category: String, forNamespace namespace: String) -> Logger { let wrapper = logWrapper(for: category + namespace) return wrapper } diff --git a/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift b/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift index 66529cc64d..8fd1277ed3 100644 --- a/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift +++ b/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift @@ -30,18 +30,22 @@ final class OSLogWrapper: Logger { public func error(_ message: @autoclosure () -> String) { guard enabled, logLevel.rawValue >= LogLevel.error.rawValue else { return } - os_log("%@", - log: osLog, - type: OSLogType.error, - message()) + os_log( + "%@", + log: osLog, + type: OSLogType.error, + message() + ) } public func error(error: Error) { guard enabled, logLevel.rawValue >= LogLevel.error.rawValue else { return } - os_log("%@", - log: osLog, - type: OSLogType.error, - error.localizedDescription) + os_log( + "%@", + log: osLog, + type: OSLogType.error, + error.localizedDescription + ) } public func warn(_ message: @autoclosure () -> String) { @@ -49,10 +53,12 @@ final class OSLogWrapper: Logger { return } - os_log("%@", - log: osLog, - type: OSLogType.info, - message()) + os_log( + "%@", + log: osLog, + type: OSLogType.info, + message() + ) } public func info(_ message: @autoclosure () -> String) { @@ -60,10 +66,12 @@ final class OSLogWrapper: Logger { return } - os_log("%@", - log: osLog, - type: OSLogType.info, - message()) + os_log( + "%@", + log: osLog, + type: OSLogType.info, + message() + ) } public func debug(_ message: @autoclosure () -> String) { @@ -71,10 +79,12 @@ final class OSLogWrapper: Logger { return } - os_log("%@", - log: osLog, - type: OSLogType.debug, - message()) + os_log( + "%@", + log: osLog, + type: OSLogType.debug, + message() + ) } public func verbose(_ message: @autoclosure () -> String) { @@ -82,9 +92,11 @@ final class OSLogWrapper: Logger { return } - os_log("%@", - log: osLog, - type: OSLogType.debug, - message()) + os_log( + "%@", + log: osLog, + type: OSLogType.debug, + message() + ) } } diff --git a/Amplify/DevMenu/AmplifyDevMenu.swift b/Amplify/DevMenu/AmplifyDevMenu.swift index b54767e3db..7ac8c23df6 100644 --- a/Amplify/DevMenu/AmplifyDevMenu.swift +++ b/Amplify/DevMenu/AmplifyDevMenu.swift @@ -31,7 +31,8 @@ public final class AmplifyDevMenu: DevMenuBehavior, TriggerDelegate { public func showMenu() { guard let rootViewController = - devMenuPresentationContextProvider?.devMenuPresentationContext().rootViewController else { + devMenuPresentationContextProvider?.devMenuPresentationContext().rootViewController + else { Amplify.Logging.warn(DevMenuStringConstants.logTag + "RootViewController of the UIWindow is nil") return diff --git a/Amplify/DevMenu/AmplifyVersionable.swift b/Amplify/DevMenu/AmplifyVersionable.swift index afaf4cbe59..0e589bf806 100644 --- a/Amplify/DevMenu/AmplifyVersionable.swift +++ b/Amplify/DevMenu/AmplifyVersionable.swift @@ -12,8 +12,8 @@ public protocol AmplifyVersionable { var version: String { get } } -extension AmplifyVersionable where Self: AnyObject { - public var version: String { +public extension AmplifyVersionable where Self: AnyObject { + var version: String { let bundle = Bundle(for: type(of: self)) let version = bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String return version ?? "Not Available" diff --git a/Amplify/DevMenu/Data/DeviceInfoHelper.swift b/Amplify/DevMenu/Data/DeviceInfoHelper.swift index d80f74cb2a..632dd3eae6 100644 --- a/Amplify/DevMenu/Data/DeviceInfoHelper.swift +++ b/Amplify/DevMenu/Data/DeviceInfoHelper.swift @@ -19,13 +19,13 @@ struct DeviceInfoHelper { isSimulator = true #endif return [ - DeviceInfoItem(type: .deviceName(UIDevice.current.name)), - DeviceInfoItem(type: .systemName(UIDevice.current.systemName)), - DeviceInfoItem(type: .systemVersion(UIDevice.current.systemVersion)), - DeviceInfoItem(type: .modelName(UIDevice.current.model)), - DeviceInfoItem(type: .localizedModelName(UIDevice.current.localizedModel)), - DeviceInfoItem(type: .isSimulator(isSimulator)) - ] + DeviceInfoItem(type: .deviceName(UIDevice.current.name)), + DeviceInfoItem(type: .systemName(UIDevice.current.systemName)), + DeviceInfoItem(type: .systemVersion(UIDevice.current.systemVersion)), + DeviceInfoItem(type: .modelName(UIDevice.current.model)), + DeviceInfoItem(type: .localizedModelName(UIDevice.current.localizedModel)), + DeviceInfoItem(type: .isSimulator(isSimulator)) + ] } } #endif diff --git a/Amplify/DevMenu/Data/DeviceInfoItem.swift b/Amplify/DevMenu/Data/DeviceInfoItem.swift index 708185c379..cb5422c98c 100644 --- a/Amplify/DevMenu/Data/DeviceInfoItem.swift +++ b/Amplify/DevMenu/Data/DeviceInfoItem.swift @@ -43,7 +43,7 @@ struct DeviceInfoItem: Identifiable, InfoItemProvider { case .localizedModelName(let value): return value ?? DevMenuStringConstants.notAvailable case .isSimulator(let value): - guard let value = value else { + guard let value else { return DevMenuStringConstants.notAvailable } return value ? "Yes" : "No" diff --git a/Amplify/DevMenu/Data/EnvironmentInfoHelper.swift b/Amplify/DevMenu/Data/EnvironmentInfoHelper.swift index 89cce0eaf3..5ec1949455 100644 --- a/Amplify/DevMenu/Data/EnvironmentInfoHelper.swift +++ b/Amplify/DevMenu/Data/EnvironmentInfoHelper.swift @@ -10,7 +10,7 @@ import Foundation import UIKit /// Helper class to fetch Developer Environment Information -struct EnvironmentInfoHelper { +enum EnvironmentInfoHelper { static let environmentInfoSourceFileName = "local-env-info" diff --git a/Amplify/DevMenu/Data/IssueInfo.swift b/Amplify/DevMenu/Data/IssueInfo.swift index 527642afd8..a237a6e2c5 100644 --- a/Amplify/DevMenu/Data/IssueInfo.swift +++ b/Amplify/DevMenu/Data/IssueInfo.swift @@ -76,8 +76,8 @@ struct IssueInfo { return infoNotAvailable } - return items.reduce("") {(description, item) -> String in - return ("\(description)\(item.displayName) - \(item.information) \n") + return items.reduce("") {description, item -> String in + return "\(description)\(item.displayName) - \(item.information) \n" } } } diff --git a/Amplify/DevMenu/Data/LogEntryHelper.swift b/Amplify/DevMenu/Data/LogEntryHelper.swift index 65fa2229da..8e556f02f3 100644 --- a/Amplify/DevMenu/Data/LogEntryHelper.swift +++ b/Amplify/DevMenu/Data/LogEntryHelper.swift @@ -9,7 +9,7 @@ import Foundation /// Helper class to fetch log entry related information -struct LogEntryHelper { +enum LogEntryHelper { /// Date formatter instance for date formatting private static let dateFormatter: DateFormatter = { @@ -26,7 +26,8 @@ struct LogEntryHelper { /// Helper function to fetch logs from `PersistentLoggingPlugin` static func getLogHistory() -> [LogEntryItem] { if let loggingPlugin: PersistentLoggingPlugin = Amplify.Logging.plugins.first(where: { - $0.key == DevMenuStringConstants.persistentLoggingPluginKey})?.value as? PersistentLoggingPlugin { + $0.key == DevMenuStringConstants.persistentLoggingPluginKey + })?.value as? PersistentLoggingPlugin { if let logger: PersistentLogWrapper = loggingPlugin.default as? PersistentLogWrapper { return logger.getLogHistory() } diff --git a/Amplify/DevMenu/Data/PluginInfoHelper.swift b/Amplify/DevMenu/Data/PluginInfoHelper.swift index c14d4a05e8..e3df27e6d6 100644 --- a/Amplify/DevMenu/Data/PluginInfoHelper.swift +++ b/Amplify/DevMenu/Data/PluginInfoHelper.swift @@ -9,7 +9,7 @@ import Foundation /// Helper class to fetch Amplify plugin information -struct PluginInfoHelper { +enum PluginInfoHelper { static func getPluginInformation() -> [PluginInfoItem] { var pluginList = [PluginInfoItem]() diff --git a/Amplify/DevMenu/DevMenuStringConstants.swift b/Amplify/DevMenu/DevMenuStringConstants.swift index 496e44cdcd..87fe6baae6 100644 --- a/Amplify/DevMenu/DevMenuStringConstants.swift +++ b/Amplify/DevMenu/DevMenuStringConstants.swift @@ -9,7 +9,7 @@ import Foundation /// String constants used in the developer menu -struct DevMenuStringConstants { +enum DevMenuStringConstants { static let notAvailable = "Not available" static let unknownPlugin = "Unknown Plugin" static let versionNotAvailable = "Version not available" diff --git a/Amplify/DevMenu/Trigger/LongPressGestureRecognizer.swift b/Amplify/DevMenu/Trigger/LongPressGestureRecognizer.swift index 766f7b7730..92a9d3f8f8 100644 --- a/Amplify/DevMenu/Trigger/LongPressGestureRecognizer.swift +++ b/Amplify/DevMenu/Trigger/LongPressGestureRecognizer.swift @@ -24,8 +24,10 @@ class LongPressGestureRecognizer: NSObject, TriggerRecognizer, UIGestureRecogniz registerLongPressRecognizer() } - public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, - shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) + public func gestureRecognizer( + _ gestureRecognizer: UIGestureRecognizer, + shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer + ) -> Bool { return true } diff --git a/Amplify/DevMenu/View/DevMenuList.swift b/Amplify/DevMenu/View/DevMenuList.swift index d0ef438ca3..a4163e468f 100644 --- a/Amplify/DevMenu/View/DevMenuList.swift +++ b/Amplify/DevMenu/View/DevMenuList.swift @@ -29,7 +29,8 @@ struct DevMenuList: View { } .navigationBarTitle( Text(screenTitle), - displayMode: .inline) + displayMode: .inline + ) }.navigationViewStyle(StackNavigationViewStyle()) } } diff --git a/Amplify/DevMenu/View/InfoRow.swift b/Amplify/DevMenu/View/InfoRow.swift index ce062b05cf..efd02458e2 100644 --- a/Amplify/DevMenu/View/InfoRow.swift +++ b/Amplify/DevMenu/View/InfoRow.swift @@ -14,8 +14,8 @@ struct InfoRow: View { var body: some View { VStack(alignment: .leading) { - Text(self.infoItem.displayName).bold() - Text(self.infoItem.information) + Text(infoItem.displayName).bold() + Text(infoItem.information) } } } diff --git a/Amplify/DevMenu/View/IssueReporter.swift b/Amplify/DevMenu/View/IssueReporter.swift index 937fd49f76..66a88dec4e 100644 --- a/Amplify/DevMenu/View/IssueReporter.swift +++ b/Amplify/DevMenu/View/IssueReporter.swift @@ -65,9 +65,11 @@ struct IssueReporter: View { .border(Color.blue) .padding(.bottom) .alert(isPresented: $showAlertIfInvalidURL) { - Alert(title: Text(githubURLErrorTitle), - message: Text(githubURLErrorMessage), - dismissButton: .default(Text("OK"))) + Alert( + title: Text(githubURLErrorTitle), + message: Text(githubURLErrorMessage), + dismissButton: .default(Text("OK")) + ) } .disabled(shouldDisableReporting()) @@ -96,9 +98,11 @@ struct IssueReporter: View { /// Open Amplify iOS issue logging screen on Github private func reportToGithub() { Task { - let issue = await IssueInfo(issueDescription: issueDescription, - includeEnvInfo: includeEnvInfo, - includeDeviceInfo: includeDeviceInfo) + let issue = await IssueInfo( + issueDescription: issueDescription, + includeEnvInfo: includeEnvInfo, + includeDeviceInfo: includeDeviceInfo + ) let issueDescriptionMarkdown = await IssueInfoHelper.generateMarkdownForIssue( issue: issue) @@ -121,9 +125,11 @@ struct IssueReporter: View { /// Copy issue as a markdown string to clipboard private func copyToClipboard() { Task { - let issue = await IssueInfo(issueDescription: issueDescription, - includeEnvInfo: includeEnvInfo, - includeDeviceInfo: includeDeviceInfo) + let issue = await IssueInfo( + issueDescription: issueDescription, + includeEnvInfo: includeEnvInfo, + includeDeviceInfo: includeDeviceInfo + ) let value = await IssueInfoHelper.generateMarkdownForIssue(issue: issue) #if os(iOS) UIPasteboard.general.string = value @@ -163,8 +169,12 @@ final class MultilineTextField: UIViewRepresentable { /// add a dismiss button in UIToolbar for keyboard let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 35)) let emptySpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let dismissButton = UIBarButtonItem(title: "Dismiss", style: .done, - target: self, action: #selector(dismissKeyboard)) + let dismissButton = UIBarButtonItem( + title: "Dismiss", + style: .done, + target: self, + action: #selector(dismissKeyboard) + ) toolbar.setItems([emptySpace, dismissButton], animated: false) toolbar.sizeToFit() @@ -174,8 +184,12 @@ final class MultilineTextField: UIViewRepresentable { @MainActor @objc func dismissKeyboard() { - UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), - to: nil, from: nil, for: nil) + UIApplication.shared.sendAction( + #selector(UIResponder.resignFirstResponder), + to: nil, + from: nil, + for: nil + ) } func updateUIView(_ uiView: UITextView, context: Context) { diff --git a/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncExpectation.swift b/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncExpectation.swift index 2746528644..45bb2a9ab6 100644 --- a/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncExpectation.swift +++ b/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncExpectation.swift @@ -35,17 +35,18 @@ public actor AsyncExpectation { } public func setShouldTrigger(_ shouldTrigger: Bool) { - self.isInverted = !shouldTrigger + isInverted = !shouldTrigger } public func setExpectedFulfillmentCount(_ count: Int) { - self.expectedFulfillmentCount = count + expectedFulfillmentCount = count } public init(description: String, isInverted: Bool = false, - expectedFulfillmentCount: Int = 1) { - expectationDescription = description + expectedFulfillmentCount: Int = 1) + { + self.expectationDescription = description self.isInverted = isInverted self.expectedFulfillmentCount = expectedFulfillmentCount } @@ -73,7 +74,7 @@ public actor AsyncExpectation { } } - internal nonisolated func wait() async throws { + nonisolated func wait() async throws { try await withTaskCancellationHandler { try await handleWait() } onCancel: { @@ -83,8 +84,9 @@ public actor AsyncExpectation { } } - internal func timeOut(file: StaticString = #filePath, - line: UInt = #line) async { + func timeOut(file: StaticString = #filePath, + line: UInt = #line) async + { if isInverted { state = .timedOut } else if state != .fulfilled { diff --git a/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncTesting.swift b/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncTesting.swift index 84ca0cbc7d..f557bae458 100644 --- a/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncTesting.swift +++ b/AmplifyAsyncTesting/Sources/AsyncTesting/AsyncTesting.swift @@ -12,7 +12,8 @@ public enum AsyncTesting { public static func expectation(description: String, isInverted: Bool = false, - expectedFulfillmentCount: Int = 1) -> AsyncExpectation { + expectedFulfillmentCount: Int = 1) -> AsyncExpectation + { AsyncExpectation(description: description, isInverted: isInverted, expectedFulfillmentCount: expectedFulfillmentCount) @@ -22,7 +23,8 @@ public enum AsyncTesting { public static func waitForExpectations(_ expectations: [AsyncExpectation], timeout: Double = 1.0, file: StaticString = #filePath, - line: UInt = #line) async { + line: UInt = #line) async + { guard !expectations.isEmpty else { return } // check if all expectations are already satisfied and skip sleeping diff --git a/AmplifyAsyncTesting/Sources/AsyncTesting/XCTestCase+AsyncTesting.swift b/AmplifyAsyncTesting/Sources/AsyncTesting/XCTestCase+AsyncTesting.swift index cce82a21d6..521b0f0382 100644 --- a/AmplifyAsyncTesting/Sources/AsyncTesting/XCTestCase+AsyncTesting.swift +++ b/AmplifyAsyncTesting/Sources/AsyncTesting/XCTestCase+AsyncTesting.swift @@ -8,9 +8,9 @@ import Foundation import XCTest -extension XCTestCase { - public static let defaultTimeoutForAsyncExpectations = TimeInterval(60) - public static let defaultNetworkTimeoutForAsyncExpectations = TimeInterval(600) +public extension XCTestCase { + static let defaultTimeoutForAsyncExpectations = TimeInterval(60) + static let defaultNetworkTimeoutForAsyncExpectations = TimeInterval(600) /// Creates a new async expectation with an associated description. /// @@ -25,9 +25,10 @@ extension XCTestCase { /// - description: A string to display in the test log for this expectation, to help diagnose failures. /// - isInverted: Indicates that the expectation is not intended to happen. /// - expectedFulfillmentCount: The number of times fulfill() must be called before the expectation is completely fulfilled. (default = 1) - public func asyncExpectation(description: String, + func asyncExpectation(description: String, isInverted: Bool = false, - expectedFulfillmentCount: Int = 1) -> AsyncExpectation { + expectedFulfillmentCount: Int = 1) -> AsyncExpectation + { AsyncExpectation(description: description, isInverted: isInverted, expectedFulfillmentCount: expectedFulfillmentCount) @@ -38,10 +39,11 @@ extension XCTestCase { /// - expectations: An array of async expectations that must be fulfilled. /// - timeout: The number of seconds within which all expectations must be fulfilled. @MainActor - public func waitForExpectations(_ expectations: [AsyncExpectation], + func waitForExpectations(_ expectations: [AsyncExpectation], timeout: Double = 1.0, file: StaticString = #filePath, - line: UInt = #line) async { + line: UInt = #line) async + { await AsyncTesting.waitForExpectations(expectations, timeout: timeout, file: file, @@ -54,10 +56,11 @@ extension XCTestCase { /// - operation: operation to run /// - Returns: result of closure @discardableResult - public func testTask(timeout: Double = defaultTimeoutForAsyncExpectations, + func testTask(timeout: Double = defaultTimeoutForAsyncExpectations, file: StaticString = #filePath, line: UInt = #line, - @_implicitSelfCapture operation: @escaping @Sendable () async throws -> Success) async throws -> Success { + @_implicitSelfCapture operation: @escaping @Sendable () async throws -> Success) async throws -> Success + { let done = asyncExpectation(description: "done") let task = Task { () -> Success in @@ -84,9 +87,10 @@ extension XCTestCase { /// /// - Returns:The result of successfuly running `action`, or `nil` if it threw an error. @discardableResult - func wait(with expectation: AsyncExpectation, + internal func wait(with expectation: AsyncExpectation, timeout: TimeInterval = defaultNetworkTimeoutForAsyncExpectations, - action: @escaping () async throws -> T) async -> T? { + action: @escaping () async throws -> T) async -> T? + { let task = Task { () -> T? in defer { Task { @@ -116,9 +120,10 @@ extension XCTestCase { /// /// - Returns:The result of successfuly running `action`, or `nil` if it threw an error. @discardableResult - func wait(name: String, + internal func wait(name: String, timeout: TimeInterval = defaultNetworkTimeoutForAsyncExpectations, - action: @escaping () async throws -> T) async -> T? { + action: @escaping () async throws -> T) async -> T? + { let expectation = asyncExpectation(description: name) return await wait(with: expectation, timeout: timeout, action: action) } @@ -136,9 +141,10 @@ extension XCTestCase { /// /// - Returns:The error thrown during the execution of `action`, or `nil` if it run successfully. @discardableResult - func waitError(with expectation: AsyncExpectation, + internal func waitError(with expectation: AsyncExpectation, timeout: TimeInterval = defaultNetworkTimeoutForAsyncExpectations, - action: @escaping () async throws -> T) async -> Error? { + action: @escaping () async throws -> T) async -> Error? + { let task = Task { () -> Error? in defer { Task { await expectation.fulfill() } @@ -170,9 +176,10 @@ extension XCTestCase { /// /// - Returns:The error thrown during the execution of `action`, or `nil` if it run successfully. @discardableResult - func waitError(name: String, + internal func waitError(name: String, timeout: TimeInterval = defaultNetworkTimeoutForAsyncExpectations, - action: @escaping () async throws -> T) async -> Error? { + action: @escaping () async throws -> T) async -> Error? + { let expectation = asyncExpectation(description: name) return await waitError(with: expectation, timeout: timeout, action: action) } diff --git a/AmplifyFunctionalTests/AmplifyConfigurationInitFromFileTests.swift b/AmplifyFunctionalTests/AmplifyConfigurationInitFromFileTests.swift index dfa4039a44..808aec3d14 100644 --- a/AmplifyFunctionalTests/AmplifyConfigurationInitFromFileTests.swift +++ b/AmplifyFunctionalTests/AmplifyConfigurationInitFromFileTests.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import XCTest import Amplify +import XCTest /// Test the public AmplifyConfiguration initializer. Note that this means we must not import /// Amplify as `@testable`. That means we cannot `await Amplify.reset()`, which means we can only have diff --git a/AmplifyFunctionalTests/Hub/DefaultHubPluginPerformanceTestHelpers.swift b/AmplifyFunctionalTests/Hub/DefaultHubPluginPerformanceTestHelpers.swift index f112b834eb..edd87f2bf5 100644 --- a/AmplifyFunctionalTests/Hub/DefaultHubPluginPerformanceTestHelpers.swift +++ b/AmplifyFunctionalTests/Hub/DefaultHubPluginPerformanceTestHelpers.swift @@ -9,11 +9,12 @@ import XCTest @testable import Amplify @testable import AmplifyTestCommon -struct DefaultHubPluginPerformanceTestHelpers { +enum DefaultHubPluginPerformanceTestHelpers { - static func makeTestObjectsForSingleChannel(listenerCount: Int, - dispatcherType: T.Type, - testCase: XCTestCase) -> PerformanceTestObjects { + static func makeTestObjectsForSingleChannel(listenerCount: Int, + dispatcherType: (some Dispatcher).Type, + testCase: XCTestCase) -> PerformanceTestObjects + { let dispatcherChannels = [HubChannel.storage] let listenerChannels = [HubChannel.storage] @@ -28,9 +29,10 @@ struct DefaultHubPluginPerformanceTestHelpers { testCase: testCase) } - static func makeTestObjectsForSingleDispatcher(listenerCount: Int, - dispatcherType: T.Type, - testCase: XCTestCase) -> PerformanceTestObjects { + static func makeTestObjectsForSingleDispatcher(listenerCount: Int, + dispatcherType: (some Dispatcher).Type, + testCase: XCTestCase) -> PerformanceTestObjects + { let dispatcherChannels = [HubChannel.storage] let listenerChannels = [HubChannel.storage, @@ -49,9 +51,10 @@ struct DefaultHubPluginPerformanceTestHelpers { testCase: testCase) } - static func makeTestObjectsForMultipleDispatchers(listenerCount: Int, - dispatcherType: T.Type, - testCase: XCTestCase) -> PerformanceTestObjects { + static func makeTestObjectsForMultipleDispatchers(listenerCount: Int, + dispatcherType: (some Dispatcher).Type, + testCase: XCTestCase) -> PerformanceTestObjects + { let dispatcherChannels = [HubChannel.storage, .custom("CustomChannel1")] let listenerChannels = [HubChannel.storage, @@ -71,12 +74,13 @@ struct DefaultHubPluginPerformanceTestHelpers { } // swiftlint:disable:next function_parameter_count - static func makeTestObjectsForDispatcherTypes(listenerCount: Int, + static func makeTestObjectsForDispatcherTypes(listenerCount: Int, listenerChannels: [HubChannel], - dispatcherType: T.Type, + dispatcherType: (some Dispatcher).Type, dispatcherChannels: [HubChannel], expectedChannels: [HubChannel], - testCase: XCTestCase) -> PerformanceTestObjects { + testCase: XCTestCase) -> PerformanceTestObjects + { var dispatchers = [Dispatcher]() for channel in dispatcherChannels { @@ -115,7 +119,8 @@ struct DefaultHubPluginPerformanceTestHelpers { static func makeListeners(count: Int, for channels: [HubChannel], expectedChannels: [HubChannel], - testCase: XCTestCase) -> ([FilteredListener], [XCTestExpectation]) { + testCase: XCTestCase) -> ([FilteredListener], [XCTestExpectation]) + { var listeners = [FilteredListener]() var expectations = [XCTestExpectation]() diff --git a/Package.swift b/Package.swift index 3a679faade..3171aa773a 100644 --- a/Package.swift +++ b/Package.swift @@ -406,7 +406,7 @@ let predictionsTargets: [Target] = [ name: "AWSPredictionsPluginUnitTests", dependencies: ["AWSPredictionsPlugin"], path: "AmplifyPlugins/Predictions/Tests/AWSPredictionsPluginUnitTests", - resources: [.copy("TestResources/TestImages") ] + resources: [.copy("TestResources/TestImages")] ), .target( name: "CoreMLPredictionsPlugin", From 47601cd3dd09049243aadebd458798a6c3280d6b Mon Sep 17 00:00:00 2001 From: Tuan Pham <103537251+phantumcode@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:38:52 -0500 Subject: [PATCH 02/13] chore(analytics): resolve swiftformat errors and warnings (#3844) * chore(analytics): resolve swiftformat errors and warnings * chore(analytics): resolve swiftformat errors and warnings * resolve review comments * fix build errors --- ...npointAnalyticsPlugin+ClientBehavior.swift | 30 +-- ...AWSPinpointAnalyticsPlugin+Configure.swift | 16 +- .../AWSPinpointAnalyticsPlugin+Options.swift | 16 +- .../AWSPinpointAnalyticsPlugin+Reset.swift | 4 +- ...PinpointAnalyticsPluginConfiguration.swift | 48 ++-- .../Constants/AnalyticsErrorConstants.swift | 2 +- ...SPinpointAnalyticsPlugin+HubCategory.swift | 6 +- .../PinpointEvent+AnalyticsEvent.swift | 12 +- ...WSPinpoint+AnalyticsErrorConvertible.swift | 2 +- .../Utils/AnalyticsErrorConvertible.swift | 2 +- .../Support/Utils/AnalyticsErrorHelper.swift | 2 +- ...nTimeError+AnalyticsErrorConvertible.swift | 4 +- ...alyticsPluginAmplifyVersionableTests.swift | 2 +- ...ntAnalyticsPluginClientBehaviorTests.swift | 110 +++++---- ...inpointAnalyticsPluginConfigureTests.swift | 29 ++- ...AWSPinpointAnalyticsPluginResetTests.swift | 2 +- .../AWSPinpointAnalyticsPluginTestBase.swift | 13 +- ...uginAmplifyOutputsConfigurationTests.swift | 41 ++-- ...intAnalyticsPluginConfigurationTests.swift | 102 +++++--- .../Mocks/MockAWSPinpoint+Analytics.swift | 72 +++--- .../Mocks/MockAWSPinpoint+Targeting.swift | 22 +- .../Mocks/MockAWSPinpoint.swift | 20 +- .../Mocks/MockNetworkMonitor.swift | 2 +- ...pointAnalyticsPluginIntegrationTests.swift | 195 ++++++++------- .../AnalyticsStressTests.swift | 78 +++--- .../AWSPinpointBehavior.swift | 12 +- .../Analytics/AnalyticsClient.swift | 227 +++++++++++------- .../Analytics/EventRecorder.swift | 91 ++++--- .../AnalyticsEventSQLStorage.swift | 21 +- .../LocalStorage/AnalyticsEventStorage.swift | 10 +- .../LocalStorage/PinpointEvent+Bindings.swift | 8 +- .../SQLiteLocalStorageAdapter.swift | 18 +- .../PinpointEvent+PinpointClientTypes.swift | 4 +- .../Analytics/PinpointEvent.swift | 18 +- .../AWSPinpointPluginConfiguration.swift | 14 +- .../Context/AWSPinpointFactory.swift | 6 +- .../PinpointContext+AWSPinpointBehavior.swift | 12 +- .../Context/PinpointContext.swift | 170 ++++++++----- .../Endpoint/EndpointClient.swift | 93 ++++--- .../Endpoint/PinpointEndpointProfile.swift | 38 +-- ...mmonRunTimeError+isConnectivityError.swift | 2 +- .../Extensions/Date+Formatting.swift | 6 +- .../PinpointClient+CredentialsProvider.swift | 2 +- .../SDKModels+AmplifyStringConvertible.swift | 4 +- .../ActivityTracking/ActivityTracker.swift | 34 ++- .../ActivityTracking/StateMachine.swift | 6 +- .../Session/PinpointSession.swift | 54 +++-- .../Session/SessionClient.swift | 76 +++--- .../AWSPinpointAnalyticsConstants.swift | 6 +- .../Constants/AWSPinpointErrorConstants.swift | 2 +- .../Support/ModeledErrorDescribable.swift | 2 +- .../Support/Utils/AmplifyArchiver.swift | 2 +- .../Utils/AnalyticsPropertiesModel.swift | 4 +- .../Utils/PinpointRequestsRegistry.swift | 5 +- .../Utils/ProvisioningProfileReader.swift | 15 +- .../Utils/RemoteNotificationsHelper.swift | 4 +- .../Support/Utils/RepeatingTimer.swift | 6 +- .../AWSPinpointFactoryTests.swift | 2 +- .../ActivityTrackerTests.swift | 16 +- .../AnalyticsClientTests.swift | 43 ++-- .../AnalyticsEventStorageTests.swift | 62 +++-- ...pointAnalyticsKeychainMigrationTests.swift | 64 ++--- .../EndpointClientTests.swift | 74 +++--- .../EndpointInformationProviderTests.swift | 4 +- .../EventRecorderTests.swift | 20 +- .../Mocks/MockActivityTracker.swift | 4 +- .../Mocks/MockAnalyticsClient.swift | 4 +- .../Mocks/MockAnalyticsEventStorage.swift | 8 +- .../Mocks/MockArchiver.swift | 6 +- .../Mocks/MockEndpointClient.swift | 4 +- .../Mocks/MockEventRecorder.swift | 9 +- .../Mocks/MockFileManager.swift | 3 +- .../Mocks/MockKeychainStore.swift | 4 +- .../Mocks/MockSQLiteLocalStorageAdapter.swift | 1 + .../Mocks/MockUserDefaults.swift | 2 +- .../PinpointRequestsRegistryTests.swift | 10 +- .../SQLiteLocalStorageAdapterTests.swift | 8 +- .../SessionClientTests.swift | 26 +- 78 files changed, 1281 insertions(+), 897 deletions(-) diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+ClientBehavior.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+ClientBehavior.swift index c2e168e217..343b51094e 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+ClientBehavior.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+ClientBehavior.swift @@ -10,8 +10,8 @@ import AWSPinpoint import Foundation @_spi(InternalAWSPinpoint) import InternalAWSPinpoint -extension AWSPinpointAnalyticsPlugin { - public func identifyUser(userId: String, userProfile: AnalyticsUserProfile?) { +public extension AWSPinpointAnalyticsPlugin { + func identifyUser(userId: String, userProfile: AnalyticsUserProfile?) { if !isEnabled { log.warn("Cannot identify user. Analytics is disabled. Call Amplify.Analytics.enable() to enable") return @@ -20,12 +20,14 @@ extension AWSPinpointAnalyticsPlugin { Task { var currentEndpointProfile = await pinpoint.currentEndpointProfile() currentEndpointProfile.addUserId(userId) - if let userProfile = userProfile { + if let userProfile { currentEndpointProfile.addUserProfile(userProfile) } do { - try await pinpoint.updateEndpoint(with: currentEndpointProfile, - source: .analytics) + try await pinpoint.updateEndpoint( + with: currentEndpointProfile, + source: .analytics + ) Amplify.Hub.dispatchIdentifyUser(userId, userProfile: userProfile) } catch { Amplify.Hub.dispatchIdentifyUser(AnalyticsErrorHelper.getDefaultError(error)) @@ -33,7 +35,7 @@ extension AWSPinpointAnalyticsPlugin { } } - public func record(event: AnalyticsEvent) { + func record(event: AnalyticsEvent) { if !isEnabled { log.warn("Cannot record events. Analytics is disabled. Call Amplify.Analytics.enable() to enable") return @@ -55,12 +57,12 @@ extension AWSPinpointAnalyticsPlugin { } } - public func record(eventWithName eventName: String) { + func record(eventWithName eventName: String) { let event = BasicAnalyticsEvent(name: eventName) record(event: event) } - public func registerGlobalProperties(_ properties: [String: AnalyticsPropertyValue]) { + func registerGlobalProperties(_ properties: [String: AnalyticsPropertyValue]) { // TODO: check if there is a limit on total number of properties properties.forEach { key, _ in guard key.count >= 1, key.count <= 50 else { @@ -75,13 +77,13 @@ extension AWSPinpointAnalyticsPlugin { } } - public func unregisterGlobalProperties(_ keys: Set?) { + func unregisterGlobalProperties(_ keys: Set?) { Task { await unregisterGlobalProperties(keys) } } - public func flushEvents() { + func flushEvents() { if !isEnabled { log.warn("Cannot flushEvents. Analytics is disabled. Call Amplify.Analytics.enable() to enable") return @@ -105,18 +107,18 @@ extension AWSPinpointAnalyticsPlugin { } } - public func enable() { + func enable() { isEnabled = true } - public func disable() { + func disable() { isEnabled = false } /// Retrieve the escape hatch to perform actions directly on PinpointClient. /// /// - Returns: PinpointClientProtocol instance - public func getEscapeHatch() -> PinpointClientProtocol { + func getEscapeHatch() -> PinpointClientProtocol { pinpoint.pinpointClient } @@ -128,7 +130,7 @@ extension AWSPinpointAnalyticsPlugin { } private func unregisterGlobalProperties(_ keys: Set?) async { - guard let keys = keys else { + guard let keys else { for (key, value) in globalProperties { await pinpoint.removeGlobalProperty(value, forKey: key) } diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Configure.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Configure.swift index 2acad0b80b..33a9cd9850 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Configure.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Configure.swift @@ -11,7 +11,7 @@ import Foundation @_spi(InternalAWSPinpoint) import InternalAWSPinpoint import Network -extension AWSPinpointAnalyticsPlugin { +public extension AWSPinpointAnalyticsPlugin { /// Configures AWSPinpointAnalyticsPlugin with the specified configuration. /// /// This method will be invoked as part of the Amplify configuration flow. @@ -19,7 +19,7 @@ extension AWSPinpointAnalyticsPlugin { /// - Parameter configuration: The configuration specified for this plugin /// - Throws: /// - PluginError.pluginConfigurationError: If one of the configuration values is invalid or empty - public func configure(using configuration: Any?) throws { + func configure(using configuration: Any?) throws { let pluginConfiguration: AWSPinpointAnalyticsPluginConfiguration if let config = configuration as? AmplifyOutputsData { print(config) @@ -45,7 +45,7 @@ extension AWSPinpointAnalyticsPlugin { } /// Configure AWSPinpointAnalyticsPlugin programatically using AWSPinpointAnalyticsPluginConfiguration - public func configure(using configuration: AWSPinpointAnalyticsPluginConfiguration) throws { + func configure(using configuration: AWSPinpointAnalyticsPluginConfiguration) throws { let pinpoint = try AWSPinpointFactory.sharedPinpoint( appId: configuration.appId, region: configuration.region @@ -82,10 +82,12 @@ extension AWSPinpointAnalyticsPlugin { // MARK: Internal /// Internal configure method to set the properties of the plugin - func configure(pinpoint: AWSPinpointBehavior, - networkMonitor: NetworkMonitor, - globalProperties: AtomicDictionary = [:], - isEnabled: Bool = true) { + internal func configure( + pinpoint: AWSPinpointBehavior, + networkMonitor: NetworkMonitor, + globalProperties: AtomicDictionary = [:], + isEnabled: Bool = true + ) { self.pinpoint = pinpoint self.networkMonitor = networkMonitor self.globalProperties = globalProperties diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Options.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Options.swift index 9849e6e9f5..ac44e7e82f 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Options.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Options.swift @@ -7,8 +7,8 @@ import Foundation -extension AWSPinpointAnalyticsPlugin { - public struct Options { +public extension AWSPinpointAnalyticsPlugin { + struct Options { static let defaultAutoFlushEventsInterval: TimeInterval = 60 static let defaultTrackAppSession = true @@ -16,14 +16,18 @@ extension AWSPinpointAnalyticsPlugin { public let trackAppSessions: Bool #if os(macOS) - public init(autoFlushEventsInterval: TimeInterval = 60, - trackAppSessions: Bool = true) { + public init( + autoFlushEventsInterval: TimeInterval = 60, + trackAppSessions: Bool = true + ) { self.autoFlushEventsInterval = autoFlushEventsInterval self.trackAppSessions = trackAppSessions } #else - public init(autoFlushEventsInterval: TimeInterval = 60, - trackAppSessions: Bool = true) { + public init( + autoFlushEventsInterval: TimeInterval = 60, + trackAppSessions: Bool = true + ) { self.autoFlushEventsInterval = autoFlushEventsInterval self.trackAppSessions = trackAppSessions } diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Reset.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Reset.swift index c6e43f86da..3c2c0dc32f 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Reset.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/AWSPinpointAnalyticsPlugin+Reset.swift @@ -9,9 +9,9 @@ import Amplify import Foundation @_spi(InternalAWSPinpoint) import InternalAWSPinpoint -extension AWSPinpointAnalyticsPlugin { +public extension AWSPinpointAnalyticsPlugin { /// Resets the state of the plugin - public func reset() async { + func reset() async { if pinpoint != nil { pinpoint = nil } diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Configuration/AWSPinpointAnalyticsPluginConfiguration.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Configuration/AWSPinpointAnalyticsPluginConfiguration.swift index 44456d7c60..1d625d7518 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Configuration/AWSPinpointAnalyticsPluginConfiguration.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Configuration/AWSPinpointAnalyticsPluginConfiguration.swift @@ -6,8 +6,8 @@ // @_spi(InternalAmplifyConfiguration) import Amplify -import AWSPinpoint import AWSClientRuntime +import AWSPinpoint import Foundation @_spi(InternalAWSPinpoint) import InternalAWSPinpoint @@ -58,9 +58,11 @@ public struct AWSPinpointAnalyticsPluginConfiguration { if let options { configOptions = options } else { - configOptions = .init( - autoFlushEventsInterval: try Self.getAutoFlushEventsInterval(configObject), - trackAppSessions: try Self.getTrackAppSessions(configObject)) + configOptions = try .init( + autoFlushEventsInterval: Self.getAutoFlushEventsInterval(configObject), + trackAppSessions: Self.getTrackAppSessions(configObject) + ) + } let autoSessionTrackingInterval = try Self.getAutoSessionTrackingInterval(configObject) @@ -71,14 +73,18 @@ public struct AWSPinpointAnalyticsPluginConfiguration { Self.logger.warn("Having different regions for Analytics and Targeting operations is not supported. The Analytics region will be used.") } - self.init(appId: pluginConfiguration.appId, - region: pluginConfiguration.region, - autoSessionTrackingInterval: autoSessionTrackingInterval, - options: configOptions) + self.init( + appId: pluginConfiguration.appId, + region: pluginConfiguration.region, + autoSessionTrackingInterval: autoSessionTrackingInterval, + options: configOptions + ) } - init(_ configuration: AmplifyOutputsData, - options: AWSPinpointAnalyticsPlugin.Options) throws { + init( + _ configuration: AmplifyOutputsData, + options: AWSPinpointAnalyticsPlugin.Options + ) throws { guard let analyticsConfig = configuration.analytics else { throw PluginError.pluginConfigurationError( AnalyticsPluginErrorConstant.missingAnalyticsCategoryConfiguration.errorDescription, @@ -93,16 +99,20 @@ public struct AWSPinpointAnalyticsPluginConfiguration { ) } - self.init(appId: pinpointAnalyticsConfig.appId, - region: pinpointAnalyticsConfig.awsRegion, - autoSessionTrackingInterval: Self.defaultAutoSessionTrackingInterval, - options: options) + self.init( + appId: pinpointAnalyticsConfig.appId, + region: pinpointAnalyticsConfig.awsRegion, + autoSessionTrackingInterval: Self.defaultAutoSessionTrackingInterval, + options: options + ) } - init(appId: String, - region: String, - autoSessionTrackingInterval: TimeInterval, - options: AWSPinpointAnalyticsPlugin.Options) { + init( + appId: String, + region: String, + autoSessionTrackingInterval: TimeInterval, + options: AWSPinpointAnalyticsPlugin.Options + ) { self.appId = appId self.region = region self.autoSessionTrackingInterval = autoSessionTrackingInterval @@ -148,7 +158,7 @@ public struct AWSPinpointAnalyticsPluginConfiguration { private static func getAutoSessionTrackingInterval(_ configuration: [String: JSONValue]) throws -> TimeInterval { guard let autoSessionTrackingInterval = configuration[autoSessionTrackingIntervalKey] else { - return Self.defaultAutoSessionTrackingInterval + return defaultAutoSessionTrackingInterval } guard case let .number(autoSessionTrackingIntervalValue) = autoSessionTrackingInterval else { diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Constants/AnalyticsErrorConstants.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Constants/AnalyticsErrorConstants.swift index 2ea40f5eb7..49cc32f2ba 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Constants/AnalyticsErrorConstants.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Constants/AnalyticsErrorConstants.swift @@ -10,7 +10,7 @@ import Foundation typealias AnalyticsPluginErrorString = (errorDescription: ErrorDescription, recoverySuggestion: RecoverySuggestion) -struct AnalyticsPluginErrorConstant { +enum AnalyticsPluginErrorConstant { static let decodeConfigurationError: AnalyticsPluginErrorString = ( "Unable to decode configuration", "Make sure the plugin configuration is JSONValue" diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/AWSPinpointAnalyticsPlugin+HubCategory.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/AWSPinpointAnalyticsPlugin+HubCategory.swift index a51cb40aee..286274402c 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/AWSPinpointAnalyticsPlugin+HubCategory.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/AWSPinpointAnalyticsPlugin+HubCategory.swift @@ -11,8 +11,10 @@ import Foundation extension HubCategory { func dispatchIdentifyUser(_ identityId: String, userProfile: AnalyticsUserProfile?) { - let payload = HubPayload(eventName: HubPayload.EventName.Analytics.identifyUser, - data: (identityId, userProfile)) + let payload = HubPayload( + eventName: HubPayload.EventName.Analytics.identifyUser, + data: (identityId, userProfile) + ) dispatch(to: .analytics, payload: payload) } diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/PinpointEvent+AnalyticsEvent.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/PinpointEvent+AnalyticsEvent.swift index bc51eec63c..f42e5cd596 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/PinpointEvent+AnalyticsEvent.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Extensions/PinpointEvent+AnalyticsEvent.swift @@ -9,8 +9,8 @@ import Amplify import Foundation @_spi(InternalAWSPinpoint) import InternalAWSPinpoint -extension PinpointEvent { - public func asAnalyticsEvent() -> AnalyticsEvent { +public extension PinpointEvent { + func asAnalyticsEvent() -> AnalyticsEvent { var properties: AnalyticsProperties = [:] for attribute in attributes { @@ -21,12 +21,14 @@ extension PinpointEvent { properties[metric.key] = metric.value } - return BasicAnalyticsEvent(name: eventType, - properties: properties) + return BasicAnalyticsEvent( + name: eventType, + properties: properties + ) } } -extension Array where Element == PinpointEvent { +extension [PinpointEvent] { func asAnalyticsEventArray() -> [AnalyticsEvent] { map { $0.asAnalyticsEvent() } } diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AWSPinpoint+AnalyticsErrorConvertible.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AWSPinpoint+AnalyticsErrorConvertible.swift index 42c5464f9e..d042e981cb 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AWSPinpoint+AnalyticsErrorConvertible.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AWSPinpoint+AnalyticsErrorConvertible.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify import AWSPinpoint import ClientRuntime +import Foundation extension AWSPinpoint.BadRequestException: AnalyticsErrorConvertible { var analyticsError: AnalyticsError { diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorConvertible.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorConvertible.swift index e21c889309..d422e9a13e 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorConvertible.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorConvertible.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation protocol AnalyticsErrorConvertible { var analyticsError: AnalyticsError { get } diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorHelper.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorHelper.swift index da6a74fe7b..93167a2d8a 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorHelper.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/AnalyticsErrorHelper.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify import AwsCommonRuntimeKit +import Foundation enum AnalyticsErrorHelper { static func getDefaultError(_ error: Error) -> AnalyticsError { diff --git a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/CommonRunTimeError+AnalyticsErrorConvertible.swift b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/CommonRunTimeError+AnalyticsErrorConvertible.swift index b65918f472..07784736d3 100644 --- a/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/CommonRunTimeError+AnalyticsErrorConvertible.swift +++ b/AmplifyPlugins/Analytics/Sources/AWSPinpointAnalyticsPlugin/Support/Utils/CommonRunTimeError+AnalyticsErrorConvertible.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify -@_spi(InternalAWSPinpoint) import InternalAWSPinpoint import AwsCommonRuntimeKit +import Foundation +@_spi(InternalAWSPinpoint) import InternalAWSPinpoint extension CommonRunTimeError: AnalyticsErrorConvertible { var analyticsError: AnalyticsError { diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginAmplifyVersionableTests.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginAmplifyVersionableTests.swift index e9922169db..cdbb482f27 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginAmplifyVersionableTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginAmplifyVersionableTests.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import XCTest import AWSPinpointAnalyticsPlugin +import XCTest // swiftlint:disable:next type_name class AWSPinpointAnalyticsPluginAmplifyVersionableTests: XCTestCase { diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginClientBehaviorTests.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginClientBehaviorTests.swift index 92c4636fd3..d78ec37ffb 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginClientBehaviorTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginClientBehaviorTests.swift @@ -7,10 +7,10 @@ import Amplify import AWSPinpoint -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint -@testable import AWSPinpointAnalyticsPlugin -@testable import AmplifyTestCommon import XCTest +@testable import AmplifyTestCommon +@testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint // swiftlint:disable:next type_name class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginTestBase { @@ -18,16 +18,20 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT let testIdentityId = "identityId" let testEmail = "testEmail" let testPlan = "testPlan" - let testProperties: [String: AnalyticsPropertyValue] = ["keyString": "value", - "keyInt": 123, - "keyDouble": 1.2, - "keyBool": true] - let testLocation = AnalyticsUserProfile.Location(latitude: 12, - longitude: 34, - postalCode: "98122", - city: "Seattle", - region: "WA", - country: "USA") + let testProperties: [String: AnalyticsPropertyValue] = [ + "keyString": "value", + "keyInt": 123, + "keyDouble": 1.2, + "keyBool": true + ] + let testLocation = AnalyticsUserProfile.Location( + latitude: 12, + longitude: 34, + postalCode: "98122", + city: "Seattle", + region: "WA", + country: "USA" + ) // MARK: IdentifyUser API @@ -52,13 +56,17 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT } } - let userProfile = AnalyticsUserProfile(name: testName, - email: testEmail, - plan: testPlan, - location: testLocation, - properties: testProperties) - var expectedEndpointProfile = PinpointEndpointProfile(applicationId: "appId", - endpointId: "endpointId") + let userProfile = AnalyticsUserProfile( + name: testName, + email: testEmail, + plan: testPlan, + location: testLocation, + properties: testProperties + ) + var expectedEndpointProfile = PinpointEndpointProfile( + applicationId: "appId", + endpointId: "endpointId" + ) expectedEndpointProfile.addUserId(testIdentityId) expectedEndpointProfile.addUserProfile(userProfile) @@ -86,8 +94,10 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT /// Then: AWSPinpoint.currentEndpoint and updateEndpoint methods are called /// and Hub Analytics.identifyUser event is dispatched with an error func testIdentifyUserDispatchesErrorForPinpointError() async throws { - mockPinpoint.updateEndpointProfileResult = .failure(NSError(domain: "domain", - code: 1)) + mockPinpoint.updateEndpointProfileResult = .failure(NSError( + domain: "domain", + code: 1 + )) let analyticsEventReceived = expectation(description: "Analytics event was received on the hub plugin") _ = plugin.listen(to: .analytics, isIncluded: nil) { payload in @@ -103,13 +113,17 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT } } - let userProfile = AnalyticsUserProfile(name: testName, - email: testEmail, - plan: testPlan, - location: testLocation, - properties: testProperties) - var expectedEndpointProfile = PinpointEndpointProfile(applicationId: "appId", - endpointId: "endpointId") + let userProfile = AnalyticsUserProfile( + name: testName, + email: testEmail, + plan: testPlan, + location: testLocation, + properties: testProperties + ) + var expectedEndpointProfile = PinpointEndpointProfile( + applicationId: "appId", + endpointId: "endpointId" + ) expectedEndpointProfile.addUserId(testIdentityId) expectedEndpointProfile.addUserProfile(userProfile) @@ -170,9 +184,11 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT /// Then: AWSPinpoint.createEvent and record methods are called /// and Hub Analytics.record event is dispatched with a error func testRecordEventDispatchesErrorForPinpointError() async { - mockPinpoint.recordResult = .failure(NSError(domain: "domain", - code: 1, - userInfo: nil)) + mockPinpoint.recordResult = .failure(NSError( + domain: "domain", + code: 1, + userInfo: nil + )) let expectedPinpointEvent = PinpointEvent(eventType: testName, session: PinpointSession(appId: "", uniqueId: "")) mockPinpoint.createEventResult = expectedPinpointEvent expectedPinpointEvent.addProperties(testProperties) @@ -246,9 +262,11 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT /// Then: AWSPinpoint.createEvent and record methods are called /// and Hub Analytics.record event is dispatched with a error func testRecordEventWithNameDispatchesErrorForPinpointError() async { - mockPinpoint.recordResult = .failure(NSError(domain: "domain", - code: 1, - userInfo: nil)) + mockPinpoint.recordResult = .failure(NSError( + domain: "domain", + code: 1, + userInfo: nil + )) let expectedPinpointEvent = PinpointEvent(eventType: testName, session: PinpointSession(appId: "", uniqueId: "")) mockPinpoint.createEventResult = expectedPinpointEvent @@ -281,9 +299,9 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT func testRegisterGlobalProperties() async { mockPinpoint.addGlobalPropertyExpectation = expectation(description: "Add global property called") mockPinpoint.addGlobalPropertyExpectation?.expectedFulfillmentCount = testProperties.count - + analyticsPlugin.registerGlobalProperties(testProperties) - + await fulfillment(of: [mockPinpoint.addGlobalPropertyExpectation!], timeout: 1) XCTAssertEqual(analyticsPlugin.globalProperties.count, testProperties.count) XCTAssertTrue(mockPinpoint.addGlobalMetricCalled > 0) @@ -310,7 +328,7 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT func testUnregisterGlobalProperties() async { mockPinpoint.removeGlobalPropertyExpectation = expectation(description: "Remove global property called") mockPinpoint.removeGlobalPropertyExpectation?.expectedFulfillmentCount = testProperties.count - + analyticsPlugin.globalProperties = AtomicDictionary(initialValue: testProperties) analyticsPlugin.unregisterGlobalProperties(Set(testProperties.keys)) @@ -343,8 +361,10 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT /// Then: AWSPinpoint.submitEvents is invoked /// and Hub Analytics.flushEvents event is dispatched with submitted events func testFlushEvents_isOnline() async { - let result = [PinpointEvent(eventType: "1", session: PinpointSession(appId: "", uniqueId: "")), - PinpointEvent(eventType: "2", session: PinpointSession(appId: "", uniqueId: ""))] + let result = [ + PinpointEvent(eventType: "1", session: PinpointSession(appId: "", uniqueId: "")), + PinpointEvent(eventType: "2", session: PinpointSession(appId: "", uniqueId: "")) + ] mockNetworkMonitor.isOnline = true mockPinpoint.submitEventsResult = .success(result) let methodWasInvokedOnPlugin = expectation(description: "method was invoked on plugin") @@ -365,7 +385,7 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT await fulfillment(of: [methodWasInvokedOnPlugin], timeout: 1) mockPinpoint.verifySubmitEvents() } - + /// Given: The device does not have internet access /// When: AnalyticsPlugin.flushEvents is invoked /// Then: AWSPinpoint.submitEvents is invoked @@ -407,9 +427,11 @@ class AWSPinpointAnalyticsPluginClientBehaviorTests: AWSPinpointAnalyticsPluginT /// Then: AWSPinpoint.submitEvents is invoked /// and Hub Analytics.flushEvents event is dispatched with error func testFlushEventsDispatchesErrorForPinpointError() async { - mockPinpoint.submitEventsResult = .failure(NSError(domain: "domain", - code: 1, - userInfo: nil)) + mockPinpoint.submitEventsResult = .failure(NSError( + domain: "domain", + code: 1, + userInfo: nil + )) let methodWasInvokedOnPlugin = expectation(description: "method was invoked on plugin") _ = plugin.listen(to: .analytics, isIncluded: nil) { payload in diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginConfigureTests.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginConfigureTests.swift index 4c14742004..3c65df01f5 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginConfigureTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginConfigureTests.swift @@ -5,19 +5,19 @@ // SPDX-License-Identifier: Apache-2.0 // +import XCTest @testable @_spi(InternalAmplifyConfiguration) import Amplify @testable import AmplifyTestCommon -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint @testable import AWSPinpointAnalyticsPlugin -import XCTest +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint class AWSPinpointAnalyticsPluginConfigureTests: AWSPinpointAnalyticsPluginTestBase { - + override func setUp() async throws { AWSPinpointFactory.credentialsProvider = MockCredentialsProvider() try await super.setUp() } - + // MARK: Plugin Key test func testPluginKey() { @@ -95,7 +95,8 @@ class AWSPinpointAnalyticsPluginConfigureTests: AWSPinpointAnalyticsPluginTestBa let analyticsPlugin = AWSPinpointAnalyticsPlugin( options: .init( autoFlushEventsInterval: 50, - trackAppSessions: true)) + trackAppSessions: true + )) try analyticsPlugin.configure(using: analyticsPluginConfig) XCTAssertNotNil(analyticsPlugin.pinpoint) @@ -115,7 +116,8 @@ class AWSPinpointAnalyticsPluginConfigureTests: AWSPinpointAnalyticsPluginTestBa XCTFail("Analytics configuration should not succeed") } catch { guard let pluginError = error as? PluginError, - case .pluginConfigurationError = pluginError else { + case .pluginConfigurationError = pluginError + else { XCTFail("Should throw invalidConfiguration exception. But received \(error) ") return } @@ -126,8 +128,10 @@ class AWSPinpointAnalyticsPluginConfigureTests: AWSPinpointAnalyticsPluginTestBa func testConfigure_WithAmplifyOutputs() { let config = AmplifyOutputsData.init(analytics: .init( - amazonPinpoint: .init(awsRegion: testRegion, - appId: testAppId))) + amazonPinpoint: .init( + awsRegion: testRegion, + appId: testAppId + ))) do { let analyticsPlugin = AWSPinpointAnalyticsPlugin() @@ -148,13 +152,16 @@ class AWSPinpointAnalyticsPluginConfigureTests: AWSPinpointAnalyticsPluginTestBa func testConfigure_WithAmplifyOutputsAndOptions() { let config = AmplifyOutputsData.init(analytics: .init( - amazonPinpoint: .init(awsRegion: testRegion, - appId: testAppId))) + amazonPinpoint: .init( + awsRegion: testRegion, + appId: testAppId + ))) do { let analyticsPlugin = AWSPinpointAnalyticsPlugin(options: .init( autoFlushEventsInterval: 100, - trackAppSessions: false)) + trackAppSessions: false + )) try analyticsPlugin.configure(using: config) XCTAssertNotNil(analyticsPlugin.pinpoint) diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginResetTests.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginResetTests.swift index a5338f8e5e..b2e8be43be 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginResetTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginResetTests.swift @@ -7,8 +7,8 @@ import Amplify @_spi(InternalAWSPinpoint) import InternalAWSPinpoint -@testable import AWSPinpointAnalyticsPlugin import XCTest +@testable import AWSPinpointAnalyticsPlugin class AWSPinpointAnalyticsPluginResetTests: AWSPinpointAnalyticsPluginTestBase { func testReset() async { diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginTestBase.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginTestBase.swift index 6e637db34a..bfefb36938 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginTestBase.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/AWSPinpointAnalyticsPluginTestBase.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // +import XCTest @testable import Amplify @testable import AmplifyTestCommon -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint @testable import AWSPinpointAnalyticsPlugin -import XCTest +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint class AWSPinpointAnalyticsPluginTestBase: XCTestCase { var analyticsPlugin: AWSPinpointAnalyticsPlugin! @@ -24,7 +24,8 @@ class AWSPinpointAnalyticsPluginTestBase: XCTestCase { var plugin: HubCategoryPlugin { guard let plugin = try? Amplify.Hub.getPlugin(for: "awsHubPlugin"), - plugin.key == "awsHubPlugin" else { + plugin.key == "awsHubPlugin" + else { fatalError("Could not access awsHubPlugin") } return plugin @@ -36,8 +37,10 @@ class AWSPinpointAnalyticsPluginTestBase: XCTestCase { mockPinpoint = MockAWSPinpoint() mockNetworkMonitor = MockNetworkMonitor() - analyticsPlugin.configure(pinpoint: mockPinpoint, - networkMonitor: mockNetworkMonitor) + analyticsPlugin.configure( + pinpoint: mockPinpoint, + networkMonitor: mockNetworkMonitor + ) await Amplify.reset() let config = AmplifyConfiguration() diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests.swift index e4aeffa943..129a735cbd 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests.swift @@ -5,10 +5,10 @@ // SPDX-License-Identifier: Apache-2.0 // -@testable @_spi(InternalAmplifyConfiguration) import Amplify import XCTest -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint +@testable @_spi(InternalAmplifyConfiguration) import Amplify @testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint // swiftlint:disable:next type_name class AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests: XCTestCase { @@ -34,20 +34,29 @@ class AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests: XCTestCase { XCTAssertNotNil(result) XCTAssertEqual(result.appId, testAppId) XCTAssertEqual(result.region, testRegion) - XCTAssertEqual(result.options.autoFlushEventsInterval, - AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval) - XCTAssertEqual(result.options.trackAppSessions, - AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession) - XCTAssertEqual(result.autoSessionTrackingInterval, - AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval) + XCTAssertEqual( + result.options.autoFlushEventsInterval, + AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval + ) + XCTAssertEqual( + result.options.trackAppSessions, + AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession + ) + XCTAssertEqual( + result.autoSessionTrackingInterval, + AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval + ) } func testConfiguration_OptionsOverride() throws { let config = AmplifyOutputsData(analytics: .init(amazonPinpoint: .init(awsRegion: testRegion, appId: appId))) let result = try AWSPinpointAnalyticsPluginConfiguration( config, - options: .init(autoFlushEventsInterval: 100, - trackAppSessions: false)) + options: .init( + autoFlushEventsInterval: 100, + trackAppSessions: false + ) + ) XCTAssertNotNil(result) XCTAssertEqual(result.appId, testAppId) XCTAssertEqual(result.region, testRegion) @@ -65,8 +74,10 @@ class AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests: XCTestCase { XCTFail("Expected to catch PluginError.pluginConfigurationError.") return } - XCTAssertEqual(errorDescription, - AnalyticsPluginErrorConstant.missingAnalyticsCategoryConfiguration.errorDescription) + XCTAssertEqual( + errorDescription, + AnalyticsPluginErrorConstant.missingAnalyticsCategoryConfiguration.errorDescription + ) } } @@ -79,8 +90,10 @@ class AWSPinpointAnalyticsPluginAmplifyOutputsConfigurationTests: XCTestCase { XCTFail("Expected to catch PluginError.pluginConfigurationError.") return } - XCTAssertEqual(errorDescription, - AnalyticsPluginErrorConstant.missingAmazonPinpointConfiguration.errorDescription) + XCTAssertEqual( + errorDescription, + AnalyticsPluginErrorConstant.missingAmazonPinpointConfiguration.errorDescription + ) } } } diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginConfigurationTests.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginConfigurationTests.swift index f7b8f7216f..2407a7fea3 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginConfigurationTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Configuration/AWSPinpointAnalyticsPluginConfigurationTests.swift @@ -7,8 +7,8 @@ import Amplify import XCTest -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint @testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint // swiftlint:disable:next type_name class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { @@ -42,17 +42,23 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTAssertNotNil(config) XCTAssertEqual(config.appId, testAppId) XCTAssertEqual(config.region, testRegion) - XCTAssertEqual(config.options.autoFlushEventsInterval, - AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval) - XCTAssertEqual(config.options.trackAppSessions, - AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession) - XCTAssertEqual(config.autoSessionTrackingInterval, - AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval) + XCTAssertEqual( + config.options.autoFlushEventsInterval, + AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval + ) + XCTAssertEqual( + config.options.trackAppSessions, + AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession + ) + XCTAssertEqual( + config.autoSessionTrackingInterval, + AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval + ) } catch { XCTFail("Failed to instantiate analytics plugin configuration") } } - + func testConfigureSuccess_withoutTargetingConfiguration() throws { let analyticsPluginConfig = JSONValue( dictionaryLiteral: @@ -64,12 +70,18 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTAssertNotNil(config) XCTAssertEqual(config.appId, testAppId) XCTAssertEqual(config.region, testRegion) - XCTAssertEqual(config.options.autoFlushEventsInterval, - AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval) - XCTAssertEqual(config.options.trackAppSessions, - AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession) - XCTAssertEqual(config.autoSessionTrackingInterval, - AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval) + XCTAssertEqual( + config.options.autoFlushEventsInterval, + AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval + ) + XCTAssertEqual( + config.options.trackAppSessions, + AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession + ) + XCTAssertEqual( + config.autoSessionTrackingInterval, + AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval + ) } catch { XCTFail("Failed to instantiate analytics plugin configuration") } @@ -88,10 +100,14 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTAssertEqual(config.appId, testAppId) XCTAssertEqual(config.region, testRegion) XCTAssertEqual(config.options.autoFlushEventsInterval, testAutoFlushInterval) - XCTAssertEqual(config.options.trackAppSessions, - AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession) - XCTAssertEqual(config.autoSessionTrackingInterval, - AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval) + XCTAssertEqual( + config.options.trackAppSessions, + AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession + ) + XCTAssertEqual( + config.autoSessionTrackingInterval, + AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval + ) } catch { XCTFail("Failed to instantiate analytics plugin configuration") } @@ -110,8 +126,10 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTFail("Expected PluginError pluginConfigurationError, got: \(error)") return } - XCTAssertEqual(errorDescription, - AnalyticsPluginErrorConstant.invalidAutoFlushEventsInterval.errorDescription) + XCTAssertEqual( + errorDescription, + AnalyticsPluginErrorConstant.invalidAutoFlushEventsInterval.errorDescription + ) } } @@ -127,11 +145,15 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTAssertNotNil(config) XCTAssertEqual(config.appId, testAppId) XCTAssertEqual(config.region, testRegion) - XCTAssertEqual(config.options.autoFlushEventsInterval, - AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval) + XCTAssertEqual( + config.options.autoFlushEventsInterval, + AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval + ) XCTAssertEqual(config.options.trackAppSessions, testTrackAppSession) - XCTAssertEqual(config.autoSessionTrackingInterval, - AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval) + XCTAssertEqual( + config.autoSessionTrackingInterval, + AWSPinpointAnalyticsPluginConfiguration.defaultAutoSessionTrackingInterval + ) } catch { XCTFail("Failed to instantiate analytics plugin configuration") } @@ -149,8 +171,10 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTAssertNotNil(config) XCTAssertEqual(config.appId, testAppId) XCTAssertEqual(config.region, testRegion) - XCTAssertEqual(config.options.autoFlushEventsInterval, - AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval) + XCTAssertEqual( + config.options.autoFlushEventsInterval, + AWSPinpointAnalyticsPlugin.Options.defaultAutoFlushEventsInterval + ) XCTAssertEqual(config.options.trackAppSessions, AWSPinpointAnalyticsPlugin.Options.defaultTrackAppSession) XCTAssertEqual(config.autoSessionTrackingInterval, testAutoSessionTrackingInterval) } catch { @@ -171,8 +195,10 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTFail("Expected PluginError pluginConfigurationError, got: \(error)") return } - XCTAssertEqual(errorDescription, - AnalyticsPluginErrorConstant.invalidAutoSessionTrackingInterval.errorDescription) + XCTAssertEqual( + errorDescription, + AnalyticsPluginErrorConstant.invalidAutoSessionTrackingInterval.errorDescription + ) } } @@ -184,13 +210,15 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTFail("Expected PluginError pluginConfigurationError, got: \(error)") return } - XCTAssertEqual(errorDescription, - AnalyticsPluginErrorConstant.configurationObjectExpected.errorDescription) + XCTAssertEqual( + errorDescription, + AnalyticsPluginErrorConstant.configurationObjectExpected.errorDescription + ) } } func testConfigureThrowsErrorForMissingPinpointAnalyticsConfiguration() { - + let analyticsPluginConfig = JSONValue( dictionaryLiteral: (AWSPinpointAnalyticsPluginConfiguration.regionConfigKey, region) @@ -201,8 +229,10 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTFail("Expected PluginError pluginConfigurationError, got: \(error)") return } - XCTAssertEqual(errorDescription, - AnalyticsPluginErrorConstant.missingPinpointAnalyicsConfiguration.errorDescription) + XCTAssertEqual( + errorDescription, + AnalyticsPluginErrorConstant.missingPinpointAnalyicsConfiguration.errorDescription + ) } } @@ -218,8 +248,10 @@ class AWSPinpointAnalyticsPluginConfigurationTests: XCTestCase { XCTFail("Expected PluginError pluginConfigurationError, got: \(error)") return } - XCTAssertEqual(errorDescription, - AWSPinpointErrorConstants.pinpointConfigurationExpected.errorDescription) + XCTAssertEqual( + errorDescription, + AWSPinpointErrorConstants.pinpointConfigurationExpected.errorDescription + ) } } diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Analytics.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Analytics.swift index 9466403f55..8de6ddffea 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Analytics.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Analytics.swift @@ -7,13 +7,13 @@ import Amplify import AWSPinpoint -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint -@testable import AWSPinpointAnalyticsPlugin import Foundation import StoreKit +@testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint extension MockAWSPinpoint { - public func addGlobalProperty(_ value: AnalyticsPropertyValue, forKey: String) { + func addGlobalProperty(_ value: AnalyticsPropertyValue, forKey: String) { if let value = value as? String { addGlobalAttribute(value, forKey: forKey) } else if let value = value as? Int { @@ -26,7 +26,7 @@ extension MockAWSPinpoint { addGlobalPropertyExpectation?.fulfill() } - public func removeGlobalProperty(_ value: AnalyticsPropertyValue, forKey: String) { + func removeGlobalProperty(_ value: AnalyticsPropertyValue, forKey: String) { if value is String || value is Bool { removeGlobalAttribute(forKey: forKey) } else if value is Int || value is Double { @@ -35,14 +35,14 @@ extension MockAWSPinpoint { removeGlobalPropertyExpectation?.fulfill() } - public func addGlobalAttribute(_ theValue: String, forKey theKey: String) { + func addGlobalAttribute(_ theValue: String, forKey theKey: String) { addGlobalAttributeCalled += 1 addGlobalAttributeValue = theValue addGlobalAttributeKey = theKey } - public func addGlobalAttribute(_ theValue: String, forKey theKey: String, forEventType theEventType: String) { + func addGlobalAttribute(_ theValue: String, forKey theKey: String, forEventType theEventType: String) { addGlobalAttributeCalled += 1 addGlobalAttributeValue = theValue @@ -50,14 +50,14 @@ extension MockAWSPinpoint { addGlobalAttributeEventType = theEventType } - public func addGlobalMetric(_ theValue: Double, forKey theKey: String) { + func addGlobalMetric(_ theValue: Double, forKey theKey: String) { addGlobalMetricCalled += 1 addGlobalMetricValue = theValue addGlobalMetricKey = theKey } - public func addGlobalMetric(_ theValue: Double, forKey theKey: String, forEventType theEventType: String) { + func addGlobalMetric(_ theValue: Double, forKey theKey: String, forEventType theEventType: String) { addGlobalMetricCalled += 1 addGlobalMetricValue = theValue @@ -65,30 +65,30 @@ extension MockAWSPinpoint { addGlobalMetricEventType = theEventType } - public func removeGlobalAttribute(forKey theKey: String) { + func removeGlobalAttribute(forKey theKey: String) { removeGlobalAttributeCalled += 1 removeGlobalAttributeKey = theKey } - public func removeGlobalAttribute(forKey theKey: String, forEventType theEventType: String) { + func removeGlobalAttribute(forKey theKey: String, forEventType theEventType: String) { removeGlobalAttributeCalled += 1 removeGlobalAttributeKey = theKey removeGlobalAttributeEventType = theEventType } - public func removeGlobalMetric(forKey theKey: String) { + func removeGlobalMetric(forKey theKey: String) { removeGlobalMetricCalled += 1 removeGlobalMetricKey = theKey } - public func removeGlobalMetric(forKey theKey: String, forEventType theEventType: String) { + func removeGlobalMetric(forKey theKey: String, forEventType theEventType: String) { removeGlobalMetricCalled += 1 removeGlobalMetricKey = theKey removeglobalMetricEventType = theEventType } - public func record(_ theEvent: PinpointEvent) async throws { + func record(_ theEvent: PinpointEvent) async throws { recordCalled += 1 recordEvent = theEvent @@ -97,15 +97,17 @@ extension MockAWSPinpoint { } } - public func createEvent(withEventType theEventType: String) -> PinpointEvent { + func createEvent(withEventType theEventType: String) -> PinpointEvent { createEventCalled += 1 createEventEventType = theEventType return createEventResult ?? createEmptyEvent() } - public func createAppleMonetizationEvent(with transaction: SKPaymentTransaction, - with product: SKProduct) -> PinpointEvent { + func createAppleMonetizationEvent( + with transaction: SKPaymentTransaction, + with product: SKProduct + ) -> PinpointEvent { createAppleMonetizationEventCalled += 1 createAppleMonetizationEventTransaction = transaction createAppleMonetizationEventProduct = product @@ -113,10 +115,12 @@ extension MockAWSPinpoint { return createAppleMonetizationEventResult ?? createEmptyEvent() } - public func createVirtualMonetizationEvent(withProductId theProductId: String, - withItemPrice theItemPrice: Double, - withQuantity theQuantity: Int, - withCurrency theCurrency: String) -> PinpointEvent { + func createVirtualMonetizationEvent( + withProductId theProductId: String, + withItemPrice theItemPrice: Double, + withQuantity theQuantity: Int, + withCurrency theCurrency: String + ) -> PinpointEvent { createVirtualMonetizationEventCalled += 1 createVirtualMonetizationEventProductId = theProductId createVirtualMonetizationEventItemPrice = theItemPrice @@ -126,11 +130,11 @@ extension MockAWSPinpoint { return createVirtualMonetizationEventResult ?? createEmptyEvent() } - public func submitEvents() async throws { + func submitEvents() async throws { submitEventsCalled += 1 } - public func submitEvents() async throws -> [PinpointEvent] { + func submitEvents() async throws -> [PinpointEvent] { submitEventsCalled += 1 switch submitEventsResult { case .success(let result): @@ -143,20 +147,24 @@ extension MockAWSPinpoint { } private func createEmptyEvent() -> PinpointEvent { - return PinpointEvent(eventType: "", - session: PinpointSession(appId: "", uniqueId: "")) + return PinpointEvent( + eventType: "", + session: PinpointSession(appId: "", uniqueId: "") + ) } - - public func setAutomaticSubmitEventsInterval(_ interval: TimeInterval, - onSubmit: AnalyticsClientBehaviour.SubmitResult?) { - + + func setAutomaticSubmitEventsInterval( + _ interval: TimeInterval, + onSubmit: AnalyticsClientBehaviour.SubmitResult? + ) { + } - - public func startTrackingSessions(backgroundTimeout: TimeInterval) { - + + func startTrackingSessions(backgroundTimeout: TimeInterval) { + } - func setRemoteGlobalAttributes(_ attributes: [String : String]) async { + func setRemoteGlobalAttributes(_ attributes: [String: String]) async { } } diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Targeting.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Targeting.swift index 429d2ffd8d..3dd090cf08 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Targeting.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint+Targeting.swift @@ -6,18 +6,18 @@ // import AWSPinpoint -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint -@testable import AWSPinpointAnalyticsPlugin import Foundation +@testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint extension MockAWSPinpoint { - public func currentEndpointProfile() -> PinpointEndpointProfile { + func currentEndpointProfile() -> PinpointEndpointProfile { currentEndpointProfileCalled += 1 return PinpointEndpointProfile(applicationId: applicationId, endpointId: endpointId) } - public func updateEndpointProfile() async throws { + func updateEndpointProfile() async throws { updateEndpointProfileCalled += 1 if case let .failure(error) = updateEndpointProfileResult { @@ -25,8 +25,10 @@ extension MockAWSPinpoint { } } - public func updateEndpoint(with endpointProfile: PinpointEndpointProfile, - source: AWSPinpointSource) async throws { + func updateEndpoint( + with endpointProfile: PinpointEndpointProfile, + source: AWSPinpointSource + ) async throws { updateEndpointProfileCalled += 1 updateEndpointProfileValue = endpointProfile @@ -35,27 +37,27 @@ extension MockAWSPinpoint { } } - public func addAttributes(_ attributes: [String], forKey key: String) { + func addAttributes(_ attributes: [String], forKey key: String) { addAttributeCalled += 1 addAttributeValue = attributes addAttributeKey = key } - public func removeAttributes(forKey key: String) { + func removeAttributes(forKey key: String) { removeAttributeCalled += 1 removeAttributeKey = key } - public func addMetric(_ metric: Double, forKey key: String) { + func addMetric(_ metric: Double, forKey key: String) { addMetricCalled += 1 addMetricValue = metric addMetricKey = key } - public func removeMetric(forKey theKey: String) { + func removeMetric(forKey theKey: String) { removeMetricCalled += 1 removeMetricKey = theKey diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint.swift index 9c445fb449..1e80ceca3d 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockAWSPinpoint.swift @@ -10,8 +10,8 @@ import Foundation import StoreKit import XCTest -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint @testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint class MockAWSPinpoint: AWSPinpointBehavior { let applicationId = "applicationId" @@ -81,7 +81,7 @@ class MockAWSPinpoint: AWSPinpointBehavior { var createAppleMonetizationEventResult: PinpointEvent? var createVirtualMonetizationEventResult: PinpointEvent? var submitEventsResult: Result<[PinpointEvent], Error>? - + var addGlobalPropertyExpectation: XCTestExpectation? var removeGlobalPropertyExpectation: XCTestExpectation? @@ -216,17 +216,21 @@ extension MockAWSPinpoint { XCTAssertEqual(createEventEventType, theEventType) } - public func verifyCreateAppleMonetizationEvent(with transaction: SKPaymentTransaction, - with product: SKProduct) { + public func verifyCreateAppleMonetizationEvent( + with transaction: SKPaymentTransaction, + with product: SKProduct + ) { XCTAssertEqual(createAppleMonetizationEventCalled, 1) XCTAssertEqual(createAppleMonetizationEventTransaction, transaction) XCTAssertEqual(createAppleMonetizationEventProduct, product) } - public func verifyCreateVirtualMonetizationEvent(withProductId theProductId: String, - withItemPrice theItemPrice: Double, - withQuantity theQuantity: Int, - withCurrency theCurrency: String) { + public func verifyCreateVirtualMonetizationEvent( + withProductId theProductId: String, + withItemPrice theItemPrice: Double, + withQuantity theQuantity: Int, + withCurrency theCurrency: String + ) { XCTAssertEqual(createVirtualMonetizationEventCalled, 1) XCTAssertEqual(createVirtualMonetizationEventProductId, theProductId) XCTAssertEqual(createVirtualMonetizationEventItemPrice, theItemPrice) diff --git a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockNetworkMonitor.swift b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockNetworkMonitor.swift index bcd1099b71..9298fcdd46 100644 --- a/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockNetworkMonitor.swift +++ b/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginUnitTests/Mocks/MockNetworkMonitor.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -@testable import AWSPinpointAnalyticsPlugin import Foundation +@testable import AWSPinpointAnalyticsPlugin class MockNetworkMonitor: NetworkMonitor { var isOnline = true diff --git a/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AWSPinpointAnalyticsPluginIntegrationTests/AWSPinpointAnalyticsPluginIntegrationTests.swift b/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AWSPinpointAnalyticsPluginIntegrationTests/AWSPinpointAnalyticsPluginIntegrationTests.swift index 3716620822..de5427eaff 100644 --- a/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AWSPinpointAnalyticsPluginIntegrationTests/AWSPinpointAnalyticsPluginIntegrationTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AWSPinpointAnalyticsPluginIntegrationTests/AWSPinpointAnalyticsPluginIntegrationTests.swift @@ -5,14 +5,14 @@ // SPDX-License-Identifier: Apache-2.0 // -import XCTest import AWSPinpoint +import XCTest -@testable import Amplify -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint -@testable import AWSPinpointAnalyticsPlugin import AWSCognitoAuthPlugin import Network +@testable import Amplify +@testable import AWSPinpointAnalyticsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint // swiftlint:disable:next type_name class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { @@ -20,7 +20,7 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { static let amplifyConfiguration = "testconfiguration/AWSPinpointAnalyticsPluginIntegrationTests-amplifyconfiguration" static let amplifyOutputs = "testconfiguration/AWSPinpointAnalyticsPluginIntegrationTests-amplify_outputs" static let analyticsPluginKey = "awsPinpointAnalyticsPlugin" - + var useGen2Configuration: Bool { ProcessInfo.processInfo.arguments.contains("GEN2") } @@ -65,21 +65,27 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } - let location = AnalyticsUserProfile.Location(latitude: 47.606209, - longitude: -122.332069, - postalCode: "98122", - city: "Seattle", - region: "WA", - country: "USA") - let properties = ["userPropertyStringKey": "userProperyStringValue", - "userPropertyIntKey": 123, - "userPropertyDoubleKey": 12.34, - "userPropertyBoolKey": true] as [String: AnalyticsPropertyValue] - let userProfile = AnalyticsUserProfile(name: "name", - email: "email", - plan: "plan", - location: location, - properties: properties) + let location = AnalyticsUserProfile.Location( + latitude: 47.606209, + longitude: -122.332069, + postalCode: "98122", + city: "Seattle", + region: "WA", + country: "USA" + ) + let properties = [ + "userPropertyStringKey": "userProperyStringValue", + "userPropertyIntKey": 123, + "userPropertyDoubleKey": 12.34, + "userPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] + let userProfile = AnalyticsUserProfile( + name: "name", + email: "email", + plan: "plan", + location: location, + properties: properties + ) Amplify.Analytics.identifyUser(userId: userId, userProfile: userProfile) await fulfillment(of: [identifyUserEvent], timeout: TestCommonConstants.networkTimeout) @@ -96,8 +102,10 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { func skip_testDeleteEndpointsForUser() async throws { let userId = "userId" let applicationId = await endpointClient().currentEndpointProfile().applicationId - let deleteEndpointsRequest = DeleteUserEndpointsInput(applicationId: applicationId, - userId: userId) + let deleteEndpointsRequest = DeleteUserEndpointsInput( + applicationId: applicationId, + userId: userId + ) do { let response = try await pinpointClient().deleteUserEndpoints(input: deleteEndpointsRequest) XCTAssertNotNil(response.endpointsResponse) @@ -118,7 +126,7 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + let flushEventsInvoked = expectation(description: "Flush events invoked") _ = Amplify.Hub.listen(to: .analytics, isIncluded: nil) { payload in if payload.eventName == HubPayload.EventName.Analytics.flushEvents { @@ -132,25 +140,29 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } - let globalProperties = ["globalPropertyStringKey": "eventProperyStringValue", - "globalPropertyIntKey": 123, - "globalPropertyDoubleKey": 12.34, - "globalPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let globalProperties = [ + "globalPropertyStringKey": "eventProperyStringValue", + "globalPropertyIntKey": 123, + "globalPropertyDoubleKey": 12.34, + "globalPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] Amplify.Analytics.registerGlobalProperties(globalProperties) - let properties = ["eventPropertyStringKey": "eventProperyStringValue", - "eventPropertyIntKey": 123, - "eventPropertyDoubleKey": 12.34, - "eventPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let properties = [ + "eventPropertyStringKey": "eventProperyStringValue", + "eventPropertyIntKey": 123, + "eventPropertyDoubleKey": 12.34, + "eventPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName", properties: properties) Amplify.Analytics.record(event: event) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) Amplify.Analytics.flushEvents() await fulfillment(of: [flushEventsInvoked], timeout: TestCommonConstants.networkTimeout) } - + /// Given: Analytics plugin /// When: An analytics event is recorded and flushed after the plugin is enabled /// Then: Flush Hub event is received @@ -163,7 +175,7 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + let flushEventsInvoked = expectation(description: "Flush events invoked") _ = Amplify.Hub.listen(to: .analytics, isIncluded: nil) { payload in if payload.eventName == HubPayload.EventName.Analytics.flushEvents { @@ -176,29 +188,33 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { flushEventsInvoked.fulfill() } } - + Amplify.Analytics.disable() Amplify.Analytics.enable() - let globalProperties = ["globalPropertyStringKey": "eventProperyStringValue", - "globalPropertyIntKey": 123, - "globalPropertyDoubleKey": 12.34, - "globalPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let globalProperties = [ + "globalPropertyStringKey": "eventProperyStringValue", + "globalPropertyIntKey": 123, + "globalPropertyDoubleKey": 12.34, + "globalPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] Amplify.Analytics.registerGlobalProperties(globalProperties) - let properties = ["eventPropertyStringKey": "eventProperyStringValue", - "eventPropertyIntKey": 123, - "eventPropertyDoubleKey": 12.34, - "eventPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let properties = [ + "eventPropertyStringKey": "eventProperyStringValue", + "eventPropertyIntKey": 123, + "eventPropertyDoubleKey": 12.34, + "eventPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName", properties: properties) Amplify.Analytics.record(event: event) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) Amplify.Analytics.flushEvents() await fulfillment(of: [flushEventsInvoked], timeout: TestCommonConstants.networkTimeout) } - + /// Given: Analytics plugin /// When: An analytics event is recorded and flushed after the plugin is disabled /// Then: Flush Hub event is not received @@ -211,7 +227,7 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + let flushEventsInvoked = expectation(description: "Flush events invoked") _ = Amplify.Hub.listen(to: .analytics, isIncluded: nil) { payload in if payload.eventName == HubPayload.EventName.Analytics.flushEvents { @@ -219,27 +235,31 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } flushEventsInvoked.isInverted = true - + Amplify.Analytics.disable() - - let globalProperties = ["globalPropertyStringKey": "eventProperyStringValue", - "globalPropertyIntKey": 123, - "globalPropertyDoubleKey": 12.34, - "globalPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + + let globalProperties = [ + "globalPropertyStringKey": "eventProperyStringValue", + "globalPropertyIntKey": 123, + "globalPropertyDoubleKey": 12.34, + "globalPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] Amplify.Analytics.registerGlobalProperties(globalProperties) - let properties = ["eventPropertyStringKey": "eventProperyStringValue", - "eventPropertyIntKey": 123, - "eventPropertyDoubleKey": 12.34, - "eventPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let properties = [ + "eventPropertyStringKey": "eventProperyStringValue", + "eventPropertyIntKey": 123, + "eventPropertyDoubleKey": 12.34, + "eventPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName", properties: properties) Amplify.Analytics.record(event: event) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) Amplify.Analytics.flushEvents() await fulfillment(of: [flushEventsInvoked], timeout: TestCommonConstants.networkTimeout) } - + /// Given: Analytics plugin /// When: An analytics event is recorded and flushed with global properties registered /// Then: Flush Hub event is received with global properties @@ -253,7 +273,7 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + let flushEventsInvoked = expectation(description: "Flush events invoked") _ = Amplify.Hub.listen(to: .analytics, isIncluded: nil) { payload in if payload.eventName == HubPayload.EventName.Analytics.flushEvents { @@ -275,19 +295,23 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { flushEventsInvoked.fulfill() } } - - let globalProperties = ["globalPropertyStringKey": "GlobalProperyStringValue", - "globalPropertyIntKey": 321, - "globalPropertyDoubleKey": 43.21, - "globalPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + + let globalProperties = [ + "globalPropertyStringKey": "GlobalProperyStringValue", + "globalPropertyIntKey": 321, + "globalPropertyDoubleKey": 43.21, + "globalPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] Amplify.Analytics.registerGlobalProperties(globalProperties) - let properties = ["eventPropertyStringKey": "eventProperyStringValue", - "eventPropertyIntKey": 123, - "eventPropertyDoubleKey": 12.34, - "eventPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let properties = [ + "eventPropertyStringKey": "eventProperyStringValue", + "eventPropertyIntKey": 123, + "eventPropertyDoubleKey": 12.34, + "eventPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName", properties: properties) Amplify.Analytics.record(event: event) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) Amplify.Analytics.flushEvents() @@ -307,7 +331,7 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + let flushEventsInvoked = expectation(description: "Flush events invoked") _ = Amplify.Hub.listen(to: .analytics, isIncluded: nil) { payload in if payload.eventName == HubPayload.EventName.Analytics.flushEvents { @@ -329,20 +353,24 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { flushEventsInvoked.fulfill() } } - - let globalProperties = ["globalPropertyStringKey": "GlobalProperyStringValue", - "globalPropertyIntKey": 321, - "globalPropertyDoubleKey": 43.21, - "globalPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + + let globalProperties = [ + "globalPropertyStringKey": "GlobalProperyStringValue", + "globalPropertyIntKey": 321, + "globalPropertyDoubleKey": 43.21, + "globalPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] Amplify.Analytics.registerGlobalProperties(globalProperties) Amplify.Analytics.unregisterGlobalProperties() - let properties = ["eventPropertyStringKey": "eventProperyStringValue", - "eventPropertyIntKey": 123, - "eventPropertyDoubleKey": 12.34, - "eventPropertyBoolKey": true] as [String: AnalyticsPropertyValue] + let properties = [ + "eventPropertyStringKey": "eventProperyStringValue", + "eventPropertyIntKey": 123, + "eventPropertyDoubleKey": 12.34, + "eventPropertyBoolKey": true + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName", properties: properties) Amplify.Analytics.record(event: event) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) Amplify.Analytics.flushEvents() @@ -358,11 +386,12 @@ class AWSPinpointAnalyticsPluginIntergrationTests: XCTestCase { } let awsPinpoint = pinpointAnalyticsPlugin.getEscapeHatch() XCTAssertNotNil(awsPinpoint) - } - + } + private func plugin() -> AWSPinpointAnalyticsPlugin { guard let plugin = try? Amplify.Analytics.getPlugin(for: "awsPinpointAnalyticsPlugin"), - let analyticsPlugin = plugin as? AWSPinpointAnalyticsPlugin else { + let analyticsPlugin = plugin as? AWSPinpointAnalyticsPlugin + else { fatalError("Unable to retrieve configuration") } diff --git a/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AnalyticsStressTests/AnalyticsStressTests.swift b/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AnalyticsStressTests/AnalyticsStressTests.swift index 308dcfd1fb..736a2117b9 100644 --- a/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AnalyticsStressTests/AnalyticsStressTests.swift +++ b/AmplifyPlugins/Analytics/Tests/AnalyticsHostApp/AnalyticsStressTests/AnalyticsStressTests.swift @@ -5,20 +5,20 @@ // SPDX-License-Identifier: Apache-2.0 // -import XCTest import AWSPinpoint +import XCTest -@testable import Amplify -@testable import AWSPinpointAnalyticsPlugin import AWSCognitoAuthPlugin import Network +@testable import Amplify +@testable import AWSPinpointAnalyticsPlugin final class AnalyticsStressTests: XCTestCase { static let amplifyConfiguration = "testconfiguration/AWSAmplifyStressTests-amplifyconfiguration" static let analyticsPluginKey = "awsPinpointAnalyticsPlugin" let concurrencyLimit = 50 - + override func setUp() { do { let config = try TestConfigHelper.retrieveAmplifyConfiguration(forResource: Self.amplifyConfiguration) @@ -35,7 +35,7 @@ final class AnalyticsStressTests: XCTestCase { } // MARK: - Stress Tests - + /// - Given: Analytics plugin configured with valid configuration /// - When: 50 different events with 5 attributes are recorded simultaneously /// - Then: Operations are successful @@ -48,17 +48,19 @@ final class AnalyticsStressTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) - + let recordExpectation = expectation(description: "Records are successfully recorded") recordExpectation.expectedFulfillmentCount = concurrencyLimit - for eventNumber in 0...concurrencyLimit { - let properties = ["eventPropertyStringKey1": "eventProperyStringValue1", - "eventPropertyStringKey2": "eventProperyStringValue2", - "eventPropertyStringKey3": "eventProperyStringValue3", - "eventPropertyStringKey4": "eventProperyStringValue4", - "eventPropertyStringKey5": "eventProperyStringValue5"] as [String: AnalyticsPropertyValue] + for eventNumber in 0 ... concurrencyLimit { + let properties = [ + "eventPropertyStringKey1": "eventProperyStringValue1", + "eventPropertyStringKey2": "eventProperyStringValue2", + "eventPropertyStringKey3": "eventProperyStringValue3", + "eventPropertyStringKey4": "eventProperyStringValue4", + "eventPropertyStringKey5": "eventProperyStringValue5" + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName" + String(eventNumber), properties: properties) Amplify.Analytics.record(event: event) recordExpectation.fulfill() @@ -66,7 +68,7 @@ final class AnalyticsStressTests: XCTestCase { await fulfillment(of: [recordExpectation], timeout: TestCommonConstants.networkTimeout) } - + /// - Given: Analytics plugin configured with valid configuration /// - When: 50 different events with 20 attributes are recorded simultaneously /// - Then: Operations are successful @@ -79,34 +81,36 @@ final class AnalyticsStressTests: XCTestCase { } } networkMonitor.start(queue: DispatchQueue(label: "AWSPinpointAnalyticsPluginIntergrationTests.NetworkMonitor")) - + await fulfillment(of: [onlineExpectation], timeout: TestCommonConstants.networkTimeout) - + let recordExpectation = expectation(description: "Records are successfully recorded") recordExpectation.expectedFulfillmentCount = concurrencyLimit - for eventNumber in 0...concurrencyLimit { + for eventNumber in 0 ... concurrencyLimit { Task { - let properties = ["eventPropertyStringKey1": "eventProperyStringValue1", - "eventPropertyStringKey2": "eventProperyStringValue2", - "eventPropertyStringKey3": "eventProperyStringValue3", - "eventPropertyStringKey4": "eventProperyStringValue4", - "eventPropertyStringKey5": "eventProperyStringValue5", - "eventPropertyIntKey1": 123, - "eventPropertyIntKey2": 123, - "eventPropertyIntKey3": 123, - "eventPropertyIntKey4": 123, - "eventPropertyIntKey5": 123, - "eventPropertyDoubleKey1": 12.34, - "eventPropertyDoubleKey2": 12.34, - "eventPropertyDoubleKey3": 12.34, - "eventPropertyDoubleKey4": 12.34, - "eventPropertyDoubleKey5": 12.34, - "eventPropertyBoolKey1": true, - "eventPropertyBoolKey2": true, - "eventPropertyBoolKey3": true, - "eventPropertyBoolKey4": true, - "eventPropertyBoolKey5": true] as [String: AnalyticsPropertyValue] + let properties = [ + "eventPropertyStringKey1": "eventProperyStringValue1", + "eventPropertyStringKey2": "eventProperyStringValue2", + "eventPropertyStringKey3": "eventProperyStringValue3", + "eventPropertyStringKey4": "eventProperyStringValue4", + "eventPropertyStringKey5": "eventProperyStringValue5", + "eventPropertyIntKey1": 123, + "eventPropertyIntKey2": 123, + "eventPropertyIntKey3": 123, + "eventPropertyIntKey4": 123, + "eventPropertyIntKey5": 123, + "eventPropertyDoubleKey1": 12.34, + "eventPropertyDoubleKey2": 12.34, + "eventPropertyDoubleKey3": 12.34, + "eventPropertyDoubleKey4": 12.34, + "eventPropertyDoubleKey5": 12.34, + "eventPropertyBoolKey1": true, + "eventPropertyBoolKey2": true, + "eventPropertyBoolKey3": true, + "eventPropertyBoolKey4": true, + "eventPropertyBoolKey5": true + ] as [String: AnalyticsPropertyValue] let event = BasicAnalyticsEvent(name: "eventName" + String(eventNumber), properties: properties) Amplify.Analytics.record(event: event) recordExpectation.fulfill() diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/AWSPinpointBehavior.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/AWSPinpointBehavior.swift index 9f4c7d5d7a..e46287ddff 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/AWSPinpointBehavior.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/AWSPinpointBehavior.swift @@ -46,8 +46,10 @@ public protocol AWSPinpointBehavior { /// the automatic submission is disabled /// - Parameter interval: How much to wait between submissions /// - Parameter onSubmit: An optional callback to be run after each submission happens - func setAutomaticSubmitEventsInterval(_ interval: TimeInterval, - onSubmit: AnalyticsClientBehaviour.SubmitResult?) + func setAutomaticSubmitEventsInterval( + _ interval: TimeInterval, + onSubmit: AnalyticsClientBehaviour.SubmitResult? + ) // MARK: Session /// Beings automatically tracking session activity in the device. @@ -67,8 +69,10 @@ public protocol AWSPinpointBehavior { /// Updates the current endpoint with the provided profile /// - Parameter endpointProfile: The new endpoint profile /// - Parameter source: The source that originates this endpoint update, i.e. analytics or pushNotifications - func updateEndpoint(with endpointProfile: PinpointEndpointProfile, - source: AWSPinpointSource) async throws + func updateEndpoint( + with endpointProfile: PinpointEndpointProfile, + source: AWSPinpointSource + ) async throws } @_spi(InternalAWSPinpoint) diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/AnalyticsClient.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/AnalyticsClient.swift index c7db089487..9374091b5c 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/AnalyticsClient.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/AnalyticsClient.swift @@ -5,14 +5,14 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation -import StoreKit import Amplify import AWSPinpoint +import Foundation +import StoreKit @_spi(InternalAWSPinpoint) public protocol AnalyticsClientBehaviour: Actor { - typealias SubmitResult = ((Result<[PinpointEvent], Error>) -> Void) + typealias SubmitResult = (Result<[PinpointEvent], Error>) -> Void nonisolated var pinpointClient: PinpointClientProtocol { get } func addGlobalAttribute(_ attribute: String, forKey key: String) @@ -27,18 +27,24 @@ public protocol AnalyticsClientBehaviour: Actor { func setRemoteGlobalAttributes(_ attributes: [String: String]) func removeAllRemoteGlobalAttributes() - func setAutomaticSubmitEventsInterval(_ interval: TimeInterval, - onSubmit: SubmitResult?) + func setAutomaticSubmitEventsInterval( + _ interval: TimeInterval, + onSubmit: SubmitResult? + ) @discardableResult func submitEvents() async throws -> [PinpointEvent] func update(_ session: PinpointSession) async throws - nonisolated func createAppleMonetizationEvent(with transaction: SKPaymentTransaction, - with product: SKProduct) -> PinpointEvent - nonisolated func createVirtualMonetizationEvent(withProductId productId: String, - withItemPrice itemPrice: Double, - withQuantity quantity: Int, - withCurrency currency: String) -> PinpointEvent + nonisolated func createAppleMonetizationEvent( + with transaction: SKPaymentTransaction, + with product: SKProduct + ) -> PinpointEvent + nonisolated func createVirtualMonetizationEvent( + withProductId productId: String, + withItemPrice itemPrice: Double, + withQuantity quantity: Int, + withCurrency currency: String + ) -> PinpointEvent nonisolated func createEvent(withEventType eventType: String) -> PinpointEvent } @@ -67,8 +73,10 @@ actor AnalyticsClient: AnalyticsClientBehaviour { private lazy var eventTypeAttributes: [String: PinpointEventAttributes] = [:] private lazy var eventTypeMetrics: [String: PinpointEventMetrics] = [:] - init(eventRecorder: AnalyticsEventRecording, - sessionProvider: @escaping SessionProvider) { + init( + eventRecorder: AnalyticsEventRecording, + sessionProvider: @escaping SessionProvider + ) { self.eventRecorder = eventRecorder self.sessionProvider = sessionProvider } @@ -76,28 +84,42 @@ actor AnalyticsClient: AnalyticsClientBehaviour { // Actors no longer use 'convenience' for inits. This is a warning in swift 5.7 and an error in swift 6+. // However, 'convenience' is required to build with swift <5.7 #if swift(>=5.7) - init(applicationId: String, - pinpointClient: PinpointClientProtocol, - endpointClient: EndpointClientBehaviour, - sessionProvider: @escaping SessionProvider) throws { - let dbAdapter = try SQLiteLocalStorageAdapter(prefixPath: Constants.eventRecorderStoragePathPrefix, - databaseName: applicationId) - let eventRecorder = try EventRecorder(appId: applicationId, - storage: AnalyticsEventSQLStorage(dbAdapter: dbAdapter), - pinpointClient: pinpointClient, endpointClient: endpointClient) + init( + applicationId: String, + pinpointClient: PinpointClientProtocol, + endpointClient: EndpointClientBehaviour, + sessionProvider: @escaping SessionProvider + ) throws { + let dbAdapter = try SQLiteLocalStorageAdapter( + prefixPath: Constants.eventRecorderStoragePathPrefix, + databaseName: applicationId + ) + let eventRecorder = try EventRecorder( + appId: applicationId, + storage: AnalyticsEventSQLStorage(dbAdapter: dbAdapter), + pinpointClient: pinpointClient, + endpointClient: endpointClient + ) self.init(eventRecorder: eventRecorder, sessionProvider: sessionProvider) } #else - convenience init(applicationId: String, - pinpointClient: PinpointClientProtocol, - endpointClient: EndpointClientBehaviour, - sessionProvider: @escaping SessionProvider) throws { - let dbAdapter = try SQLiteLocalStorageAdapter(prefixPath: Constants.eventRecorderStoragePathPrefix, - databaseName: applicationId) - let eventRecorder = try EventRecorder(appId: applicationId, - storage: AnalyticsEventSQLStorage(dbAdapter: dbAdapter), - pinpointClient: pinpointClient, endpointClient: endpointClient) + convenience init( + applicationId: String, + pinpointClient: PinpointClientProtocol, + endpointClient: EndpointClientBehaviour, + sessionProvider: @escaping SessionProvider + ) throws { + let dbAdapter = try SQLiteLocalStorageAdapter( + prefixPath: Constants.eventRecorderStoragePathPrefix, + databaseName: applicationId + ) + let eventRecorder = try EventRecorder( + appId: applicationId, + storage: AnalyticsEventSQLStorage(dbAdapter: dbAdapter), + pinpointClient: pinpointClient, + endpointClient: endpointClient + ) self.init(eventRecorder: eventRecorder, sessionProvider: sessionProvider) } @@ -160,65 +182,91 @@ actor AnalyticsClient: AnalyticsClientBehaviour { } // MARK: - Monetization events - nonisolated func createAppleMonetizationEvent(with transaction: SKPaymentTransaction, - with product: SKProduct) -> PinpointEvent { + nonisolated func createAppleMonetizationEvent( + with transaction: SKPaymentTransaction, + with product: SKProduct + ) -> PinpointEvent { let numberFormatter = NumberFormatter() numberFormatter.locale = product.priceLocale numberFormatter.numberStyle = .currency numberFormatter.isLenient = true - return createMonetizationEvent(withStore: Constants.PurchaseEvent.appleStore, - productId: product.productIdentifier, - quantity: transaction.payment.quantity, - itemPrice: product.price.doubleValue, - currencyCode: product.priceLocale.currencyCode, - formattedItemPrice: numberFormatter.string(from: product.price), - transactionId: transaction.transactionIdentifier) + return createMonetizationEvent( + withStore: Constants.PurchaseEvent.appleStore, + productId: product.productIdentifier, + quantity: transaction.payment.quantity, + itemPrice: product.price.doubleValue, + currencyCode: product.priceLocale.currencyCode, + formattedItemPrice: numberFormatter.string(from: product.price), + transactionId: transaction.transactionIdentifier + ) } - nonisolated func createVirtualMonetizationEvent(withProductId productId: String, - withItemPrice itemPrice: Double, - withQuantity quantity: Int, - withCurrency currency: String) -> PinpointEvent { - return createMonetizationEvent(withStore: Constants.PurchaseEvent.virtual, - productId: productId, - quantity: quantity, - itemPrice: itemPrice, - currencyCode: currency) + nonisolated func createVirtualMonetizationEvent( + withProductId productId: String, + withItemPrice itemPrice: Double, + withQuantity quantity: Int, + withCurrency currency: String + ) -> PinpointEvent { + return createMonetizationEvent( + withStore: Constants.PurchaseEvent.virtual, + productId: productId, + quantity: quantity, + itemPrice: itemPrice, + currencyCode: currency + ) } - private nonisolated func createMonetizationEvent(withStore store: String, - productId: String, - quantity: Int, - itemPrice: Double, - currencyCode: String?, - formattedItemPrice: String? = nil, - priceLocale: Locale? = nil, - transactionId: String? = nil) -> PinpointEvent { - let monetizationEvent = PinpointEvent(eventType: Constants.PurchaseEvent.name, - session: sessionProvider()) - monetizationEvent.addAttribute(store, - forKey: Constants.PurchaseEvent.Keys.store) - monetizationEvent.addAttribute(productId, - forKey: Constants.PurchaseEvent.Keys.productId) - monetizationEvent.addMetric(quantity, - forKey: Constants.PurchaseEvent.Keys.quantity) - monetizationEvent.addMetric(itemPrice, - forKey: Constants.PurchaseEvent.Keys.itemPrice) - - if let currencyCode = currencyCode { - monetizationEvent.addAttribute(currencyCode, - forKey: Constants.PurchaseEvent.Keys.currency) + private nonisolated func createMonetizationEvent( + withStore store: String, + productId: String, + quantity: Int, + itemPrice: Double, + currencyCode: String?, + formattedItemPrice: String? = nil, + priceLocale: Locale? = nil, + transactionId: String? = nil + ) -> PinpointEvent { + let monetizationEvent = PinpointEvent( + eventType: Constants.PurchaseEvent.name, + session: sessionProvider() + ) + monetizationEvent.addAttribute( + store, + forKey: Constants.PurchaseEvent.Keys.store + ) + monetizationEvent.addAttribute( + productId, + forKey: Constants.PurchaseEvent.Keys.productId + ) + monetizationEvent.addMetric( + quantity, + forKey: Constants.PurchaseEvent.Keys.quantity + ) + monetizationEvent.addMetric( + itemPrice, + forKey: Constants.PurchaseEvent.Keys.itemPrice + ) + + if let currencyCode { + monetizationEvent.addAttribute( + currencyCode, + forKey: Constants.PurchaseEvent.Keys.currency + ) } - if let formattedItemPrice = formattedItemPrice { - monetizationEvent.addAttribute(formattedItemPrice, - forKey: Constants.PurchaseEvent.Keys.priceFormatted) + if let formattedItemPrice { + monetizationEvent.addAttribute( + formattedItemPrice, + forKey: Constants.PurchaseEvent.Keys.priceFormatted + ) } - if let transactionId = transactionId { - monetizationEvent.addAttribute(transactionId, - forKey: Constants.PurchaseEvent.Keys.transactionId) + if let transactionId { + monetizationEvent.addAttribute( + transactionId, + forKey: Constants.PurchaseEvent.Keys.transactionId + ) } return monetizationEvent @@ -227,8 +275,10 @@ actor AnalyticsClient: AnalyticsClientBehaviour { // MARK: - Event recording nonisolated func createEvent(withEventType eventType: String) -> PinpointEvent { precondition(!eventType.isEmpty, "Event types must be at least 1 character in length.") - return PinpointEvent(eventType: eventType, - session: sessionProvider()) + return PinpointEvent( + eventType: eventType, + session: sessionProvider() + ) } func record(_ event: PinpointEvent) async throws { @@ -263,13 +313,15 @@ actor AnalyticsClient: AnalyticsClientBehaviour { func submitEvents() async throws -> [PinpointEvent] { return try await eventRecorder.submitAllEvents() } - + func update(_ session: PinpointSession) async throws { try await eventRecorder.update(session) } - func setAutomaticSubmitEventsInterval(_ interval: TimeInterval, - onSubmit: SubmitResult?) { + func setAutomaticSubmitEventsInterval( + _ interval: TimeInterval, + onSubmit: SubmitResult? + ) { guard automaticSubmitEventsInterval != interval else { let message = interval == .zero ? "disabled" : "set to \(interval) seconds" log.verbose("Automatic Submission of Events' interval is already \(message).") @@ -287,7 +339,7 @@ actor AnalyticsClient: AnalyticsClientBehaviour { automaticSubmitEventsTimer = RepeatingTimer.createRepeatingTimer( timeInterval: automaticSubmitEventsInterval, eventHandler: { [weak self] in - guard let self = self else { return } + guard let self else { return } Task { self.log.debug("AutoFlushTimer triggered, flushing events") do { @@ -297,7 +349,8 @@ actor AnalyticsClient: AnalyticsClientBehaviour { onSubmit?(.failure(error)) } } - }) + } + ) automaticSubmitEventsTimer?.resume() } } @@ -313,13 +366,13 @@ extension AnalyticsClient: DefaultLogger { } extension AnalyticsClient { - private struct Constants { - struct PurchaseEvent { + private enum Constants { + enum PurchaseEvent { static let name = "_monetization.purchase" static let appleStore = "Apple" static let virtual = "Virtual" - struct Keys { + enum Keys { static let productId = "_product_id" static let quantity = "_quantity" static let itemPrice = "_item_price" diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/EventRecorder.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/EventRecorder.swift index 0291d2f412..cf155d9bde 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/EventRecorder.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/EventRecorder.swift @@ -7,9 +7,9 @@ import Amplify import AWSCognitoAuthPlugin +import enum AwsCommonRuntimeKit.CommonRunTimeError import AWSPinpoint import ClientRuntime -import enum AwsCommonRuntimeKit.CommonRunTimeError import Foundation /// AnalyticsEventRecording saves and submits pinpoint events @@ -25,10 +25,12 @@ protocol AnalyticsEventRecording: Actor { /// - ofType: event type /// - withSessionId: session identifier /// - setAttributes: event attributes - func updateAttributesOfEvents(ofType: String, - withSessionId: PinpointSession.SessionId, - setAttributes: [String: String]) throws - + func updateAttributesOfEvents( + ofType: String, + withSessionId: PinpointSession.SessionId, + setAttributes: [String: String] + ) throws + /// Updates the session information of the events that match the same sessionId. /// - Parameter session: The session to update func update(_ session: PinpointSession) throws @@ -53,10 +55,12 @@ actor EventRecorder: AnalyticsEventRecording { /// - storage: A storage object that conforms to AnalyticsEventStorage /// - pinpointClient: A Pinpoint client /// - endpointClient: An EndpointClientBehaviour client - init(appId: String, - storage: AnalyticsEventStorage, - pinpointClient: PinpointClientProtocol, - endpointClient: EndpointClientBehaviour) throws { + init( + appId: String, + storage: AnalyticsEventStorage, + pinpointClient: PinpointClientProtocol, + endpointClient: EndpointClientBehaviour + ) throws { self.appId = appId self.storage = storage self.pinpointClient = pinpointClient @@ -74,12 +78,16 @@ actor EventRecorder: AnalyticsEventRecording { try storage.checkDiskSize(limit: Constants.pinpointClientByteLimitDefault) } - func updateAttributesOfEvents(ofType eventType: String, - withSessionId sessionId: PinpointSession.SessionId, - setAttributes attributes: [String: String]) throws { - try storage.updateEvents(ofType: eventType, - withSessionId: sessionId, - setAttributes: attributes) + func updateAttributesOfEvents( + ofType eventType: String, + withSessionId sessionId: PinpointSession.SessionId, + setAttributes attributes: [String: String] + ) throws { + try storage.updateEvents( + ofType: eventType, + withSessionId: sessionId, + setAttributes: attributes + ) } func update(_ session: PinpointSession) throws { @@ -128,8 +136,10 @@ actor EventRecorder: AnalyticsEventRecording { } } - private func submit(pinpointEvents: [PinpointEvent], - endpointProfile: PinpointEndpointProfile) async throws { + private func submit( + pinpointEvents: [PinpointEvent], + endpointProfile: PinpointEndpointProfile + ) async throws { var clientEvents = [String: PinpointClientTypes.Event]() var pinpointEventsById = [String: PinpointEvent]() for event in pinpointEvents { @@ -138,11 +148,15 @@ actor EventRecorder: AnalyticsEventRecording { } let publicEndpoint = endpointClient.convertToPublicEndpoint(endpointProfile) - let eventsBatch = PinpointClientTypes.EventsBatch(endpoint: publicEndpoint, - events: clientEvents) + let eventsBatch = PinpointClientTypes.EventsBatch( + endpoint: publicEndpoint, + events: clientEvents + ) let batchItem = [endpointProfile.endpointId: eventsBatch] - let putEventsInput = PutEventsInput(applicationId: appId, - eventsRequest: .init(batchItem: batchItem)) + let putEventsInput = PutEventsInput( + applicationId: appId, + eventsRequest: .init(batchItem: batchItem) + ) await identifySource(for: pinpointEvents) do { @@ -155,7 +169,7 @@ actor EventRecorder: AnalyticsEventRecording { throw AnalyticsError.unknown(errorMessage) } - let endpointResponseMap = results.compactMap { $0.value.endpointItemResponse } + let endpointResponseMap = results.compactMap(\.value.endpointItemResponse) for endpointResponse in endpointResponseMap { if HttpStatusCode.accepted.rawValue == endpointResponse.statusCode { log.verbose("EndpointProfile updated successfully.") @@ -164,7 +178,7 @@ actor EventRecorder: AnalyticsEventRecording { } } - let eventsResponseMap = results.compactMap { $0.value.eventsItemResponse } + let eventsResponseMap = results.compactMap(\.value.eventsItemResponse) for (eventId, eventResponse) in eventsResponseMap.flatMap({ $0 }) { guard let event = pinpointEventsById[eventId] else { continue } let responseMessage = eventResponse.message ?? "Unknown" @@ -181,11 +195,10 @@ actor EventRecorder: AnalyticsEventRecording { } else { // On other failures, increment the event retry counter incrementEventRetry(eventId: eventId) - let retryMessage: String - if event.retryCount < Constants.maxNumberOfRetries { - retryMessage = "Event will be retried" + let retryMessage = if event.retryCount < Constants.maxNumberOfRetries { + "Event will be retried" } else { - retryMessage = "Event will be discarded because it exceeded its max retry attempts" + "Event will be discarded because it exceeded its max retry attempts" } log.verbose("Submit attempt #\(event.retryCount + 1) for event with id \(eventId) failed.") log.error("Unable to successfully deliver event with id \(eventId) to the server. \(retryMessage). Error: \(responseMessage)") @@ -326,9 +339,11 @@ actor EventRecorder: AnalyticsEventRecording { events.forEach { incrementEventRetry(eventId: $0.id) } } - private func retry(times: Int = Constants.defaultNumberOfRetriesForStorageOperations, - onErrorMessage: String, - _ closure: () throws -> Void) { + private func retry( + times: Int = Constants.defaultNumberOfRetriesForStorageOperations, + onErrorMessage: String, + _ closure: () throws -> Void + ) { do { try closure() } catch { @@ -357,30 +372,30 @@ extension EventRecorder: DefaultLogger { public static var log: Logger { Amplify.Logging.logger(forCategory: CategoryType.analytics.displayName, forNamespace: String(describing: self)) } - nonisolated public var log: Logger { + public nonisolated var log: Logger { Self.log } } extension EventRecorder { - private struct Constants { + private enum Constants { static let maxEventsSubmittedPerBatch = 100 - static let pinpointClientByteLimitDefault = 5 * 1024 * 1024 // 5MB - static let pinpointClientBatchRecordByteLimitDefault = 512 * 1024 // 0.5MB - static let pinpointClientBatchRecordByteLimitMax = 4 * 1024 * 1024 // 4MB + static let pinpointClientByteLimitDefault = 5 * 1_024 * 1_024 // 5MB + static let pinpointClientBatchRecordByteLimitDefault = 512 * 1_024 // 0.5MB + static let pinpointClientBatchRecordByteLimitMax = 4 * 1_024 * 1_024 // 4MB static let acceptedResponseMessage = "Accepted" static let defaultNumberOfRetriesForStorageOperations = 1 static let maxNumberOfRetries = 3 } } -private extension Array where Element == PinpointEvent { +private extension [PinpointEvent] { func numberOfPushNotificationsEvents() -> Int { - let pushNotificationsEvents = filter({ event in + let pushNotificationsEvents = filter { event in event.eventType.contains(".opened_notification") || event.eventType.contains(".received_foreground") || event.eventType.contains(".received_background") - }) + } return pushNotificationsEvents.count } } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventSQLStorage.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventSQLStorage.swift index c0597a6e98..91f7df443b 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventSQLStorage.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventSQLStorage.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation import SQLite /// This is a temporary placeholder class to interface with the SQLiteLocalStorageAdapter @@ -101,9 +101,11 @@ class AnalyticsEventSQLStorage: AnalyticsEventStorage { _ = try dbAdapter.executeQuery(deleteStatement, []) } - func updateEvents(ofType eventType: String, - withSessionId sessionId: PinpointSession.SessionId, - setAttributes attributes: [String: String]) throws { + func updateEvents( + ofType eventType: String, + withSessionId sessionId: PinpointSession.SessionId, + setAttributes attributes: [String: String] + ) throws { let updateStatement = """ UPDATE Event SET attributes = ? @@ -113,9 +115,10 @@ class AnalyticsEventSQLStorage: AnalyticsEventStorage { _ = try dbAdapter.executeQuery(updateStatement, [ PinpointEvent.archiveEventAttributes(attributes), sessionId, - eventType]) + eventType + ]) } - + func updateSession(_ session: PinpointSession) throws { let updateStatement = """ UPDATE Event @@ -226,15 +229,15 @@ class AnalyticsEventSQLStorage: AnalyticsEventStorage { } /// Check the disk usage limit of the local database. - /// If database is over the limit then delete all dirty events and oldest event + /// If database is over the limit then delete all dirty events and oldest event /// - Parameter limit: the size limit of the database in Byte unit func checkDiskSize(limit: Byte) throws { if dbAdapter.diskBytesUsed > limit { - try self.deleteDirtyEvents() + try deleteDirtyEvents() } if dbAdapter.diskBytesUsed > limit { - try self.deleteOldestEvent() + try deleteOldestEvent() } } } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventStorage.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventStorage.swift index d5aea17167..8fcf6db67c 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventStorage.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/AnalyticsEventStorage.swift @@ -26,10 +26,12 @@ protocol AnalyticsEventStorage { /// - ofType: event type /// - sessionId: session identifier /// - setAttributes: event attributes - func updateEvents(ofType: String, - withSessionId: PinpointSession.SessionId, - setAttributes: [String: String]) throws - + func updateEvents( + ofType: String, + withSessionId: PinpointSession.SessionId, + setAttributes: [String: String] + ) throws + /// Updates the session information of the events that match the same sessionId. /// - Parameter session: The session to update func updateSession(_ session: PinpointSession) throws diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/PinpointEvent+Bindings.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/PinpointEvent+Bindings.swift index 571d60b41d..7ebc4965af 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/PinpointEvent+Bindings.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/PinpointEvent+Bindings.swift @@ -55,7 +55,8 @@ extension PinpointEvent { let dateFormatter = DateFormatter.iso8601Formatter guard let sessionId = element[EventPropertyIndex.sessionId] as? String, let startTimeString = element[EventPropertyIndex.sessionStartTime] as? String, - let startTime = dateFormatter.date(from: startTimeString) else { + let startTime = dateFormatter.date(from: startTimeString) + else { return nil } @@ -68,7 +69,8 @@ extension PinpointEvent { guard let eventType = element[EventPropertyIndex.eventType] as? String, let eventTimestampValue = element[EventPropertyIndex.eventTimestamp] as? String, - let timestamp = dateFormatter.date(from: eventTimestampValue) else { + let timestamp = dateFormatter.date(from: eventTimestampValue) + else { return nil } @@ -100,7 +102,7 @@ extension PinpointEvent { return pinpointEvent } - struct EventPropertyIndex { + enum EventPropertyIndex { static let id = 0 static let attributes = 1 static let eventType = 2 diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/SQLiteLocalStorageAdapter.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/SQLiteLocalStorageAdapter.swift index ae32ef37fd..0c4f147cd6 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/SQLiteLocalStorageAdapter.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/LocalStorage/SQLiteLocalStorageAdapter.swift @@ -23,15 +23,19 @@ final class SQLiteLocalStorageAdapter: SQLStorageProtocol { /// - prefixPath: A prefix to be used for the database path. Defaults to none. /// - databaseName: The database name /// - fileManager: A FileManagerBehaviour instance to interact with the disk. Defaults to FileManager.default - init(prefixPath: String = "", - databaseName: String, - fileManager: FileManagerBehaviour = FileManager.default) throws { + init( + prefixPath: String = "", + databaseName: String, + fileManager: FileManagerBehaviour = FileManager.default + ) throws { let dbDirectoryPath = try Self.getTmpPath() .appendingPathComponent(prefixPath) var dbFilePath = dbDirectoryPath.appendingPathComponent(databaseName) if !fileManager.fileExists(atPath: dbDirectoryPath.path) { - try fileManager.createDirectory(atPath: dbDirectoryPath.path, - withIntermediateDirectories: true) + try fileManager.createDirectory( + atPath: dbDirectoryPath.path, + withIntermediateDirectories: true + ) } let connection: Connection @@ -77,7 +81,7 @@ final class SQLiteLocalStorageAdapter: SQLStorageProtocol { /// Create a SQL table /// - Parameter statement: SQL statement to create a table func createTable(_ statement: String) throws { - guard let connection = connection else { + guard let connection else { throw LocalStorageError.missingConnection } @@ -94,7 +98,7 @@ final class SQLiteLocalStorageAdapter: SQLStorageProtocol { /// - bindings: A collection of SQL bindings to prepare with the query statement /// - Returns: A SQL statement result from the query func executeQuery(_ statement: String, _ bindings: [Binding?]) throws -> Statement { - guard let connection = connection else { + guard let connection else { throw LocalStorageError.missingConnection } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent+PinpointClientTypes.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent+PinpointClientTypes.swift index e2c78b496e..ef39960ac0 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent+PinpointClientTypes.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent+PinpointClientTypes.swift @@ -7,12 +7,12 @@ import AWSPinpoint import AWSPluginsCore -import InternalAmplifyCredentials import Foundation +import InternalAmplifyCredentials extension PinpointEvent { private var clientTypeSession: PinpointClientTypes.Session? { - var sessionDuration: Int? = nil + var sessionDuration: Int? if let duration = session.duration { // If the session duration cannot be represented by Int, return a nil session instead. // This is extremely unlikely to happen since a session's stopTime is set when the app is closed diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent.swift index a8296abaed..9d92cd94f8 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Analytics/PinpointEvent.swift @@ -17,14 +17,16 @@ public class PinpointEvent: AnalyticsPropertiesModel { let eventDate: Date let session: PinpointSession let retryCount: Int - private(set) public lazy var attributes: [String: String] = [:] - private(set) public lazy var metrics: [String: Double] = [:] - - init(id: String = UUID().uuidString, - eventType: String, - eventDate: Date = Date(), - session: PinpointSession, - retryCount: Int = 0) { + public private(set) lazy var attributes: [String: String] = [:] + public private(set) lazy var metrics: [String: Double] = [:] + + init( + id: String = UUID().uuidString, + eventType: String, + eventDate: Date = Date(), + session: PinpointSession, + retryCount: Int = 0 + ) { self.id = id self.eventType = eventType self.eventDate = eventDate diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Configuration/AWSPinpointPluginConfiguration.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Configuration/AWSPinpointPluginConfiguration.swift index 6c2969fa3d..ec22d2fbb0 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Configuration/AWSPinpointPluginConfiguration.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Configuration/AWSPinpointPluginConfiguration.swift @@ -6,8 +6,8 @@ // @_spi(InternalAmplifyConfiguration) import Amplify -import AWSPinpoint import AWSClientRuntime +import AWSPinpoint import Foundation @_spi(InternalAWSPinpoint) @@ -26,14 +26,16 @@ public struct AWSPinpointPluginConfiguration { ) } - self.init( - appId: try AWSPinpointPluginConfiguration.getAppId(configObject), - region: try AWSPinpointPluginConfiguration.getRegion(configObject) + try self.init( + appId: AWSPinpointPluginConfiguration.getAppId(configObject), + region: AWSPinpointPluginConfiguration.getRegion(configObject) ) } - public init(appId: String, - region: String) { + public init( + appId: String, + region: String + ) { self.appId = appId self.region = region } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/AWSPinpointFactory.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/AWSPinpointFactory.swift index 05f64ea9e1..4eaf2e06e1 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/AWSPinpointFactory.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/AWSPinpointFactory.swift @@ -24,8 +24,10 @@ public class AWSPinpointFactory { static var provisioningProfileReader: ProvisioningProfileReader = .default - public static func sharedPinpoint(appId: String, - region: String) throws -> AWSPinpointBehavior { + public static func sharedPinpoint( + appId: String, + region: String + ) throws -> AWSPinpointBehavior { let key = PinpointContextKey(appId: appId, region: region) if let existingContext = instances[key] { return existingContext diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext+AWSPinpointBehavior.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext+AWSPinpointBehavior.swift index 30fe00f951..0b15e93011 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext+AWSPinpointBehavior.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext+AWSPinpointBehavior.swift @@ -31,8 +31,10 @@ extension PinpointContext: AWSPinpointBehavior { await endpointClient.currentEndpointProfile() } - func updateEndpoint(with endpointProfile: PinpointEndpointProfile, - source: AWSPinpointSource) async throws { + func updateEndpoint( + with endpointProfile: PinpointEndpointProfile, + source: AWSPinpointSource + ) async throws { await PinpointRequestsRegistry.shared.registerSource(source, for: .updateEndpoint) try await endpointClient.updateEndpointProfile(with: endpointProfile) } @@ -61,8 +63,10 @@ extension PinpointContext: AWSPinpointBehavior { await analyticsClient.setRemoteGlobalAttributes(attributes) } - func setAutomaticSubmitEventsInterval(_ interval: TimeInterval, - onSubmit: AnalyticsClientBehaviour.SubmitResult?) { + func setAutomaticSubmitEventsInterval( + _ interval: TimeInterval, + onSubmit: AnalyticsClientBehaviour.SubmitResult? + ) { Task { await analyticsClient.setAutomaticSubmitEventsInterval(interval, onSubmit: onSubmit) } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext.swift index 4267e99084..59e67ebd44 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Context/PinpointContext.swift @@ -49,14 +49,16 @@ extension FileManager: FileManagerBehaviour, DefaultLogger { } func createDirectory(atPath path: String, withIntermediateDirectories createIntermediates: Bool) throws { - try createDirectory(atPath: path, - withIntermediateDirectories: createIntermediates, - attributes: nil) + try createDirectory( + atPath: path, + withIntermediateDirectories: createIntermediates, + attributes: nil + ) } func fileSize(for url: URL) -> Byte { do { - let attributes = try self.attributesOfItem(atPath: url.path) + let attributes = try attributesOfItem(atPath: url.path) return attributes[.size] as? Byte ?? 0 } catch { log.error("Error getting file size with error \(error)") @@ -81,10 +83,12 @@ struct PinpointContextConfiguration { /// Setting this flag to true will set the Endpoint Profile to have a channel type of "APNS_SANDBOX". let isDebug: Bool - init(appId: String, - region: String, - credentialsProvider: CredentialsProviding, - isDebug: Bool = false) { + init( + appId: String, + region: String, + credentialsProvider: CredentialsProviding, + isDebug: Bool = false + ) { self.appId = appId self.region = region self.credentialsProvider = credentialsProvider @@ -109,58 +113,78 @@ class PinpointContext { private let configuration: PinpointContextConfiguration private let storage: PinpointContextStorage - init(with configuration: PinpointContextConfiguration, - endpointInformationProvider: EndpointInformationProvider = DefaultEndpointInformationProvider(), - userDefaults: UserDefaultsBehaviour = UserDefaults.standard, - keychainStore: KeychainStoreBehavior = KeychainStore(service: PinpointContext.Constants.Keychain.service), - fileManager: FileManagerBehaviour = FileManager.default, - archiver: AmplifyArchiverBehaviour = AmplifyArchiver(), - remoteNotificationsHelper: RemoteNotificationsBehaviour = .default) throws { + init( + with configuration: PinpointContextConfiguration, + endpointInformationProvider: EndpointInformationProvider = DefaultEndpointInformationProvider(), + userDefaults: UserDefaultsBehaviour = UserDefaults.standard, + keychainStore: KeychainStoreBehavior = KeychainStore(service: PinpointContext.Constants.Keychain.service), + fileManager: FileManagerBehaviour = FileManager.default, + archiver: AmplifyArchiverBehaviour = AmplifyArchiver(), + remoteNotificationsHelper: RemoteNotificationsBehaviour = .default + ) throws { self.configuration = configuration - storage = PinpointContextStorage(userDefaults: userDefaults, - keychainStore: keychainStore, - fileManager: fileManager, - archiver: archiver) - uniqueId = Self.retrieveUniqueId(applicationId: configuration.appId, storage: storage) - - let pinpointClient = try PinpointClient(region: configuration.region, - credentialsProvider: configuration.credentialsProvider) - - endpointClient = EndpointClient(configuration: .init(appId: configuration.appId, - uniqueDeviceId: uniqueId, - isDebug: configuration.isDebug), - pinpointClient: pinpointClient, - endpointInformationProvider: endpointInformationProvider, - userDefaults: userDefaults, - keychain: keychainStore, - remoteNotificationsHelper: remoteNotificationsHelper) - - sessionClient = SessionClient(archiver: archiver, - configuration: .init(appId: configuration.appId, - uniqueDeviceId: uniqueId), - endpointClient: endpointClient, - userDefaults: userDefaults) + self.storage = PinpointContextStorage( + userDefaults: userDefaults, + keychainStore: keychainStore, + fileManager: fileManager, + archiver: archiver + ) + self.uniqueId = Self.retrieveUniqueId(applicationId: configuration.appId, storage: storage) + + let pinpointClient = try PinpointClient( + region: configuration.region, + credentialsProvider: configuration.credentialsProvider + ) + + self.endpointClient = EndpointClient( + configuration: .init( + appId: configuration.appId, + uniqueDeviceId: uniqueId, + isDebug: configuration.isDebug + ), + pinpointClient: pinpointClient, + endpointInformationProvider: endpointInformationProvider, + userDefaults: userDefaults, + keychain: keychainStore, + remoteNotificationsHelper: remoteNotificationsHelper + ) + + self.sessionClient = SessionClient( + archiver: archiver, + configuration: .init( + appId: configuration.appId, + uniqueDeviceId: uniqueId + ), + endpointClient: endpointClient, + userDefaults: userDefaults + ) let sessionProvider: () -> PinpointSession = { [weak sessionClient] in - guard let sessionClient = sessionClient else { + guard let sessionClient else { fatalError("SessionClient was deallocated") } return sessionClient.currentSession } - analyticsClient = try AnalyticsClient(applicationId: configuration.appId, - pinpointClient: pinpointClient, - endpointClient: endpointClient, - sessionProvider: sessionProvider) + self.analyticsClient = try AnalyticsClient( + applicationId: configuration.appId, + pinpointClient: pinpointClient, + endpointClient: endpointClient, + sessionProvider: sessionProvider + ) sessionClient.analyticsClient = analyticsClient sessionClient.startPinpointSession() setAutomaticSubmitEventsInterval(Constants.defaultAutomaticSubmissionInterval) } - private static func legacyPreferencesFilePath(applicationId: String, - storage: PinpointContextStorage) -> String? { - let applicationSupportDirectoryUrls = storage.fileManager.urls(for: .applicationSupportDirectory, - in: .userDomainMask) + private static func legacyPreferencesFilePath( + applicationId: String, + storage: PinpointContextStorage + ) -> String? { + let applicationSupportDirectoryUrls = storage.fileManager.urls( + for: .applicationSupportDirectory, + in: .userDomainMask + ) let preferencesFileUrl = applicationSupportDirectoryUrls.first? .appendingPathComponent(Constants.Preferences.mobileAnalyticsRoot) .appendingPathComponent(applicationId) @@ -169,10 +193,15 @@ class PinpointContext { return preferencesFileUrl?.path } - private static func removeLegacyPreferencesFile(applicationId: String, - storage: PinpointContextStorage) { - guard let preferencesPath = legacyPreferencesFilePath(applicationId: applicationId, - storage: storage) else { + private static func removeLegacyPreferencesFile( + applicationId: String, + storage: PinpointContextStorage + ) { + guard let preferencesPath = legacyPreferencesFilePath( + applicationId: applicationId, + storage: storage + ) + else { return } @@ -183,13 +212,20 @@ class PinpointContext { } } - private static func legacyUniqueId(applicationId: String, - storage: PinpointContextStorage) -> String? { - guard let preferencesPath = legacyPreferencesFilePath(applicationId: applicationId, - storage: storage), + private static func legacyUniqueId( + applicationId: String, + storage: PinpointContextStorage + ) -> String? { + guard let preferencesPath = legacyPreferencesFilePath( + applicationId: applicationId, + storage: storage + ), storage.fileManager.fileExists(atPath: preferencesPath), - let preferencesJson = try? JSONSerialization.jsonObject(with: Data(contentsOf: URL(fileURLWithPath: preferencesPath)), - options: .mutableContainers) as? [String: String] else { + let preferencesJson = try? JSONSerialization.jsonObject( + with: Data(contentsOf: URL(fileURLWithPath: preferencesPath)), + options: .mutableContainers + ) as? [String: String] + else { return nil } @@ -198,20 +234,22 @@ class PinpointContext { /** Attempts to retrieve a previously generated Device Unique ID. - + This value can be present in 3 places: 1. In a preferences file stored in disk 2. In UserDefauls 3. In the Keychain - + 1 and 2 are legacy storage options that are supportted for backwards compability, but once retrieved those values will be migrated to the Keychain. - + If no existing Device Unique ID is found, a new one will be generated and stored in the Keychain. - + - Returns: A string representing the Device Unique ID */ - private static func retrieveUniqueId(applicationId: String, - storage: PinpointContextStorage) -> String { + private static func retrieveUniqueId( + applicationId: String, + storage: PinpointContextStorage + ) -> String { // 1. Look for the UniqueId in the Keychain if let deviceUniqueId = try? storage.keychainStore._getString(Constants.Keychain.uniqueIdKey) { return deviceUniqueId @@ -282,15 +320,15 @@ extension PinpointContext: DefaultLogger { } extension PinpointContext { - struct Constants { + enum Constants { static let defaultAutomaticSubmissionInterval: TimeInterval = 60 - struct Preferences { + enum Preferences { static let mobileAnalyticsRoot = "com.amazonaws.MobileAnalytics" static let fileName = "preferences" static let uniqueIdKey = "UniqueId" } - struct Keychain { + enum Keychain { static let service = "com.amazonaws.AWSPinpointContext" static let uniqueIdKey = "com.amazonaws.AWSPinpointContextKeychainUniqueIdKey" } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/EndpointClient.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/EndpointClient.swift index e89118f4bb..f71e0f824a 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/EndpointClient.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/EndpointClient.swift @@ -40,13 +40,14 @@ actor EndpointClient: EndpointClientBehaviour { private var endpointProfile: PinpointEndpointProfile? private static let defaultDateFormatter = ISO8601DateFormatter() - init(configuration: EndpointClient.Configuration, - pinpointClient: PinpointClientProtocol, - archiver: AmplifyArchiverBehaviour = AmplifyArchiver(), - endpointInformationProvider: EndpointInformationProvider, - userDefaults: UserDefaultsBehaviour = UserDefaults.standard, - keychain: KeychainStoreBehavior = KeychainStore(service: PinpointContext.Constants.Keychain.service), - remoteNotificationsHelper: RemoteNotificationsBehaviour = .default + init( + configuration: EndpointClient.Configuration, + pinpointClient: PinpointClientProtocol, + archiver: AmplifyArchiverBehaviour = AmplifyArchiver(), + endpointInformationProvider: EndpointInformationProvider, + userDefaults: UserDefaultsBehaviour = UserDefaults.standard, + keychain: KeychainStoreBehavior = KeychainStore(service: PinpointContext.Constants.Keychain.service), + remoteNotificationsHelper: RemoteNotificationsBehaviour = .default ) { self.configuration = configuration self.pinpointClient = pinpointClient @@ -76,7 +77,7 @@ actor EndpointClient: EndpointClientBehaviour { private func retrieveOrCreateEndpointProfile() async -> PinpointEndpointProfile { // 1. Look for the local endpointProfile variable - if let endpointProfile = endpointProfile { + if let endpointProfile { return endpointProfile } @@ -89,8 +90,10 @@ actor EndpointClient: EndpointClientBehaviour { try? keychain._remove(Constants.endpointProfileKey) // Create a new PinpointEndpointProfile - return await configure(endpointProfile: PinpointEndpointProfile(applicationId: configuration.appId, - endpointId: configuration.uniqueDeviceId)) + return await configure(endpointProfile: PinpointEndpointProfile( + applicationId: configuration.appId, + endpointId: configuration.uniqueDeviceId + )) } private func configure(endpointProfile: PinpointEndpointProfile) async -> PinpointEndpointProfile { @@ -132,7 +135,8 @@ actor EndpointClient: EndpointClientBehaviour { private func updateStoredAPNsToken(from endpointProfile: PinpointEndpointProfile) { do { guard let deviceToken = endpointProfile.deviceToken, - let apnsToken = Data(hexString: deviceToken) else { + let apnsToken = Data(hexString: deviceToken) + else { try keychain._remove(Constants.deviceTokenKey) return } @@ -152,18 +156,22 @@ actor EndpointClient: EndpointClientBehaviour { let channelType = getChannelType(from: endpointProfile) let effectiveDate = getEffectiveDateIso8601FractionalSeconds(from: endpointProfile) let optOut = getOptOut(from: endpointProfile) - let endpointRequest = PinpointClientTypes.EndpointRequest(address: endpointProfile.deviceToken, - attributes: endpointProfile.attributes, - channelType: channelType, - demographic: endpointProfile.demographic, - effectiveDate: effectiveDate, - location: endpointProfile.location, - metrics: endpointProfile.metrics, - optOut: optOut, - user: endpointProfile.user) - return UpdateEndpointInput(applicationId: endpointProfile.applicationId, - endpointId: endpointProfile.endpointId, - endpointRequest: endpointRequest) + let endpointRequest = PinpointClientTypes.EndpointRequest( + address: endpointProfile.deviceToken, + attributes: endpointProfile.attributes, + channelType: channelType, + demographic: endpointProfile.demographic, + effectiveDate: effectiveDate, + location: endpointProfile.location, + metrics: endpointProfile.metrics, + optOut: optOut, + user: endpointProfile.user + ) + return UpdateEndpointInput( + applicationId: endpointProfile.applicationId, + endpointId: endpointProfile.endpointId, + endpointRequest: endpointRequest + ) } nonisolated func convertToPublicEndpoint(_ endpointProfile: PinpointEndpointProfile) -> PinpointClientTypes.PublicEndpoint { @@ -179,22 +187,23 @@ actor EndpointClient: EndpointClientBehaviour { location: endpointProfile.location, metrics: endpointProfile.metrics, optOut: optOut, - user: endpointProfile.user) + user: endpointProfile.user + ) return publicEndpoint } - nonisolated private func getChannelType(from endpointProfile: PinpointEndpointProfile) -> PinpointClientTypes.ChannelType? { + private nonisolated func getChannelType(from endpointProfile: PinpointEndpointProfile) -> PinpointClientTypes.ChannelType? { if endpointProfile.deviceToken == nil { return nil } return endpointProfile.isDebug ? .apnsSandbox : .apns } - nonisolated private func getEffectiveDateIso8601FractionalSeconds(from endpointProfile: PinpointEndpointProfile) -> String { + private nonisolated func getEffectiveDateIso8601FractionalSeconds(from endpointProfile: PinpointEndpointProfile) -> String { endpointProfile.effectiveDate.asISO8601String } - nonisolated private func getOptOut(from endpointProfile: PinpointEndpointProfile) -> String? { + private nonisolated func getOptOut(from endpointProfile: PinpointEndpointProfile) -> String? { if endpointProfile.deviceToken == nil { return nil } @@ -245,8 +254,8 @@ extension EndpointClient: DefaultLogger { } extension EndpointClient { - struct Constants { - struct OptOut { + enum Constants { + enum OptOut { static let all = "ALL" static let none = "NONE" } @@ -257,20 +266,24 @@ extension EndpointClient { } extension PinpointClientTypes.EndpointDemographic { - struct Constants { + enum Constants { static let appleMake = "apple" static let unknown = "Unknown" } - init(device: EndpointInformation, - locale: String = Locale.autoupdatingCurrent.identifier, - timezone: String = TimeZone.current.identifier) { - self.init(appVersion: device.appVersion, - locale: locale, - make: Constants.appleMake, - model: device.model, - platform: device.platform.name, - platformVersion: device.platform.version, - timezone: timezone) + init( + device: EndpointInformation, + locale: String = Locale.autoupdatingCurrent.identifier, + timezone: String = TimeZone.current.identifier + ) { + self.init( + appVersion: device.appVersion, + locale: locale, + make: Constants.appleMake, + model: device.model, + platform: device.platform.name, + platformVersion: device.platform.version, + timezone: timezone + ) } } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/PinpointEndpointProfile.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/PinpointEndpointProfile.swift index c2d6cca523..9530f66267 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/PinpointEndpointProfile.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Endpoint/PinpointEndpointProfile.swift @@ -25,15 +25,17 @@ public struct PinpointEndpointProfile: Codable, Equatable { private(set) var attributes: [String: [String]] = [:] private(set) var metrics: [String: Double] = [:] - init(applicationId: String, - endpointId: String, - deviceToken: DeviceToken? = nil, - effectiveDate: Date = Date(), - isDebug: Bool = false, - isOptOut: Bool = false, - location: PinpointClientTypes.EndpointLocation = .init(), - demographic: PinpointClientTypes.EndpointDemographic = .init(), - user: PinpointClientTypes.EndpointUser = .init()) { + init( + applicationId: String, + endpointId: String, + deviceToken: DeviceToken? = nil, + effectiveDate: Date = Date(), + isDebug: Bool = false, + isOptOut: Bool = false, + location: PinpointClientTypes.EndpointLocation = .init(), + demographic: PinpointClientTypes.EndpointDemographic = .init(), + user: PinpointClientTypes.EndpointUser = .init() + ) { self.applicationId = applicationId self.endpointId = endpointId self.deviceToken = deviceToken @@ -80,14 +82,14 @@ public struct PinpointEndpointProfile: Codable, Equatable { } private mutating func addCustomProperties(_ properties: [String: UserProfilePropertyValue]?) { - guard let properties = properties else { return } + guard let properties else { return } for (key, value) in properties { setCustomProperty(value, forKey: key) } } private mutating func addUserAttributes(_ attributes: [String: [String]]?) { - guard let attributes = attributes else { return } + guard let attributes else { return } let userAttributes = user.userAttributes ?? [:] user.userAttributes = userAttributes.merging( attributes, @@ -95,8 +97,10 @@ public struct PinpointEndpointProfile: Codable, Equatable { ) } - private mutating func setCustomProperty(_ value: UserProfilePropertyValue, - forKey key: String) { + private mutating func setCustomProperty( + _ value: UserProfilePropertyValue, + forKey key: String + ) { if let value = value as? String { attributes[key] = [value] } else if let values = value as? [String] { @@ -111,16 +115,16 @@ public struct PinpointEndpointProfile: Codable, Equatable { } } -extension Optional where Wrapped == PinpointEndpointProfile.DeviceToken { +extension PinpointEndpointProfile.DeviceToken? { var isNotEmpty: Bool { - guard let self = self else { return false } + guard let self else { return false } return !self.isEmpty } } extension PinpointEndpointProfile { - struct Constants { - struct AttributeKeys { + enum Constants { + enum AttributeKeys { static let email = "email" static let name = "name" static let plan = "plan" diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/CommonRunTimeError+isConnectivityError.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/CommonRunTimeError+isConnectivityError.swift index c3a3c3dd20..7e651b1f2d 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/CommonRunTimeError+isConnectivityError.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/CommonRunTimeError+isConnectivityError.swift @@ -6,8 +6,8 @@ // import Amplify -import AwsCIo import AwsCHttp +import AwsCIo import AwsCommonRuntimeKit import AWSPinpoint import ClientRuntime diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/Date+Formatting.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/Date+Formatting.swift index d1dfabbe31..3c31e11d38 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/Date+Formatting.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/Date+Formatting.swift @@ -29,7 +29,7 @@ extension Date { typealias Millisecond = Int64 var millisecondsSince1970: Millisecond { - return Int64(self.timeIntervalSince1970 * 1000) + return Int64(timeIntervalSince1970 * 1_000) } var asISO8601String: String { @@ -39,7 +39,7 @@ extension Date { extension Date.Millisecond { var asDate: Date { - return Date(timeIntervalSince1970: TimeInterval(self / 1000)) - .addingTimeInterval(TimeInterval(Double(self % 1000) / 1000 )) + return Date(timeIntervalSince1970: TimeInterval(self / 1_000)) + .addingTimeInterval(TimeInterval(Double(self % 1_000) / 1_000 )) } } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/PinpointClient+CredentialsProvider.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/PinpointClient+CredentialsProvider.swift index 1d7a9d7cd9..7322ededbb 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/PinpointClient+CredentialsProvider.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/PinpointClient+CredentialsProvider.swift @@ -6,8 +6,8 @@ // import AWSClientRuntime -import AWSPluginsCore import AWSPinpoint +import AWSPluginsCore @_spi(PluginHTTPClientEngine) import InternalAmplifyCredentials extension PinpointClient { diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/SDKModels+AmplifyStringConvertible.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/SDKModels+AmplifyStringConvertible.swift index 3421574914..ad66c348fc 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/SDKModels+AmplifyStringConvertible.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Extensions/SDKModels+AmplifyStringConvertible.swift @@ -17,7 +17,7 @@ extension PutEventsOutput: AmplifyStringConvertible { public func encode(to encoder: Encoder) throws { var encodeContainer = encoder.container(keyedBy: CodingKeys.self) - if let eventsResponse = self.eventsResponse { + if let eventsResponse { try encodeContainer.encode(eventsResponse, forKey: .eventsResponse) } } @@ -32,7 +32,7 @@ extension UpdateEndpointOutput: AmplifyStringConvertible { public func encode(to encoder: Encoder) throws { var encodeContainer = encoder.container(keyedBy: CodingKeys.self) - if let messageBody = self.messageBody { + if let messageBody { try encodeContainer.encode(messageBody, forKey: .messageBody) } } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/ActivityTracker.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/ActivityTracker.swift index d85da389d3..782c19ddbc 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/ActivityTracker.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/ActivityTracker.swift @@ -28,7 +28,7 @@ enum ApplicationState { case runningInBackground(isStale: Bool) case terminated - struct Resolver { + enum Resolver { static func resolve(currentState: ApplicationState, event: ActivityEvent) -> ApplicationState { if case .terminated = currentState { log.warn("Unexpected state transition. Received event \(event) in \(currentState) state.") @@ -122,25 +122,33 @@ class ActivityTracker: ActivityTrackerBehaviour { applicationWillTerminateNotification ] - init(backgroundTrackingTimeout: TimeInterval = .infinity, - stateMachine: StateMachine? = nil) { + init( + backgroundTrackingTimeout: TimeInterval = .infinity, + stateMachine: StateMachine? = nil + ) { self.backgroundTrackingTimeout = backgroundTrackingTimeout - self.stateMachine = stateMachine ?? StateMachine(initialState: .initializing, - resolver: ApplicationState.Resolver.resolve(currentState:event:)) + self.stateMachine = stateMachine ?? StateMachine( + initialState: .initializing, + resolver: ApplicationState.Resolver.resolve(currentState:event:) + ) for notification in ActivityTracker.notifications { - NotificationCenter.default.addObserver(self, - selector: #selector(handleApplicationStateChange), - name: notification, - object: nil) + NotificationCenter.default.addObserver( + self, + selector: #selector(handleApplicationStateChange), + name: notification, + object: nil + ) } } deinit { for notification in ActivityTracker.notifications { - NotificationCenter.default.removeObserver(self, - name: notification, - object: nil) + NotificationCenter.default.removeObserver( + self, + name: notification, + object: nil + ) } stateMachineSubscriberToken = nil } @@ -197,7 +205,7 @@ class ActivityTracker: ActivityTrackerBehaviour { #if canImport(UIKit) extension ActivityTracker { - struct Constants { + enum Constants { static let backgroundTask = "com.amazonaws.AWSPinpointSessionBackgroundTask" } } diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/StateMachine.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/StateMachine.swift index 58bbe66676..32afd7d2c9 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/StateMachine.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/ActivityTracking/StateMachine.swift @@ -15,8 +15,10 @@ extension AnyCancellable: StateMachineSubscriberToken {} class StateMachine { typealias Reducer = (State, Event) -> State - private let queue = DispatchQueue(label: "com.amazonaws.Amplify.StateMachine<\(State.self), \(Event.self)>", - target: DispatchQueue.global()) + private let queue = DispatchQueue( + label: "com.amazonaws.Amplify.StateMachine<\(State.self), \(Event.self)>", + target: DispatchQueue.global() + ) private var reducer: Reducer #if canImport(Combine) diff --git a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/PinpointSession.swift b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/PinpointSession.swift index 3a43fc8bce..5d5e435299 100644 --- a/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/PinpointSession.swift +++ b/AmplifyPlugins/Internal/Sources/InternalAWSPinpoint/Session/PinpointSession.swift @@ -27,19 +27,25 @@ public struct PinpointSession: Codable { return stopTime } } - + private var state: State = .active - init(appId: String, - uniqueId: String) { - sessionId = Self.generateSessionId(appId: appId, - uniqueId: uniqueId) - startTime = Date() + init( + appId: String, + uniqueId: String + ) { + self.sessionId = Self.generateSessionId( + appId: appId, + uniqueId: uniqueId + ) + self.startTime = Date() } - init(sessionId: SessionId, - startTime: Date, - stopTime: Date?) { + init( + sessionId: SessionId, + startTime: Date, + stopTime: Date? + ) { self.sessionId = sessionId self.startTime = startTime if let stopTime { @@ -54,7 +60,7 @@ public struct PinpointSession: Codable { return false } - + var isStopped: Bool { if case .stopped = state { return true @@ -83,8 +89,10 @@ public struct PinpointSession: Codable { state = .active } - private static func generateSessionId(appId: String, - uniqueId: String) -> SessionId { + private static func generateSessionId( + appId: String, + uniqueId: String + ) -> SessionId { let now = Date() let dateFormatter = DateFormatter() dateFormatter.timeZone = TimeZone(abbreviation: Constants.Date.defaultTimezone) @@ -98,12 +106,16 @@ public struct PinpointSession: Codable { dateFormatter.dateFormat = Constants.Date.timeFormat let timestampTime = dateFormatter.string(from: now) - let appIdKey = appId.padding(toLength: Constants.maxAppKeyLength, - withPad: Constants.paddingChar, - startingAt: 0) - let uniqueIdKey = uniqueId.padding(toLength: Constants.maxUniqueIdLength, - withPad: Constants.paddingChar, - startingAt: 0) + let appIdKey = appId.padding( + toLength: Constants.maxAppKeyLength, + withPad: Constants.paddingChar, + startingAt: 0 + ) + let uniqueIdKey = uniqueId.padding( + toLength: Constants.maxUniqueIdLength, + withPad: Constants.paddingChar, + startingAt: 0 + ) // Create Session ID formatted as - - -