diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a2f1fd77a..0469f15234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ ### Dependencies +- Bump Cocoa SDK from v8.57.2 to v9.0.0-alpha.0 ([#5356](https://github.com/getsentry/sentry-react-native/pull/5356)) + - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#900-alpha0) + - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.57.2...9.0.0-alpha.0) - Bump JavaScript SDK from v10.24.0 to v10.25.0 ([#5362](https://github.com/getsentry/sentry-react-native/pull/5362)) - [changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#10250) - [diff](https://github.com/getsentry/sentry-javascript/compare/10.24.0...10.25.0) diff --git a/packages/core/RNSentry.podspec b/packages/core/RNSentry.podspec index 6ee4619779..e9be2f1cf3 100644 --- a/packages/core/RNSentry.podspec +++ b/packages/core/RNSentry.podspec @@ -46,7 +46,7 @@ Pod::Spec.new do |s| s.compiler_flags = other_cflags - s.dependency 'Sentry/HybridSDK', '8.57.2' + s.dependency 'Sentry/HybridSDK', '9.0.0-alpha.0' if defined? install_modules_dependencies # Default React Native dependencies for 0.71 and above (new and legacy architecture) diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj b/packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj index 7ee546e8af..4b74c4b06a 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj @@ -40,9 +40,7 @@ 338739072A7D7D2800950DDD /* RNSentryReplay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSentryReplay.h; path = ../ios/RNSentryReplay.h; sourceTree = ""; }; 33958C672BFCEF5A00AD1FB6 /* RNSentryOnDrawReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSentryOnDrawReporter.h; path = ../ios/RNSentryOnDrawReporter.h; sourceTree = ""; }; 33AFDFEC2B8D14B300AAB120 /* RNSentryFramesTrackerListenerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNSentryFramesTrackerListenerTests.m; sourceTree = ""; }; - 33AFDFEE2B8D14C200AAB120 /* RNSentryFramesTrackerListenerTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSentryFramesTrackerListenerTests.h; sourceTree = ""; }; 33AFDFF02B8D15E500AAB120 /* RNSentryDependencyContainerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNSentryDependencyContainerTests.m; sourceTree = ""; }; - 33AFDFF22B8D15F600AAB120 /* RNSentryDependencyContainerTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSentryDependencyContainerTests.h; sourceTree = ""; }; 33AFE0132B8F31AF00AAB120 /* RNSentryDependencyContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSentryDependencyContainer.h; path = ../ios/RNSentryDependencyContainer.h; sourceTree = ""; }; 33DEDFE92D8DBE5B006066E4 /* RNSentryOnDrawReporterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNSentryOnDrawReporterTests.swift; sourceTree = ""; }; 33DEDFEB2D8DC800006066E4 /* RNSentryOnDrawReporter+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNSentryOnDrawReporter+Test.h"; sourceTree = ""; }; @@ -52,6 +50,8 @@ 33F58ACF2977037D008F60EA /* RNSentryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSentryTests.m; sourceTree = ""; }; 650CB718ACFBD05609BF2126 /* libPods-RNSentryCocoaTesterTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNSentryCocoaTesterTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E2321E7CFA55AB617247098E /* Pods-RNSentryCocoaTesterTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNSentryCocoaTesterTests.debug.xcconfig"; path = "Target Support Files/Pods-RNSentryCocoaTesterTests/Pods-RNSentryCocoaTesterTests.debug.xcconfig"; sourceTree = ""; }; + F48F26542EA2A481008A185E /* RNSentryEmitNewFrameEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSentryEmitNewFrameEvent.h; path = ../ios/RNSentryEmitNewFrameEvent.h; sourceTree = SOURCE_ROOT; }; + F48F26552EA2A4D4008A185E /* RNSentryFramesTrackerListener.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSentryFramesTrackerListener.h; path = ../ios/RNSentryFramesTrackerListener.h; sourceTree = SOURCE_ROOT; }; FADF868E2EBD053E00D6652D /* SentrySDKWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySDKWrapper.h; path = ../ios/SentrySDKWrapper.h; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -109,9 +109,7 @@ 33F58ACF2977037D008F60EA /* RNSentryTests.m */, 3339C4802D6625570088EB3A /* RNSentryUserTests.m */, 33AFDFEC2B8D14B300AAB120 /* RNSentryFramesTrackerListenerTests.m */, - 33AFDFEE2B8D14C200AAB120 /* RNSentryFramesTrackerListenerTests.h */, 33AFDFF02B8D15E500AAB120 /* RNSentryDependencyContainerTests.m */, - 33AFDFF22B8D15F600AAB120 /* RNSentryDependencyContainerTests.h */, 3360843C2C340C76008CC412 /* RNSentryBreadcrumbTests.swift */, 332D33462CDBDBB600547D76 /* RNSentryReplayOptionsTests.swift */, 3380C6C32CE25ECA0018B9B6 /* RNSentryReplayPostInitTests.swift */, @@ -140,6 +138,8 @@ FADF868E2EBD053E00D6652D /* SentrySDKWrapper.h */, 33AFE0132B8F31AF00AAB120 /* RNSentryDependencyContainer.h */, 338739072A7D7D2800950DDD /* RNSentryReplay.h */, + F48F26542EA2A481008A185E /* RNSentryEmitNewFrameEvent.h */, + F48F26552EA2A4D4008A185E /* RNSentryFramesTrackerListener.h */, ); name = RNSentry; sourceTree = ""; @@ -238,10 +238,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-RNSentryCocoaTesterTests/Pods-RNSentryCocoaTesterTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-RNSentryCocoaTesterTests/Pods-RNSentryCocoaTesterTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNSentryCocoaTesterTests/Pods-RNSentryCocoaTesterTests-resources.sh\"\n"; @@ -436,7 +440,7 @@ "\"$(PODS_TARGET_SRCROOT)/include/\"", "\"${PODS_ROOT}/Sentry/Sources/Sentry/include\"", ); - IPHONEOS_DEPLOYMENT_TARGET = 12.4; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.RNSentryCocoaTesterTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -503,7 +507,7 @@ "\"$(PODS_TARGET_SRCROOT)/include/\"", "\"${PODS_ROOT}/Sentry/Sources/Sentry/include\"", ); - IPHONEOS_DEPLOYMENT_TARGET = 12.4; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.RNSentryCocoaTesterTests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h deleted file mode 100644 index c987776703..0000000000 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h +++ /dev/null @@ -1,8 +0,0 @@ -#import "SentryFramesTracker.h" -#import -#import - -@interface SentryDependencyContainer : NSObject -+ (instancetype)sharedInstance; -@property (nonatomic, strong) SentryFramesTracker *framesTracker; -@end diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.m index 1cef19682c..eb53a6322e 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.m +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.m @@ -1,8 +1,8 @@ -#import "RNSentryDependencyContainerTests.h" #import "RNSentryDependencyContainer.h" #import #import #import +@import Sentry; @interface RNSentryDependencyContainerTests : XCTestCase diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h deleted file mode 100644 index c987776703..0000000000 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h +++ /dev/null @@ -1,8 +0,0 @@ -#import "SentryFramesTracker.h" -#import -#import - -@interface SentryDependencyContainer : NSObject -+ (instancetype)sharedInstance; -@property (nonatomic, strong) SentryFramesTracker *framesTracker; -@end diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m index 7a877795d6..933d913cb5 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m @@ -1,8 +1,9 @@ -#import "RNSentryFramesTrackerListenerTests.h" #import "RNSentryDependencyContainer.h" +#import "RNSentryFramesTrackerListener.h" #import #import #import +@import Sentry; @interface RNSentryFramesTrackerListenerTests : XCTestCase diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporter+Test.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporter+Test.h index 8a9df3a94e..753983baae 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporter+Test.h +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporter+Test.h @@ -1,3 +1,4 @@ +#import "RNSentryEmitNewFrameEvent.h" #import "RNSentryOnDrawReporter.h" #import diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m index d4cd8e957d..e24ba83756 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m @@ -40,7 +40,6 @@ - (void)testCreateOptionsWithDictionaryRemovesPerformanceProperties XCTAssertEqual( actualOptions.tracesSampleRate, nil, @"Traces sample rate should not be passed to native"); XCTAssertEqual(actualOptions.tracesSampler, nil, @"Traces sampler should not be passed to native"); -XCTAssertEqual(actualOptions.enableTracing, false, @"EnableTracing should not be passed to native"); } - (void)testCaptureFailedRequestsIsDisabled @@ -348,10 +347,7 @@ - (void)testCreateOptionsWithDictionaryEnableLogsEnabled XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - id experimentalOptions = [actualOptions valueForKey:@"experimental"]; - XCTAssertNotNil(experimentalOptions, @"Experimental options should not be nil"); - - BOOL enableLogs = [[experimentalOptions valueForKey:@"enableLogs"] boolValue]; + BOOL enableLogs = [[actualOptions valueForKey:@"enableLogs"] boolValue]; XCTAssertTrue(enableLogs, @"enableLogs should be enabled"); } @@ -370,11 +366,7 @@ - (void)testCreateOptionsWithDictionaryEnableLogsDisabled XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - - id experimentalOptions = [actualOptions valueForKey:@"experimental"]; - XCTAssertNotNil(experimentalOptions, @"Experimental options should not be nil"); - - BOOL enableLogs = [[experimentalOptions valueForKey:@"enableLogs"] boolValue]; + BOOL enableLogs = [[actualOptions valueForKey:@"enableLogs"] boolValue]; XCTAssertFalse(enableLogs, @"enableLogs should be disabled"); } diff --git a/packages/core/ios/RNSentry.mm b/packages/core/ios/RNSentry.mm index 10586ab910..033c898e21 100644 --- a/packages/core/ios/RNSentry.mm +++ b/packages/core/ios/RNSentry.mm @@ -26,7 +26,6 @@ #import #import #import -#import #import // This guard prevents importing Hermes in JSC apps @@ -47,13 +46,14 @@ #endif #if SENTRY_HAS_UIKIT -# import "RNSentryFramesTrackerListener.h" +# import "RNSentryEmitNewFrameEvent.h" # import "RNSentryRNSScreen.h" #endif #import "RNSentryExperimentalOptions.h" #import "RNSentryVersion.h" #import "SentrySDKWrapper.h" +#import "SentryScreenFramesWrapper.h" static bool hasFetchedAppStart; @@ -486,21 +486,15 @@ - (void)stopObserving #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST if (PrivateSentrySDKOnly.isFramesTrackingRunning) { - SentryScreenFrames *frames = PrivateSentrySDKOnly.currentScreenFrames; - - if (frames == nil) { + if (![SentryScreenFramesWrapper canTrackFrames]) { resolve(nil); return; } - NSNumber *total = [NSNumber numberWithLong:frames.total]; - NSNumber *frozen = [NSNumber numberWithLong:frames.frozen]; - NSNumber *slow = [NSNumber numberWithLong:frames.slow]; - resolve(@ { - @"totalFrames" : total, - @"frozenFrames" : frozen, - @"slowFrames" : slow, + @"totalFrames" : [SentryScreenFramesWrapper totalFrames], + @"frozenFrames" : [SentryScreenFramesWrapper frozenFrames], + @"slowFrames" : [SentryScreenFramesWrapper slowFrames], }); } else { resolve(nil); diff --git a/packages/core/ios/RNSentryDependencyContainer.h b/packages/core/ios/RNSentryDependencyContainer.h index cd3eca59c7..b3b3ff5233 100644 --- a/packages/core/ios/RNSentryDependencyContainer.h +++ b/packages/core/ios/RNSentryDependencyContainer.h @@ -1,6 +1,7 @@ #import -#import "RNSentryFramesTrackerListener.h" +#import "RNSentryEmitNewFrameEvent.h" +@class RNSentryFramesTrackerListener; @interface RNSentryDependencyContainer : NSObject SENTRY_NO_INIT diff --git a/packages/core/ios/RNSentryDependencyContainer.m b/packages/core/ios/RNSentryDependencyContainer.m index a29b602d52..08c4f6a8bf 100644 --- a/packages/core/ios/RNSentryDependencyContainer.m +++ b/packages/core/ios/RNSentryDependencyContainer.m @@ -1,4 +1,5 @@ #import "RNSentryDependencyContainer.h" +#import "RNSentryFramesTrackerListener.h" @import Sentry; @implementation RNSentryDependencyContainer { diff --git a/packages/core/ios/RNSentryEmitNewFrameEvent.h b/packages/core/ios/RNSentryEmitNewFrameEvent.h new file mode 100644 index 0000000000..473c91cc77 --- /dev/null +++ b/packages/core/ios/RNSentryEmitNewFrameEvent.h @@ -0,0 +1,3 @@ +#import + +typedef void (^RNSentryEmitNewFrameEvent)(NSNumber *newFrameTimestampInSeconds); diff --git a/packages/core/ios/RNSentryExperimentalOptions.m b/packages/core/ios/RNSentryExperimentalOptions.m index 7e0974e527..7bb198ab60 100644 --- a/packages/core/ios/RNSentryExperimentalOptions.m +++ b/packages/core/ios/RNSentryExperimentalOptions.m @@ -24,7 +24,7 @@ + (void)setEnableLogs:(BOOL)enabled sentryOptions:(SentryOptions *)sentryOptions if (sentryOptions == nil) { return; } - sentryOptions.experimental.enableLogs = enabled; + sentryOptions.enableLogs = enabled; } + (void)setEnableSessionReplayInUnreliableEnvironment:(BOOL)enabled diff --git a/packages/core/ios/RNSentryFramesTrackerListener.h b/packages/core/ios/RNSentryFramesTrackerListener.h index 627b3059f4..630f0daeee 100644 --- a/packages/core/ios/RNSentryFramesTrackerListener.h +++ b/packages/core/ios/RNSentryFramesTrackerListener.h @@ -2,11 +2,11 @@ #if SENTRY_HAS_UIKIT +# import "RNSentryEmitNewFrameEvent.h" # import # import -# import -typedef void (^RNSentryEmitNewFrameEvent)(NSNumber *newFrameTimestampInSeconds); +@import Sentry; @protocol RNSentryFramesTrackerListenerProtocol diff --git a/packages/core/ios/RNSentryFramesTrackerListener.m b/packages/core/ios/RNSentryFramesTrackerListener.m index 4a3c7d99cd..2e090bc711 100644 --- a/packages/core/ios/RNSentryFramesTrackerListener.m +++ b/packages/core/ios/RNSentryFramesTrackerListener.m @@ -2,6 +2,8 @@ #if SENTRY_HAS_UIKIT +@import Sentry; + @implementation RNSentryFramesTrackerListener - (instancetype)initWithSentryFramesTracker:(SentryFramesTracker *)framesTracker diff --git a/packages/core/ios/RNSentryOnDrawReporter.h b/packages/core/ios/RNSentryOnDrawReporter.h index 5c4083015d..b462dc4f0b 100644 --- a/packages/core/ios/RNSentryOnDrawReporter.h +++ b/packages/core/ios/RNSentryOnDrawReporter.h @@ -2,10 +2,11 @@ #if SENTRY_HAS_UIKIT -# import "RNSentryFramesTrackerListener.h" # import # import +@protocol RNSentryFramesTrackerListenerProtocol; + @interface RNSentryOnDrawReporter : RCTViewManager @end diff --git a/packages/core/ios/RNSentryOnDrawReporter.m b/packages/core/ios/RNSentryOnDrawReporter.m index b069fcd6f6..6f63ca92d8 100644 --- a/packages/core/ios/RNSentryOnDrawReporter.m +++ b/packages/core/ios/RNSentryOnDrawReporter.m @@ -1,4 +1,6 @@ #import "RNSentryOnDrawReporter.h" +#import "RNSentryEmitNewFrameEvent.h" +#import "RNSentryFramesTrackerListener.h" #import "RNSentryTimeToDisplay.h" @import Sentry; diff --git a/packages/core/ios/RNSentryRNSScreen.m b/packages/core/ios/RNSentryRNSScreen.m index 20c42ab4c4..90b2e733d3 100644 --- a/packages/core/ios/RNSentryRNSScreen.m +++ b/packages/core/ios/RNSentryRNSScreen.m @@ -2,11 +2,10 @@ #if SENTRY_HAS_UIKIT -# import -# import -# import - # import "RNSentryDependencyContainer.h" +# import "RNSentryFramesTrackerListener.h" +# import +@import Sentry; @implementation RNSentryRNSScreen diff --git a/packages/core/ios/SentryScreenFramesWrapper.h b/packages/core/ios/SentryScreenFramesWrapper.h new file mode 100644 index 0000000000..4c664140e0 --- /dev/null +++ b/packages/core/ios/SentryScreenFramesWrapper.h @@ -0,0 +1,14 @@ +#import + +#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST + +@interface SentryScreenFramesWrapper : NSObject + ++ (BOOL)canTrackFrames; ++ (NSNumber *)totalFrames; ++ (NSNumber *)frozenFrames; ++ (NSNumber *)slowFrames; + +@end + +#endif // TARGET_OS_IPHONE || TARGET_OS_MACCATALYST diff --git a/packages/core/ios/SentryScreenFramesWrapper.m b/packages/core/ios/SentryScreenFramesWrapper.m new file mode 100644 index 0000000000..9df4e13070 --- /dev/null +++ b/packages/core/ios/SentryScreenFramesWrapper.m @@ -0,0 +1,39 @@ +#import "SentryScreenFramesWrapper.h" +@import Sentry; + +#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST + +@implementation SentryScreenFramesWrapper + ++ (BOOL)canTrackFrames +{ + return PrivateSentrySDKOnly.currentScreenFrames != nil; +} + ++ (NSNumber *)totalFrames +{ + if (![self canTrackFrames]) { + return nil; + } + return [NSNumber numberWithLong:PrivateSentrySDKOnly.currentScreenFrames.total]; +} + ++ (NSNumber *)frozenFrames +{ + if (![self canTrackFrames]) { + return nil; + } + return [NSNumber numberWithLong:PrivateSentrySDKOnly.currentScreenFrames.frozen]; +} + ++ (NSNumber *)slowFrames +{ + if (![self canTrackFrames]) { + return nil; + } + return [NSNumber numberWithLong:PrivateSentrySDKOnly.currentScreenFrames.slow]; +} + +@end + +#endif // TARGET_OS_IPHONE || TARGET_OS_MACCATALYST