From 2907dbc1b7de57b4a512e154a46edcbd387dda04 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 13:34:13 -0400 Subject: [PATCH 01/14] [Core] Add availability gate on implementation --- FirebaseCore/Sources/FIRHeartbeatLogger.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FirebaseCore/Sources/FIRHeartbeatLogger.m b/FirebaseCore/Sources/FIRHeartbeatLogger.m index d1c77ee4f2f..4becd085c22 100644 --- a/FirebaseCore/Sources/FIRHeartbeatLogger.m +++ b/FirebaseCore/Sources/FIRHeartbeatLogger.m @@ -87,7 +87,8 @@ - (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload { } - (void)flushHeartbeatsIntoPayloadWithCompletionHandler: - (void (^)(FIRHeartbeatsPayload *))completionHandler { + (void (^)(FIRHeartbeatsPayload *))completionHandler + API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) { [_heartbeatController flushAsyncWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { completionHandler(payload); }]; From 3e9c506844eff2d6bc0ea45fb6c0f2d295bdb220 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 13:36:10 -0400 Subject: [PATCH 02/14] Add changelog entry --- FirebaseCore/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FirebaseCore/CHANGELOG.md b/FirebaseCore/CHANGELOG.md index efaf85d2fa4..cc3b3e510f7 100644 --- a/FirebaseCore/CHANGELOG.md +++ b/FirebaseCore/CHANGELOG.md @@ -1,3 +1,7 @@ +# Firebase 11.4.2 +- [fixed] CocoaPods only release to fix iOS 12 build failure resulting from + missing OS availability check in the `FirebaseCoreExtension` SDK. + # Firebase 11.4.1 - [fixed] CocoaPods only release to revert breaking change in `FirebaseCoreExtension` SDK. (#13942) From e4af49983a4c8951c18e733fa008db44dc4af934 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 13:52:01 -0400 Subject: [PATCH 03/14] bump specs --- Firebase.podspec | 4 ++-- FirebaseCore.podspec | 2 +- FirebaseCoreExtension.podspec | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Firebase.podspec b/Firebase.podspec index 1f11d9f682f..33068324e86 100644 --- a/Firebase.podspec +++ b/Firebase.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Firebase' - s.version = '11.4.1' + s.version = '11.4.2' s.summary = 'Firebase' s.description = <<-DESC @@ -43,7 +43,7 @@ Simplify your app development, grow your user base, and monetize more effectivel end s.subspec 'CoreOnly' do |ss| - ss.dependency 'FirebaseCore', '11.4.1' + ss.dependency 'FirebaseCore', '11.4.2' ss.source_files = 'CoreOnly/Sources/Firebase.h' ss.preserve_paths = 'CoreOnly/Sources/module.modulemap' if ENV['FIREBASE_POD_REPO_FOR_DEV_POD'] then diff --git a/FirebaseCore.podspec b/FirebaseCore.podspec index 45697bdff72..4dcb9127a96 100644 --- a/FirebaseCore.podspec +++ b/FirebaseCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCore' - s.version = '11.4.1' + s.version = '11.4.2' s.summary = 'Firebase Core' s.description = <<-DESC diff --git a/FirebaseCoreExtension.podspec b/FirebaseCoreExtension.podspec index a5517189f2d..af0d1d35566 100644 --- a/FirebaseCoreExtension.podspec +++ b/FirebaseCoreExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreExtension' - s.version = '11.4.1' + s.version = '11.4.2' s.summary = 'Extended FirebaseCore APIs for Firebase product SDKs' s.description = <<-DESC From 73cb34f9652b5acd70d198b2ec83a8151501fdef Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 13:53:55 -0400 Subject: [PATCH 04/14] undo bump in extension pod --- FirebaseCoreExtension.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseCoreExtension.podspec b/FirebaseCoreExtension.podspec index af0d1d35566..a5517189f2d 100644 --- a/FirebaseCoreExtension.podspec +++ b/FirebaseCoreExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreExtension' - s.version = '11.4.2' + s.version = '11.4.1' s.summary = 'Extended FirebaseCore APIs for Firebase product SDKs' s.description = <<-DESC From 7db9bdd9a4963cc0d0eaaa5038d78ffd0f7f7b7c Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 14:23:59 -0400 Subject: [PATCH 05/14] Runtime approach --- FirebaseCore/Extension/FIRHeartbeatLogger.h | 6 ++--- FirebaseCore/Sources/FIRHeartbeatLogger.m | 28 +++++++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/FirebaseCore/Extension/FIRHeartbeatLogger.h b/FirebaseCore/Extension/FIRHeartbeatLogger.h index 962974e1bca..808537c6d6d 100644 --- a/FirebaseCore/Extension/FIRHeartbeatLogger.h +++ b/FirebaseCore/Extension/FIRHeartbeatLogger.h @@ -40,8 +40,7 @@ typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) { #ifndef FIREBASE_BUILD_CMAKE /// Returns the header value for the heartbeat logger via the given completion handler.. -- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler - API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)); +- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler; /// Return the header value for the heartbeat logger. - (NSString *_Nullable)headerValue; @@ -87,8 +86,7 @@ NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *he /// @note This API is thread-safe. /// @param completionHandler A completion handler to process the flushed payload of heartbeats. - (void)flushHeartbeatsIntoPayloadWithCompletionHandler: - (void (^)(FIRHeartbeatsPayload *))completionHandler - API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)); + (void (^)(FIRHeartbeatsPayload *))completionHandler; #endif // FIREBASE_BUILD_CMAKE /// Gets today's corresponding heartbeat code. diff --git a/FirebaseCore/Sources/FIRHeartbeatLogger.m b/FirebaseCore/Sources/FIRHeartbeatLogger.m index 4becd085c22..c3df0dc2849 100644 --- a/FirebaseCore/Sources/FIRHeartbeatLogger.m +++ b/FirebaseCore/Sources/FIRHeartbeatLogger.m @@ -74,11 +74,15 @@ - (NSString *_Nullable)headerValue { return FIRHeaderValueFromHeartbeatsPayload([self flushHeartbeatsIntoPayload]); } -- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler - API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) { - [self flushHeartbeatsIntoPayloadWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { - completionHandler(FIRHeaderValueFromHeartbeatsPayload(payload)); - }]; +- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler { + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)) { + [self flushHeartbeatsIntoPayloadWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { + completionHandler(FIRHeaderValueFromHeartbeatsPayload(payload)); + }]; + } else { + // no-op + completionHandler(nil); + } } - (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload { @@ -87,11 +91,15 @@ - (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload { } - (void)flushHeartbeatsIntoPayloadWithCompletionHandler: - (void (^)(FIRHeartbeatsPayload *))completionHandler - API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) { - [_heartbeatController flushAsyncWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { - completionHandler(payload); - }]; + (void (^)(FIRHeartbeatsPayload *))completionHandler { + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)) { + [_heartbeatController flushAsyncWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { + completionHandler(payload); + }]; + } else { + // no-op + completionHandler(nil); + } } #endif // FIREBASE_BUILD_CMAKE From cde104d747190827a63d9676c1eaebb3d2a182ad Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 14:43:05 -0400 Subject: [PATCH 06/14] Move issue down into FirebaseCoreInternal --- .../_ObjC_HeartbeatController.swift | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift index fdd13af13be..fb1eb1d8e98 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift @@ -49,10 +49,15 @@ public class _ObjC_HeartbeatController: NSObject { /// /// - Note: This API is thread-safe. /// - Returns: A heartbeats payload for the flushed heartbeat(s). - @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) - public func flushAsync() async -> _ObjC_HeartbeatsPayload { - let heartbeatsPayload = await heartbeatController.flushAsync() - return _ObjC_HeartbeatsPayload(heartbeatsPayload) + public func flushAsync(completionHandler: @escaping (_ObjC_HeartbeatsPayload) -> Void) { + if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) { + Task { + let heartbeatsPayload = await heartbeatController.flushAsync() + completionHandler(_ObjC_HeartbeatsPayload(heartbeatsPayload)) + } + } else { + completionHandler(_ObjC_HeartbeatsPayload(HeartbeatsPayload.emptyPayload)) + } } /// Synchronously flushes the heartbeat for today. From 94bb5eeca6b04eb51f1596887feed308c80d13c0 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 14:43:28 -0400 Subject: [PATCH 07/14] Revert "Runtime approach" This reverts commit 7db9bdd9a4963cc0d0eaaa5038d78ffd0f7f7b7c. --- FirebaseCore/Extension/FIRHeartbeatLogger.h | 6 +++-- FirebaseCore/Sources/FIRHeartbeatLogger.m | 28 ++++++++------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/FirebaseCore/Extension/FIRHeartbeatLogger.h b/FirebaseCore/Extension/FIRHeartbeatLogger.h index 808537c6d6d..962974e1bca 100644 --- a/FirebaseCore/Extension/FIRHeartbeatLogger.h +++ b/FirebaseCore/Extension/FIRHeartbeatLogger.h @@ -40,7 +40,8 @@ typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) { #ifndef FIREBASE_BUILD_CMAKE /// Returns the header value for the heartbeat logger via the given completion handler.. -- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler; +- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler + API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)); /// Return the header value for the heartbeat logger. - (NSString *_Nullable)headerValue; @@ -86,7 +87,8 @@ NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *he /// @note This API is thread-safe. /// @param completionHandler A completion handler to process the flushed payload of heartbeats. - (void)flushHeartbeatsIntoPayloadWithCompletionHandler: - (void (^)(FIRHeartbeatsPayload *))completionHandler; + (void (^)(FIRHeartbeatsPayload *))completionHandler + API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)); #endif // FIREBASE_BUILD_CMAKE /// Gets today's corresponding heartbeat code. diff --git a/FirebaseCore/Sources/FIRHeartbeatLogger.m b/FirebaseCore/Sources/FIRHeartbeatLogger.m index c3df0dc2849..4becd085c22 100644 --- a/FirebaseCore/Sources/FIRHeartbeatLogger.m +++ b/FirebaseCore/Sources/FIRHeartbeatLogger.m @@ -74,15 +74,11 @@ - (NSString *_Nullable)headerValue { return FIRHeaderValueFromHeartbeatsPayload([self flushHeartbeatsIntoPayload]); } -- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler { - if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)) { - [self flushHeartbeatsIntoPayloadWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { - completionHandler(FIRHeaderValueFromHeartbeatsPayload(payload)); - }]; - } else { - // no-op - completionHandler(nil); - } +- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler + API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) { + [self flushHeartbeatsIntoPayloadWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { + completionHandler(FIRHeaderValueFromHeartbeatsPayload(payload)); + }]; } - (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload { @@ -91,15 +87,11 @@ - (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload { } - (void)flushHeartbeatsIntoPayloadWithCompletionHandler: - (void (^)(FIRHeartbeatsPayload *))completionHandler { - if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)) { - [_heartbeatController flushAsyncWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { - completionHandler(payload); - }]; - } else { - // no-op - completionHandler(nil); - } + (void (^)(FIRHeartbeatsPayload *))completionHandler + API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) { + [_heartbeatController flushAsyncWithCompletionHandler:^(FIRHeartbeatsPayload *payload) { + completionHandler(payload); + }]; } #endif // FIREBASE_BUILD_CMAKE From 4fbdbce6a45caad44ad5ed0ae7f5178eaa894245 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 15:51:32 -0400 Subject: [PATCH 08/14] [skip ci] review --- .../Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift index fb1eb1d8e98..8c4aaa86a47 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift @@ -56,6 +56,8 @@ public class _ObjC_HeartbeatController: NSObject { completionHandler(_ObjC_HeartbeatsPayload(heartbeatsPayload)) } } else { + // It is not expected to reach this state as this API should only be + // called on iOS 13.0+. completionHandler(_ObjC_HeartbeatsPayload(HeartbeatsPayload.emptyPayload)) } } From a2c8aaec4e1b1b345de04f84d4461915150d544d Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 15:52:46 -0400 Subject: [PATCH 09/14] [skip ci] review: changelog --- FirebaseCore/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseCore/CHANGELOG.md b/FirebaseCore/CHANGELOG.md index cc3b3e510f7..89ed80fcf55 100644 --- a/FirebaseCore/CHANGELOG.md +++ b/FirebaseCore/CHANGELOG.md @@ -1,6 +1,6 @@ # Firebase 11.4.2 - [fixed] CocoaPods only release to fix iOS 12 build failure resulting from - missing OS availability check in the `FirebaseCoreExtension` SDK. + incomplete implementation in the FirebaseCoreInternal CocoaPod. # Firebase 11.4.1 - [fixed] CocoaPods only release to revert breaking change in From 1a5827bd346448f682da9aadca4de05ad0c6155c Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 15:56:10 -0400 Subject: [PATCH 10/14] Bump FirebaseCoreInternal --- FirebaseCoreInternal.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseCoreInternal.podspec b/FirebaseCoreInternal.podspec index df449a9b8c6..38cd7901466 100644 --- a/FirebaseCoreInternal.podspec +++ b/FirebaseCoreInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreInternal' - s.version = '11.4.0' + s.version = '11.4.2' s.summary = 'APIs for internal FirebaseCore usage.' s.description = <<-DESC From 5e6b55de1ec1abddce0676fef3ae960eea38c787 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 15:58:11 -0400 Subject: [PATCH 11/14] Bump core's dep on coreinternal --- FirebaseCore.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseCore.podspec b/FirebaseCore.podspec index 4dcb9127a96..70c7cd728ad 100644 --- a/FirebaseCore.podspec +++ b/FirebaseCore.podspec @@ -53,7 +53,7 @@ Firebase Core includes FIRApp and FIROptions which provide central configuration # Remember to also update version in `cmake/external/GoogleUtilities.cmake` s.dependency 'GoogleUtilities/Environment', '~> 8.0' s.dependency 'GoogleUtilities/Logger', '~> 8.0' - s.dependency 'FirebaseCoreInternal', '~> 11.4' + s.dependency 'FirebaseCoreInternal', '>= 11.4.2', '< 12.0' s.pod_target_xcconfig = { 'GCC_C_LANGUAGE_STANDARD' => 'c99', From 13affce1badd61652ad65f987fd47a286fd8efb5 Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 16:02:52 -0400 Subject: [PATCH 12/14] Add TODO --- .../Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift index 8c4aaa86a47..cef5c7d9a8e 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift @@ -50,6 +50,8 @@ public class _ObjC_HeartbeatController: NSObject { /// - Note: This API is thread-safe. /// - Returns: A heartbeats payload for the flushed heartbeat(s). public func flushAsync(completionHandler: @escaping (_ObjC_HeartbeatsPayload) -> Void) { + // TODO: When minimum version moves to iOS 13.0, restore the async version + // removed in #13952. if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) { Task { let heartbeatsPayload = await heartbeatController.flushAsync() From 4e9c6dded820d6fc7c577d313253b352bc652f8b Mon Sep 17 00:00:00 2001 From: Nick Cooke Date: Tue, 22 Oct 2024 17:14:58 -0400 Subject: [PATCH 13/14] Fix auth test build failure from global test run --- .../Tests/Unit/AuthBackendRPCImplementationTests.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FirebaseAuth/Tests/Unit/AuthBackendRPCImplementationTests.swift b/FirebaseAuth/Tests/Unit/AuthBackendRPCImplementationTests.swift index 754fa761a54..7180313df34 100644 --- a/FirebaseAuth/Tests/Unit/AuthBackendRPCImplementationTests.swift +++ b/FirebaseAuth/Tests/Unit/AuthBackendRPCImplementationTests.swift @@ -534,6 +534,11 @@ class AuthBackendRPCImplementationTests: RPCBaseTests { #if COCOAPODS || SWIFT_PACKAGE private class FakeHeartbeatLogger: NSObject, FIRHeartbeatLoggerProtocol { + func headerValue() -> String? { + // `asyncHeaderValue` should be used instead. + fatalError("FakeHeartbeatLogger headerValue should not be used in tests.") + } + func asyncHeaderValue() async -> String? { let payload = flushHeartbeatsIntoPayload() guard !payload.isEmpty else { From 181c7c879415efe1884439dd579b27fc61d3cd5b Mon Sep 17 00:00:00 2001 From: Nick Cooke <36927374+ncooke3@users.noreply.github.com> Date: Tue, 22 Oct 2024 17:25:44 -0400 Subject: [PATCH 14/14] [Core] Prefer completion handler APIs in Core Internal (#13954) --- .../HeartbeatController.swift | 48 +++++++++---------- .../_ObjC_HeartbeatController.swift | 11 +---- .../HeartbeatLoggingIntegrationTests.swift | 37 ++++++++------ .../Tests/Unit/HeartbeatControllerTests.swift | 38 ++++++++------- 4 files changed, 68 insertions(+), 66 deletions(-) diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift index e4a2cc4c335..e7f4ece2781 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift @@ -126,34 +126,30 @@ public final class HeartbeatController { } } - @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) - public func flushAsync() async -> HeartbeatsPayload { - return await withCheckedContinuation { continuation in - let resetTransform = { (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in - guard let oldHeartbeatsBundle = heartbeatsBundle else { - return nil // Storage was empty. - } - // The new value that's stored will use the old's cache to prevent the - // logging of duplicates after flushing. - return HeartbeatsBundle( - capacity: self.heartbeatsStorageCapacity, - cache: oldHeartbeatsBundle.lastAddedHeartbeatDates - ) + public func flushAsync(completionHandler: @escaping (HeartbeatsPayload) -> Void) { + let resetTransform = { (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in + guard let oldHeartbeatsBundle = heartbeatsBundle else { + return nil // Storage was empty. } + // The new value that's stored will use the old's cache to prevent the + // logging of duplicates after flushing. + return HeartbeatsBundle( + capacity: self.heartbeatsStorageCapacity, + cache: oldHeartbeatsBundle.lastAddedHeartbeatDates + ) + } - // Asynchronously gets and returns the stored heartbeats, resetting storage - // using the given transform. - storage.getAndSetAsync(using: resetTransform) { result in - switch result { - case let .success(heartbeatsBundle): - // If no heartbeats bundle was stored, return an empty payload. - continuation - .resume(returning: heartbeatsBundle?.makeHeartbeatsPayload() ?? HeartbeatsPayload - .emptyPayload) - case .failure: - // If the operation throws, assume no heartbeat(s) were retrieved or set. - continuation.resume(returning: HeartbeatsPayload.emptyPayload) - } + // Asynchronously gets and returns the stored heartbeats, resetting storage + // using the given transform. + storage.getAndSetAsync(using: resetTransform) { result in + switch result { + case let .success(heartbeatsBundle): + // If no heartbeats bundle was stored, return an empty payload. + completionHandler(heartbeatsBundle?.makeHeartbeatsPayload() ?? HeartbeatsPayload + .emptyPayload) + case .failure: + // If the operation throws, assume no heartbeat(s) were retrieved or set. + completionHandler(HeartbeatsPayload.emptyPayload) } } } diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift index cef5c7d9a8e..c60a1e11cc5 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift @@ -52,15 +52,8 @@ public class _ObjC_HeartbeatController: NSObject { public func flushAsync(completionHandler: @escaping (_ObjC_HeartbeatsPayload) -> Void) { // TODO: When minimum version moves to iOS 13.0, restore the async version // removed in #13952. - if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) { - Task { - let heartbeatsPayload = await heartbeatController.flushAsync() - completionHandler(_ObjC_HeartbeatsPayload(heartbeatsPayload)) - } - } else { - // It is not expected to reach this state as this API should only be - // called on iOS 13.0+. - completionHandler(_ObjC_HeartbeatsPayload(HeartbeatsPayload.emptyPayload)) + heartbeatController.flushAsync { heartbeatsPayload in + completionHandler(_ObjC_HeartbeatsPayload(heartbeatsPayload)) } } diff --git a/FirebaseCore/Internal/Tests/Integration/HeartbeatLoggingIntegrationTests.swift b/FirebaseCore/Internal/Tests/Integration/HeartbeatLoggingIntegrationTests.swift index b306405f4bd..3a9823aa94a 100644 --- a/FirebaseCore/Internal/Tests/Integration/HeartbeatLoggingIntegrationTests.swift +++ b/FirebaseCore/Internal/Tests/Integration/HeartbeatLoggingIntegrationTests.swift @@ -52,29 +52,36 @@ class HeartbeatLoggingIntegrationTests: XCTestCase { ) } - @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) - func testLogAndFlushAsync() async throws { + func testLogAndFlushAsync() throws { // Given let heartbeatController = HeartbeatController(id: #function) let expectedDate = HeartbeatsPayload.dateFormatter.string(from: Date()) + let expectation = self.expectation(description: #function) // When heartbeatController.log("dummy_agent") - let payload = await heartbeatController.flushAsync() - // Then - try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( - payload.headerValue(), - """ - { - "version": 2, - "heartbeats": [ + heartbeatController.flushAsync { payload in + // Then + do { + try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( + payload.headerValue(), + """ { - "agent": "dummy_agent", - "dates": ["\(expectedDate)"] + "version": 2, + "heartbeats": [ + { + "agent": "dummy_agent", + "dates": ["\(expectedDate)"] + } + ] } - ] + """ + ) + expectation.fulfill() + } catch { + XCTFail("Unexpected error: \(error)") } - """ - ) + } + waitForExpectations(timeout: 1.0) } /// This test may flake if it is executed during the transition from one day to the next. diff --git a/FirebaseCore/Internal/Tests/Unit/HeartbeatControllerTests.swift b/FirebaseCore/Internal/Tests/Unit/HeartbeatControllerTests.swift index ddf3d1c5d9d..82691ed3f24 100644 --- a/FirebaseCore/Internal/Tests/Unit/HeartbeatControllerTests.swift +++ b/FirebaseCore/Internal/Tests/Unit/HeartbeatControllerTests.swift @@ -58,35 +58,41 @@ class HeartbeatControllerTests: XCTestCase { assertHeartbeatControllerFlushesEmptyPayload(controller) } - @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *) - func testLogAndFlushAsync() async throws { + func testLogAndFlushAsync() throws { // Given let controller = HeartbeatController( storage: HeartbeatStorageFake(), dateProvider: { self.date } ) + let expectation = expectation(description: #function) assertHeartbeatControllerFlushesEmptyPayload(controller) // When controller.log("dummy_agent") - let heartbeatPayload = await controller.flushAsync() - - // Then - try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( - heartbeatPayload.headerValue(), - """ - { - "version": 2, - "heartbeats": [ + controller.flushAsync { heartbeatPayload in + // Then + do { + try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( + heartbeatPayload.headerValue(), + """ { - "agent": "dummy_agent", - "dates": ["2021-11-01"] + "version": 2, + "heartbeats": [ + { + "agent": "dummy_agent", + "dates": ["2021-11-01"] + } + ] } - ] + """ + ) + expectation.fulfill() + } catch { + XCTFail("Unexpected error: \(error)") } - """ - ) + } + waitForExpectations(timeout: 1.0) assertHeartbeatControllerFlushesEmptyPayload(controller) }