refactor(misc): remove obsolete OS availability checks (#16313)

This commit is contained in:
Nick Cooke authored and GitHub committed 2026-07-09 16:40:30 -04:00
1 parent c6b30ac647
commit e28a1a1a84
19 files changed
+88 -195

No files matched your search

@@ -37,13 +37,11 @@ final class AnalyticsAPITests {
Analytics.setDefaultEventParameters(["default": 100])
Analytics.sessionID { sessionID, error in }
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
Task {
let _: Int64? = try? await Analytics.sessionID()
}
Task {
let _: Int64? = try? await Analytics.sessionID()
}
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *)
@available(macOS 12.0, *)
@available(watchOS, unavailable)
func logTransactionUsage() {
let transaction: StoreKit.Transaction! = nil
@@ -53,11 +51,10 @@ final class AnalyticsAPITests {
// MARK: - AppDelegate
Analytics.handleEvents(forBackgroundURLSession: "session_id", completionHandler: {})
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
Task {
await Analytics.handleEvents(forBackgroundURLSession: "session_id")
}
Task {
await Analytics.handleEvents(forBackgroundURLSession: "session_id")
}
Analytics.handleOpen(URL(string: "https://google.com")!)
Analytics.handleUserActivity(NSUserActivity(activityType: "editing"))
@@ -198,7 +195,6 @@ final class AnalyticsAPITests {
// MARK: - Analytics + SwiftUI
@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *)
@available(watchOS, unavailable)
struct MyView: View {
let name: String
@@ -88,9 +88,7 @@ ASWebAuthenticationSession *_webAuthenticationVC;
completion(appDistributionError);
}];
if (@available(iOS 13.0, *)) {
authenticationVC.presentationContextProvider = self;
}
authenticationVC.presentationContextProvider = self;
_webAuthenticationVC = authenticationVC;
@@ -164,30 +162,26 @@ ASWebAuthenticationSession *_webAuthenticationVC;
return;
}
if (@available(iOS 13.0, *)) {
UIWindowScene *foregroundedScene = nil;
for (UIWindowScene *connectedScene in [UIApplication sharedApplication].connectedScenes) {
if (connectedScene.activationState == UISceneActivationStateForegroundActive) {
foregroundedScene = connectedScene;
break;
}
UIWindowScene *foregroundedScene = nil;
for (UIWindowScene *connectedScene in [UIApplication sharedApplication].connectedScenes) {
if (connectedScene.activationState == UISceneActivationStateForegroundActive) {
foregroundedScene = connectedScene;
break;
}
}
if (foregroundedScene) {
self.window = [[UIWindow alloc] initWithWindowScene:foregroundedScene];
} else if ([UIApplication sharedApplication].connectedScenes.count == 1) {
// There are situations where a scene isn't considered foreground in viewDidAppear
// and this fixes the issue in single scene apps.
// https://github.com/firebase/firebase-ios-sdk/issues/8096
UIWindowScene *scene =
(UIWindowScene *)[UIApplication sharedApplication].connectedScenes.anyObject;
self.window = [[UIWindow alloc] initWithWindowScene:scene];
} else {
// TODO: Consider using UISceneDidActivateNotification.
FIRFADInfoLog(@"No foreground scene found.");
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
if (foregroundedScene) {
self.window = [[UIWindow alloc] initWithWindowScene:foregroundedScene];
} else if ([UIApplication sharedApplication].connectedScenes.count == 1) {
// There are situations where a scene isn't considered foreground in viewDidAppear
// and this fixes the issue in single scene apps.
// https://github.com/firebase/firebase-ios-sdk/issues/8096
UIWindowScene *scene =
(UIWindowScene *)[UIApplication sharedApplication].connectedScenes.anyObject;
self.window = [[UIWindow alloc] initWithWindowScene:scene];
} else {
// TODO: Consider using UISceneDidActivateNotification.
FIRFADInfoLog(@"No foreground scene found.");
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
self.window.rootViewController = self.safariHostingViewController;
@@ -223,7 +217,7 @@ ASWebAuthenticationSession *_webAuthenticationVC;
}
- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:
(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)) {
(ASWebAuthenticationSession *)session {
return self.safariHostingViewController.view.window;
}
@@ -16,7 +16,6 @@
import XCTest
class AppDistributionAPITests: XCTestCase {
@available(iOS 13.0.0, *)
func asyncAPIs() async throws {
let distro = AppDistribution.appDistribution()
+2 -4
View File
@@ -44,8 +44,7 @@ NS_SWIFT_SENDABLE
#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;
@@ -91,8 +90,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.
+2 -4
View File
@@ -74,8 +74,7 @@ NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *he
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)) {
- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler {
[self flushHeartbeatsIntoPayloadWithCompletionHandler:^(FIRHeartbeatsPayload *payload) {
completionHandler(FIRHeaderValueFromHeartbeatsPayload(payload));
}];
@@ -87,8 +86,7 @@ NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *he
}
- (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 {
[_heartbeatController flushAsyncWithCompletionHandler:^(FIRHeartbeatsPayload *payload) {
completionHandler(payload);
}];
@@ -51,11 +51,9 @@ final class CoreAPITests {
// ...
}
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
await app.delete()
}
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
await app.delete()
}
}
+1 -5
View File
@@ -865,11 +865,7 @@ NSString *const kFIRTestAppName2 = @"test-app-name-2";
return NSApplicationDidBecomeActiveNotification;
#elif TARGET_OS_WATCH
// See comment in `- [FIRApp subscribeForAppDidBecomeActiveNotifications]`.
if (@available(watchOS 7.0, *)) {
return WKApplicationDidBecomeActiveNotification;
} else {
return kFIRAppReadyToConfigureSDKNotification;
}
return WKApplicationDidBecomeActiveNotification;
#endif
}
@@ -125,8 +125,7 @@
}];
}
- (void)testFlushingAsync_UsingV2API_WhenHeartbeatsAreStored_ReturnsNonEmptyPayload API_AVAILABLE(
ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) {
- (void)testFlushingAsync_UsingV2API_WhenHeartbeatsAreStored_ReturnsNonEmptyPayload {
// Given
FIRHeartbeatLogger *heartbeatLogger = self.heartbeatLogger;
NSString *expectedDate = [[self class] formattedStringForDate:[NSDate date]];
@@ -158,8 +157,7 @@
[self assertHeartbeatsPayloadIsEmpty:heartbeatsPayload];
}
- (void)testFlushingAsync_UsingV2API_WhenNoHeartbeatsAreStored_ReturnsEmptyPayload API_AVAILABLE(
ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0)) {
- (void)testFlushingAsync_UsingV2API_WhenNoHeartbeatsAreStored_ReturnsEmptyPayload {
// Given
FIRHeartbeatLogger *heartbeatLogger = self.heartbeatLogger;
// When
@@ -217,7 +217,7 @@ public enum StreamResponse<Message: Decodable & Sendable, Result: Decodable & Se
}
}
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 12.0, watchOS 8.0, *)
public extension Callable where Request: Sendable, Response: Sendable {
/// Creates a stream that yields responses from the streaming callable function.
///
+1 -1
View File
@@ -407,7 +407,7 @@ enum FunctionsConstants {
}
}
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 12.0, watchOS 8.0, *)
func stream(at url: URL,
data: SendableWrapper?,
options: HTTPSCallableOptions?,
@@ -165,7 +165,7 @@ public final class HTTPSCallable: NSObject, Sendable {
.callFunction(at: url, withObject: data, options: options, timeout: timeoutInterval)
}
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 12.0, watchOS 8.0, *)
func stream(_ data: SendableWrapper? = nil) -> AsyncThrowingStream<JSONStreamResponse, Error> {
functions.stream(at: url, data: data, options: options, timeout: timeoutInterval)
}
@@ -895,7 +895,7 @@ class IntegrationTests: XCTestCase {
/// indicate the callable function does not accept parameters.
private struct EmptyRequest: Encodable, Sendable {}
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
@available(macOS 12.0, watchOS 8.0, *)
extension IntegrationTests {
func testStream_NoArgs() async throws {
// 1. Custom `EmptyRequest` struct is passed as a placeholder generic arg.
@@ -203,11 +203,7 @@ static NSString *const kFIRInstallationsIIDCreationTimePlistKey = @"|S|cre";
NSMutableDictionary *plistContent = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
plistContent[kFIRInstallationsIIDCreationTimePlistKey] = nil;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
return [plistContent writeToURL:[NSURL fileURLWithPath:path] error:outError];
}
return [plistContent writeToFile:path atomically:YES];
return [plistContent writeToURL:[NSURL fileURLWithPath:path] error:outError];
}
- (BOOL)hasPlistIIDFlag {
@@ -80,18 +80,7 @@ static NSString *const kFIRInstallationsIIDTokenKeychainId = @"com.google.iid-to
NSError *archiverError;
NSKeyedUnarchiver *unarchiver;
if (@available(iOS 11.0, tvOS 11.0, macOS 10.13, *)) {
unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&archiverError];
} else {
@try {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
#pragma clang diagnostic pop
} @catch (NSException *exception) {
archiverError = [FIRInstallationsErrorUtil keyedArchiverErrorWithException:exception];
}
}
unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&archiverError];
if (!unarchiver) {
NSError *error = archiverError ?: [FIRInstallationsErrorUtil corruptedIIDTokenData];
@@ -51,14 +51,12 @@ final class InstallationsAPITests {
}
}
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
try await Installations.installations().installationID()
} catch {
// ...
}
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
try await Installations.installations().installationID()
} catch {
// ...
}
}
@@ -71,14 +69,12 @@ final class InstallationsAPITests {
}
}
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
_ = try await Installations.installations().authToken()
} catch {
// ...
}
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
_ = try await Installations.installations().authToken()
} catch {
// ...
}
}
@@ -91,14 +87,12 @@ final class InstallationsAPITests {
}
}
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
_ = try await Installations.installations().authTokenForcingRefresh(true)
} catch {
// ...
}
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
_ = try await Installations.installations().authTokenForcingRefresh(true)
} catch {
// ...
}
}
@@ -109,20 +103,18 @@ final class InstallationsAPITests {
}
}
if #available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 7.0, *) {
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
_ = try await Installations.installations().delete()
} catch let error as NSError
where error.domain == InstallationsErrorDomain && error.code == InstallationsErrorCode
.unknown.rawValue {
// Above is the old way to handle errors.
} catch InstallationsErrorCode.unknown {
// Above is the new way to handle errors.
} catch {
// ...
}
// async/await is a Swift Concurrency feature available on iOS 13+ and macOS 10.15+
Task {
do {
_ = try await Installations.installations().delete()
} catch let error as NSError
where error.domain == InstallationsErrorDomain && error.code == InstallationsErrorCode
.unknown.rawValue {
// Above is the old way to handle errors.
} catch InstallationsErrorCode.unknown {
// Above is the new way to handle errors.
} catch {
// ...
}
}
@@ -19,67 +19,15 @@
@implementation FIRKeyedArchivingUtils
+ (nullable NSData *)archivedDataWithRootObject:(id)object error:(NSError **)outError {
NSData *archivedData;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
archivedData = [NSKeyedArchiver archivedDataWithRootObject:object
requiringSecureCoding:YES
error:outError];
} else {
@try {
NSMutableData *data = [NSMutableData data];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
#pragma clang diagnostic pop
archiver.requiresSecureCoding = YES;
[archiver encodeObject:object forKey:NSKeyedArchiveRootObjectKey];
[archiver finishEncoding];
archivedData = [data copy];
} @catch (NSException *exception) {
if (outError) {
NSString *failureReason = [NSString stringWithFormat:@"Exception: %@", exception];
*outError = [NSError errorWithDomain:@"FIRKeyedArchivingUtils"
code:-1
userInfo:@{
NSLocalizedFailureReasonErrorKey : failureReason,
}];
}
}
}
return archivedData;
return [NSKeyedArchiver archivedDataWithRootObject:object
requiringSecureCoding:YES
error:outError];
}
+ (nullable id)unarchivedObjectOfClass:(Class)class
fromData:(NSData *)data
error:(NSError **)outError {
id object;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
object = [NSKeyedUnarchiver unarchivedObjectOfClass:class fromData:data error:outError];
} else {
@try {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
#pragma clang diagnostic pop
unarchiver.requiresSecureCoding = YES;
object = [unarchiver decodeObjectOfClass:class forKey:NSKeyedArchiveRootObjectKey];
} @catch (NSException *exception) {
if (outError) {
NSString *failureReason = [NSString stringWithFormat:@"Exception: %@", exception];
*outError = [NSError errorWithDomain:@"FIRKeyedArchivingUtils"
code:-1
userInfo:@{
NSLocalizedFailureReasonErrorKey : failureReason,
}];
}
}
}
return object;
return [NSKeyedUnarchiver unarchivedObjectOfClass:class fromData:data error:outError];
}
@end
@@ -14,7 +14,6 @@
import Foundation
@available(iOS 13.0.0, macOS 10.15.0, macCatalyst 13.0.0, tvOS 13.0.0, watchOS 7.0.0, *)
public extension RemoteConfig {
/// Returns an `AsyncSequence` that provides real-time updates to the configuration.
///
@@ -144,16 +144,14 @@ final class FirebaseRemoteConfig_APIBuildTests: XCTestCase {
config.activate()
if #available(iOS 13.0, *) {
Task {
let _: Void = try await config.ensureInitialized()
let _: FirebaseRemoteConfig.RemoteConfigFetchStatus = try await config.fetch()
let _: FirebaseRemoteConfig.RemoteConfigFetchStatus = try await config
.fetch(withExpirationDuration: TimeInterval(100))
let _: FirebaseRemoteConfig.RemoteConfigFetchAndActivateStatus = try await config
.fetchAndActivate()
let _: Bool = try await config.activate()
}
Task {
let _: Void = try await config.ensureInitialized()
let _: FirebaseRemoteConfig.RemoteConfigFetchStatus = try await config.fetch()
let _: FirebaseRemoteConfig.RemoteConfigFetchStatus = try await config
.fetch(withExpirationDuration: TimeInterval(100))
let _: FirebaseRemoteConfig.RemoteConfigFetchAndActivateStatus = try await config
.fetchAndActivate()
let _: Bool = try await config.activate()
}
let _: FirebaseRemoteConfig.RemoteConfigValue = config["key"]
@@ -151,12 +151,8 @@ class TestFirebaseDataEncoder: XCTestCase {
}
let model = Model.testValue
if #available(OSX 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
let expected = ["top": ["first": "Johnny Appleseed", "second": "appleseed@apple.com"]]
_testRoundTrip(of: model, expected: expected)
} else {
_testRoundTrip(of: model)
}
let expected = ["top": ["first": "Johnny Appleseed", "second": "appleseed@apple.com"]]
_testRoundTrip(of: model, expected: expected)
}
// NOTE: This test causes a precondition error, so I am uncertain about how it ought to be tested.
@@ -193,11 +189,9 @@ class TestFirebaseDataEncoder: XCTestCase {
//
// let model = Model.testValue
// // This following test would fail as it attempts to re-encode into already encoded container is invalid. This will always fail
// if #available(OSX 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
// _testEncodeFailure(of: model)
// } else {
// _testEncodeFailure(of: model)
// }
// _testEncodeFailure(of: model)
//
// }
// MARK: - Date Strategy Tests