From 47cb155a2823c5ab20fb5f3cff54cf04176bac1e Mon Sep 17 00:00:00 2001 From: Brennan Stehling Date: Wed, 19 Oct 2022 12:01:26 -0700 Subject: [PATCH 1/4] implements new Storage API for handleEventsForBackgroundURLSession --- .../StorageCategory+ClientBehavior.swift | 5 ++-- .../Storage/StorageCategoryBehavior.swift | 3 +- ...SS3StoragePlugin+AsyncClientBehavior.swift | 6 ++-- .../StorageBackgroundEventsRegistry.swift | 8 ++--- .../StorageServiceSessionDelegate.swift | 2 +- ...StorageBackgroundEventsRegistryTests.swift | 29 ++++++------------- .../Mocks/MockStorageCategoryPlugin.swift | 2 +- .../Hub/AmplifyOperationHubTests.swift | 2 +- 8 files changed, 23 insertions(+), 34 deletions(-) diff --git a/Amplify/Categories/Storage/StorageCategory+ClientBehavior.swift b/Amplify/Categories/Storage/StorageCategory+ClientBehavior.swift index e1a8daf4c3..7c146af62a 100644 --- a/Amplify/Categories/Storage/StorageCategory+ClientBehavior.swift +++ b/Amplify/Categories/Storage/StorageCategory+ClientBehavior.swift @@ -53,8 +53,9 @@ extension StorageCategory: StorageCategoryBehavior { try await plugin.list(options: options) } - public func handleBackgroundEvents(identifier: String) async -> Bool { - await plugin.handleBackgroundEvents(identifier: identifier) + @discardableResult + public func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { + await plugin.handleEventsForBackgroundURLSession(identifier: identifier) } } diff --git a/Amplify/Categories/Storage/StorageCategoryBehavior.swift b/Amplify/Categories/Storage/StorageCategoryBehavior.swift index 91cbdcb64a..81837ffc25 100644 --- a/Amplify/Categories/Storage/StorageCategoryBehavior.swift +++ b/Amplify/Categories/Storage/StorageCategoryBehavior.swift @@ -88,6 +88,7 @@ public protocol StorageCategoryBehavior { /// Handles background events which are related to URLSession /// - Parameter identifier: identifier /// - Returns: returns true if the identifier is handled by Amplify - func handleBackgroundEvents(identifier: String) async -> Bool + @discardableResult + func handleEventsForBackgroundURLSession(identifier: String) async -> Bool } diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift index 4e98076636..81313aedf0 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift @@ -119,10 +119,8 @@ extension AWSS3StoragePlugin { return try await taskAdapter.value } - public func handleBackgroundEvents(identifier: String) async -> Bool { - await withCheckedContinuation { (continuation: CheckedContinuation) in - StorageBackgroundEventsRegistry.handleBackgroundEvents(identifier: identifier, continuation: continuation) - } + public func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { + await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) } } diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift index 01f8126261..a726ed617b 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift @@ -22,11 +22,11 @@ class StorageBackgroundEventsRegistry { /// - identifier: session identifier /// - completionHandler: completion handler /// - Returns: indicates if the identifier was registered and will be handled - static func handleBackgroundEvents(identifier: String, continuation: StorageBackgroundEventsContinuation) { - if self.identifier == identifier { + static func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { + guard self.identifier == identifier else { return false } + + return await withCheckedContinuation { (continuation: CheckedContinuation) in self.continuation = continuation - } else { - continuation.resume(returning: false) } } diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift index 03da3cc4fe..66cd17c4d0 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift @@ -53,7 +53,7 @@ extension StorageServiceSessionDelegate: URLSessionDelegate { func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { logURLSessionActivity("Session did finish background events") - if let identifier = storageService?.identifier, + if let identifier = session.configuration.identifier, let continuation = StorageBackgroundEventsRegistry.getContinuation(for: identifier) { // Must be run on main thread as covered by Apple Developer docs. Task { @MainActor in diff --git a/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift b/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift index 4d1cb67a88..d2fe6f430a 100644 --- a/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift +++ b/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift @@ -21,29 +21,21 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { let done = asyncExpectation(description: "done", expectedFulfillmentCount: 2) Task { - let handled = await withCheckedContinuation { (continuation: CheckedContinuation) in - StorageBackgroundEventsRegistry.handleBackgroundEvents(identifier: identifier, continuation: continuation) - Task { - await done.fulfill() - } - } + let handled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) + await done.fulfill() XCTAssertTrue(handled) } Task { - let otherHandled = await withCheckedContinuation { (continuation: CheckedContinuation) in - StorageBackgroundEventsRegistry.handleBackgroundEvents(identifier: otherIdentifier, continuation: continuation) - Task { - await done.fulfill() - } - } + let otherHandled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: otherIdentifier) + await done.fulfill() XCTAssertFalse(otherHandled) } - await waitForExpectations([done]) - handleEvents(for: identifier) handleEvents(for: otherIdentifier) + + await waitForExpectations([done]) } func testHandlingUnregisteredIdentifier() async throws { @@ -54,12 +46,8 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { let done = asyncExpectation(description: "done") Task { - let handled = await withCheckedContinuation { (continuation: CheckedContinuation) in - StorageBackgroundEventsRegistry.handleBackgroundEvents(identifier: identifier, continuation: continuation) - Task { - await done.fulfill() - } - } + let handled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) + await done.fulfill() XCTAssertFalse(handled) } @@ -70,6 +58,7 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { func handleEvents(for identifier: String) { if let continuation = StorageBackgroundEventsRegistry.getContinuation(for: identifier) { continuation.resume(returning: true) + StorageBackgroundEventsRegistry.removeContinuation(for: identifier) } } diff --git a/AmplifyTestCommon/Mocks/MockStorageCategoryPlugin.swift b/AmplifyTestCommon/Mocks/MockStorageCategoryPlugin.swift index 59aa769ea5..9b2845bab1 100644 --- a/AmplifyTestCommon/Mocks/MockStorageCategoryPlugin.swift +++ b/AmplifyTestCommon/Mocks/MockStorageCategoryPlugin.swift @@ -176,7 +176,7 @@ class MockStorageCategoryPlugin: MessageReporter, StorageCategoryPlugin { return try await taskAdapter.value } - func handleBackgroundEvents(identifier: String) async -> Bool { + func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { false } diff --git a/AmplifyTests/CategoryTests/Hub/AmplifyOperationHubTests.swift b/AmplifyTests/CategoryTests/Hub/AmplifyOperationHubTests.swift index e30c9628d4..f90619d673 100644 --- a/AmplifyTests/CategoryTests/Hub/AmplifyOperationHubTests.swift +++ b/AmplifyTests/CategoryTests/Hub/AmplifyOperationHubTests.swift @@ -217,7 +217,7 @@ class MockDispatchingStoragePlugin: StorageCategoryPlugin { return operation } - func handleBackgroundEvents(identifier: String) async -> Bool { + func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { false } From cf0cd9a1ce5aff41d3a1484aed8a952ea9b80ab1 Mon Sep 17 00:00:00 2001 From: Brennan Stehling Date: Wed, 19 Oct 2022 13:57:18 -0700 Subject: [PATCH 2/4] handles race condition and coordinates with tests for handling behavior --- .../StorageBackgroundEventsRegistry.swift | 18 +++++++- ...StorageBackgroundEventsRegistryTests.swift | 45 ++++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift index a726ed617b..84f94eb2af 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift @@ -7,16 +7,23 @@ import Foundation +extension Notification.Name { + static let StorageBackgroundEventsRegistryWaiting = Notification.Name("StorageBackgroundEventsRegistryWaiting") +} + /// Background events registry. /// /// Discussion: /// Multiple URLSession instances could be running background events with their own unique identifier. Those can be run /// independently of the Amplify Storage plugin and this function will indiciate if it will handle the given identifier. -class StorageBackgroundEventsRegistry { +actor StorageBackgroundEventsRegistry { typealias StorageBackgroundEventsContinuation = CheckedContinuation static var identifier: String? static var continuation: StorageBackgroundEventsContinuation? + // override for use with unit tests + static var notificationCenter: NotificationCenter? + /// Handles background events for URLSession on iOS. /// - Parameters: /// - identifier: session identifier @@ -27,10 +34,17 @@ class StorageBackgroundEventsRegistry { return await withCheckedContinuation { (continuation: CheckedContinuation) in self.continuation = continuation + notifyWaiting(for: identifier) } } - // MARK: - Internal - + /// Notifies observes when waiting for continuation to be resumed. + /// - Parameters: + /// - identifier: session identifier + private static func notifyWaiting(for identifier: String) { + let notificationCenter = notificationCenter ?? NotificationCenter.default + notificationCenter.post(name: Notification.Name.StorageBackgroundEventsRegistryWaiting, object: identifier) + } // The storage plugin will register the session identifier when it is configured. static func register(identifier: String) { diff --git a/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift b/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift index d2fe6f430a..92f9b8baa1 100644 --- a/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift +++ b/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift @@ -18,7 +18,25 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { let otherIdentifier = UUID().uuidString StorageBackgroundEventsRegistry.register(identifier: identifier) - let done = asyncExpectation(description: "done", expectedFulfillmentCount: 2) + let notificationCenter = NotificationCenter() + StorageBackgroundEventsRegistry.notificationCenter = notificationCenter + defer { + StorageBackgroundEventsRegistry.notificationCenter = nil + } + + let done = asyncExpectation(description: "done") + let waiting = asyncExpectation(description: "waiting") + + notificationCenter.addObserver(forName: Notification.Name.StorageBackgroundEventsRegistryWaiting, object: nil, queue: nil) { notification in + guard let notificationIdentifier = notification.object as? String else { + XCTFail("Identifier not defined") + return + } + XCTAssertEqual(notificationIdentifier, identifier) + Task { + await waiting.fulfill() + } + } Task { let handled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) @@ -26,16 +44,23 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { XCTAssertTrue(handled) } + await waitForExpectations([waiting]) + + let didContinue = await handleEvents(for: identifier) + XCTAssertTrue(didContinue) + await waitForExpectations([done]) + + let otherDone = asyncExpectation(description: "other done") + Task { let otherHandled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: otherIdentifier) - await done.fulfill() + await otherDone.fulfill() XCTAssertFalse(otherHandled) } - handleEvents(for: identifier) - handleEvents(for: otherIdentifier) - - await waitForExpectations([done]) + let didNotContinue = await handleEvents(for: otherIdentifier) + XCTAssertFalse(didNotContinue) + await waitForExpectations([otherDone]) } func testHandlingUnregisteredIdentifier() async throws { @@ -55,10 +80,16 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { } // Simulates URLSessionDelegate behavior - func handleEvents(for identifier: String) { + func handleEvents(for identifier: String) async -> Bool { + await Task.yield() + if let continuation = StorageBackgroundEventsRegistry.getContinuation(for: identifier) { continuation.resume(returning: true) StorageBackgroundEventsRegistry.removeContinuation(for: identifier) + return true + } else { + print("No continuation for identifier: \(identifier)") + return false } } From fbde41b597db1e4acfa1d77ac4b57fe47f16dcf2 Mon Sep 17 00:00:00 2001 From: Brennan Stehling Date: Fri, 21 Oct 2022 12:51:06 -0700 Subject: [PATCH 3/4] notifies for StorageBackgroundEventsRegistryWaiting only when notificationCenter is defined --- .../Support/Internal/StorageBackgroundEventsRegistry.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift index 84f94eb2af..0395162d6d 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift @@ -42,8 +42,7 @@ actor StorageBackgroundEventsRegistry { /// - Parameters: /// - identifier: session identifier private static func notifyWaiting(for identifier: String) { - let notificationCenter = notificationCenter ?? NotificationCenter.default - notificationCenter.post(name: Notification.Name.StorageBackgroundEventsRegistryWaiting, object: identifier) + notificationCenter?.post(name: Notification.Name.StorageBackgroundEventsRegistryWaiting, object: identifier) } // The storage plugin will register the session identifier when it is configured. From 175dc7d6cfd6ffa8e739c9253ba26e102b15364e Mon Sep 17 00:00:00 2001 From: Brennan Stehling Date: Fri, 21 Oct 2022 13:13:46 -0700 Subject: [PATCH 4/4] makes StorageBackgroundEventsRegistry work as a singleton so the actor protects state --- ...SS3StoragePlugin+AsyncClientBehavior.swift | 2 +- .../Service/Storage/AWSS3StorageService.swift | 8 ++++-- .../StorageBackgroundEventsRegistry.swift | 26 ++++++++++++------- .../StorageServiceSessionDelegate.swift | 14 +++++----- ...StorageBackgroundEventsRegistryTests.swift | 20 +++++++------- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift index 81313aedf0..b04117d243 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/AWSS3StoragePlugin+AsyncClientBehavior.swift @@ -120,7 +120,7 @@ extension AWSS3StoragePlugin { } public func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { - await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) + await StorageBackgroundEventsRegistry.shared.handleEventsForBackgroundURLSession(identifier: identifier) } } diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Service/Storage/AWSS3StorageService.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Service/Storage/AWSS3StorageService.swift index 055607d719..209dce23b9 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Service/Storage/AWSS3StorageService.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Service/Storage/AWSS3StorageService.swift @@ -108,7 +108,9 @@ class AWSS3StorageService: AWSS3StorageServiceBehaviour, StorageServiceProxy { self.awsS3 = awsS3 self.bucket = bucket - StorageBackgroundEventsRegistry.register(identifier: identifier) + Task { + await StorageBackgroundEventsRegistry.shared.register(identifier: identifier) + } delegate.storageService = self @@ -125,7 +127,9 @@ class AWSS3StorageService: AWSS3StorageServiceBehaviour, StorageServiceProxy { } deinit { - StorageBackgroundEventsRegistry.unregister(identifier: identifier) + Task { + await StorageBackgroundEventsRegistry.shared.unregister(identifier: identifier) + } } func reset() { diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift index 0395162d6d..e43cbcac0e 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageBackgroundEventsRegistry.swift @@ -18,18 +18,26 @@ extension Notification.Name { /// independently of the Amplify Storage plugin and this function will indiciate if it will handle the given identifier. actor StorageBackgroundEventsRegistry { typealias StorageBackgroundEventsContinuation = CheckedContinuation - static var identifier: String? - static var continuation: StorageBackgroundEventsContinuation? + + @MainActor + static let shared = StorageBackgroundEventsRegistry() + + private var identifier: String? + private var continuation: StorageBackgroundEventsContinuation? // override for use with unit tests - static var notificationCenter: NotificationCenter? + internal private(set) var notificationCenter: NotificationCenter? + + func change(notificationCenter: NotificationCenter?) { + self.notificationCenter = notificationCenter + } /// Handles background events for URLSession on iOS. /// - Parameters: /// - identifier: session identifier /// - completionHandler: completion handler /// - Returns: indicates if the identifier was registered and will be handled - static func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { + func handleEventsForBackgroundURLSession(identifier: String) async -> Bool { guard self.identifier == identifier else { return false } return await withCheckedContinuation { (continuation: CheckedContinuation) in @@ -41,29 +49,29 @@ actor StorageBackgroundEventsRegistry { /// Notifies observes when waiting for continuation to be resumed. /// - Parameters: /// - identifier: session identifier - private static func notifyWaiting(for identifier: String) { + private func notifyWaiting(for identifier: String) { notificationCenter?.post(name: Notification.Name.StorageBackgroundEventsRegistryWaiting, object: identifier) } // The storage plugin will register the session identifier when it is configured. - static func register(identifier: String) { + func register(identifier: String) { self.identifier = identifier } // When the storage function is deinitialized it will unregister the session identifier. - static func unregister(identifier: String) { + func unregister(identifier: String) { if self.identifier == identifier { self.identifier = nil } } // When URLSession is done processing background events it will use this function to get the completion handler. - static func getContinuation(for identifier: String) -> StorageBackgroundEventsContinuation? { + func getContinuation(for identifier: String) -> StorageBackgroundEventsContinuation? { self.identifier == identifier ? continuation : nil } // Once the background event completion handler is used it can be cleared. - static func removeContinuation(for identifier: String) { + func removeContinuation(for identifier: String) { if self.identifier == identifier { self.continuation = nil } diff --git a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift index 66cd17c4d0..cac86ccfa9 100644 --- a/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift +++ b/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Support/Internal/StorageServiceSessionDelegate.swift @@ -53,13 +53,15 @@ extension StorageServiceSessionDelegate: URLSessionDelegate { func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { logURLSessionActivity("Session did finish background events") - if let identifier = session.configuration.identifier, - let continuation = StorageBackgroundEventsRegistry.getContinuation(for: identifier) { - // Must be run on main thread as covered by Apple Developer docs. - Task { @MainActor in - continuation.resume(returning: true) + Task { + if let identifier = session.configuration.identifier, + let continuation = await StorageBackgroundEventsRegistry.shared.getContinuation(for: identifier) { + // Must be run on main thread as covered by Apple Developer docs. + Task { @MainActor in + continuation.resume(returning: true) + } + await StorageBackgroundEventsRegistry.shared.removeContinuation(for: identifier) } - StorageBackgroundEventsRegistry.removeContinuation(for: identifier) } } diff --git a/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift b/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift index 92f9b8baa1..f6c4f80070 100644 --- a/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift +++ b/AmplifyPlugins/Storage/Tests/AWSS3StoragePluginTests/Support/Internal/StorageBackgroundEventsRegistryTests.swift @@ -16,12 +16,14 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { func testRegisteringAndUnregister() async throws { let identifier = UUID().uuidString let otherIdentifier = UUID().uuidString - StorageBackgroundEventsRegistry.register(identifier: identifier) + await StorageBackgroundEventsRegistry.shared.register(identifier: identifier) let notificationCenter = NotificationCenter() - StorageBackgroundEventsRegistry.notificationCenter = notificationCenter + await StorageBackgroundEventsRegistry.shared.change(notificationCenter: notificationCenter) defer { - StorageBackgroundEventsRegistry.notificationCenter = nil + Task { + await StorageBackgroundEventsRegistry.shared.change(notificationCenter: nil) + } } let done = asyncExpectation(description: "done") @@ -39,7 +41,7 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { } Task { - let handled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) + let handled = await StorageBackgroundEventsRegistry.shared.handleEventsForBackgroundURLSession(identifier: identifier) await done.fulfill() XCTAssertTrue(handled) } @@ -53,7 +55,7 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { let otherDone = asyncExpectation(description: "other done") Task { - let otherHandled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: otherIdentifier) + let otherHandled = await StorageBackgroundEventsRegistry.shared.handleEventsForBackgroundURLSession(identifier: otherIdentifier) await otherDone.fulfill() XCTAssertFalse(otherHandled) } @@ -66,12 +68,12 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { func testHandlingUnregisteredIdentifier() async throws { let identifier = UUID().uuidString let otherIdentifier = UUID().uuidString - StorageBackgroundEventsRegistry.register(identifier: otherIdentifier) + await StorageBackgroundEventsRegistry.shared.register(identifier: otherIdentifier) let done = asyncExpectation(description: "done") Task { - let handled = await StorageBackgroundEventsRegistry.handleEventsForBackgroundURLSession(identifier: identifier) + let handled = await StorageBackgroundEventsRegistry.shared.handleEventsForBackgroundURLSession(identifier: identifier) await done.fulfill() XCTAssertFalse(handled) } @@ -83,9 +85,9 @@ class StorageBackgroundEventsRegistryTests: XCTestCase { func handleEvents(for identifier: String) async -> Bool { await Task.yield() - if let continuation = StorageBackgroundEventsRegistry.getContinuation(for: identifier) { + if let continuation = await StorageBackgroundEventsRegistry.shared.getContinuation(for: identifier) { continuation.resume(returning: true) - StorageBackgroundEventsRegistry.removeContinuation(for: identifier) + await StorageBackgroundEventsRegistry.shared.removeContinuation(for: identifier) return true } else { print("No continuation for identifier: \(identifier)")