diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bb59bc358..f2ed6b7ccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ > make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first. +## Unreleased + +### Dependencies + +- Bump Cocoa SDK from v8.53.2 to v8.55.0 ([#5036](https://github.com/getsentry/sentry-react-native/pull/5036)) + - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8550) + - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.53.2...8.55.0) + ## 6.20.0 ### Features diff --git a/packages/core/RNSentry.podspec b/packages/core/RNSentry.podspec index b78039a056..0982aa9fa9 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.53.2' + s.dependency 'Sentry/HybridSDK', '8.55.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/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift index 3b8765547f..0d7ef3aa12 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift @@ -67,11 +67,7 @@ final class RNSentryReplayOptions: XCTestCase { ] as NSDictionary).mutableCopy() as! NSMutableDictionary RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.sessionSampleRate, 0.75) } @@ -82,11 +78,7 @@ final class RNSentryReplayOptions: XCTestCase { ] as NSDictionary).mutableCopy() as! NSMutableDictionary RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.onErrorSampleRate, 0.75) } @@ -116,11 +108,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.maskAllImages, true) assertContainsClass(classArray: actualOptions.sessionReplay.maskedViewClasses, stringClass: "RCTImageView") @@ -135,11 +123,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.maskAllImages, false) XCTAssertEqual(actualOptions.sessionReplay.maskedViewClasses.count, 0) @@ -154,11 +138,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.maskAllText, true) assertContainsClass(classArray: actualOptions.sessionReplay.maskedViewClasses, stringClass: "RCTTextView") @@ -182,11 +162,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.maskAllText, false) XCTAssertEqual(actualOptions.sessionReplay.maskedViewClasses.count, 0) @@ -200,11 +176,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertTrue(actualOptions.sessionReplay.enableViewRendererV2) } @@ -218,11 +190,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertTrue(actualOptions.sessionReplay.enableViewRendererV2) } @@ -236,11 +204,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertFalse(actualOptions.sessionReplay.enableViewRendererV2) } @@ -253,11 +217,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertFalse(actualOptions.sessionReplay.enableFastViewRendering) } @@ -271,11 +231,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertTrue(actualOptions.sessionReplay.enableFastViewRendering) } @@ -289,15 +245,11 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertFalse(actualOptions.sessionReplay.enableFastViewRendering) } - + func testReplayQualityDefault() { let optionsDict = ([ "dsn": "https://abc@def.ingest.sentry.io/1234567", @@ -306,11 +258,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.quality, SentryReplayOptions.SentryReplayQuality.medium) } @@ -324,11 +272,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.quality, SentryReplayOptions.SentryReplayQuality.low) } @@ -342,11 +286,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.quality, SentryReplayOptions.SentryReplayQuality.medium) } @@ -360,11 +300,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.quality, SentryReplayOptions.SentryReplayQuality.high) } @@ -378,11 +314,7 @@ final class RNSentryReplayOptions: XCTestCase { RNSentryReplay.updateOptions(optionsDict) - #if CROSS_PLATFORM_TEST let actualOptions = try! SentryOptionsInternal.initWithDict(optionsDict as! [String: Any]) - #else - let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - #endif XCTAssertEqual(actualOptions.sessionReplay.quality, SentryReplayOptions.SentryReplayQuality.medium) } diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h index fa80410d6c..54e8504da0 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h @@ -3,12 +3,8 @@ @class SentryOptions; -#if CROSS_PLATFORM_TEST @interface SentrySDKInternal (PrivateTests) -#else -@interface -SentrySDK (PrivateTests) -#endif + + (nullable SentryOptions *)options; @end diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m index 2020a8e5a3..f6c989a455 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.m @@ -465,13 +465,8 @@ - (void)prepareNativeFrameMocksWithLocalSymbolication:(BOOL)debug SentryOptions *sentryOptions = [[SentryOptions alloc] init]; sentryOptions.debug = debug; // no local symbolication -#if CROSS_PLATFORM_TEST id sentrySDKMock = OCMClassMock([SentrySDKInternal class]); OCMStub([(Class)sentrySDKMock options]).andReturn(sentryOptions); -#else - id sentrySDKMock = OCMClassMock([SentrySDK class]); - OCMStub([(Class)sentrySDKMock options]).andReturn(sentryOptions); -#endif id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])) diff --git a/packages/core/ios/RNSentry.h b/packages/core/ios/RNSentry.h index 9fb651929a..dc037bc86d 100644 --- a/packages/core/ios/RNSentry.h +++ b/packages/core/ios/RNSentry.h @@ -15,12 +15,7 @@ typedef int (*SymbolicateCallbackType)(const void *, Dl_info *); @class SentryOptions; @class SentryEvent; -#if CROSS_PLATFORM_TEST @interface SentrySDKInternal : NSObject -#else -@interface -SentrySDK (Private) -#endif @property (nonatomic, nullable, readonly, class) SentryOptions *options; @end diff --git a/packages/core/ios/RNSentry.mm b/packages/core/ios/RNSentry.mm index a632c83d01..3c4b202cf8 100644 --- a/packages/core/ios/RNSentry.mm +++ b/packages/core/ios/RNSentry.mm @@ -29,15 +29,9 @@ #import #import #import -#import -#if __has_include() -# define USE_SENTRY_OPTIONS 1 -# import -#else -# define USE_SENTRY_OPTIONS 0 -# import -#endif +#import #import +#import // This guard prevents importing Hermes in JSC apps #if SENTRY_PROFILING_ENABLED @@ -169,13 +163,8 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull) [RNSentryReplay updateOptions:mutableOptions]; #endif -#if USE_SENTRY_OPTIONS - SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions - didFailWithError:errorPointer]; -#else SentryOptions *sentryOptions = [SentryOptionsInternal initWithDict:mutableOptions didFailWithError:errorPointer]; -#endif if (*errorPointer != nil) { return nil; } @@ -361,11 +350,7 @@ - (void)stopObserving - (NSDictionary *)fetchNativeStackFramesBy:(NSArray *)instructionsAddr symbolicate:(SymbolicateCallbackType)symbolicate { -#if CROSS_PLATFORM_TEST BOOL shouldSymbolicateLocally = [SentrySDKInternal.options debug]; -#else - BOOL shouldSymbolicateLocally = [SentrySDK.options debug]; -#endif NSString *appPackageName = [[NSBundle mainBundle] executablePath]; NSMutableSet *_Nonnull imagesAddrToRetrieveDebugMetaImages = diff --git a/samples/react-native/ios/SentryNativeInitializer.h b/samples/react-native/ios/SentryNativeInitializer.h new file mode 100644 index 0000000000..9d0c2b1d1a --- /dev/null +++ b/samples/react-native/ios/SentryNativeInitializer.h @@ -0,0 +1,7 @@ +#import + +@interface SentryNativeInitializer : NSObject + ++ (void)initializeSentry; + +@end diff --git a/samples/react-native/ios/SentryNativeInitializer.m b/samples/react-native/ios/SentryNativeInitializer.m new file mode 100644 index 0000000000..20a4bcaa44 --- /dev/null +++ b/samples/react-native/ios/SentryNativeInitializer.m @@ -0,0 +1,38 @@ +#import "SentryNativeInitializer.h" +@import Sentry; + +@implementation SentryNativeInitializer + ++ (void)initializeSentry +{ + [SentrySDK startWithConfigureOptions:^(SentryOptions *options) { + // Only options set here will apply to the iOS SDK + // Options from JS are not passed to the iOS SDK when initialized manually + options.dsn = @"https://1df17bd4e543fdb31351dee1768bb679@o447951.ingest.sentry.io/5428561"; + options.debug = YES; // Enabled debug when first installing is always helpful + + options.beforeSend = ^SentryEvent *(SentryEvent *event) + { + // We don't want to send an event after startup that came from a Unhandled JS Exception + // of react native Because we sent it already before the app crashed. + if (nil != event.exceptions.firstObject.type && + [event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location + != NSNotFound) { + NSLog(@"Unhandled JS Exception"); + return nil; + } + + return event; + }; + + // Enable the App start and Frames tracking measurements + // If this is disabled the app start and frames tracking + // won't be passed from native to JS transactions + PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = true; +#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST + PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = true; +#endif + }]; +} + +@end diff --git a/samples/react-native/ios/sentryreactnativesample.xcodeproj/project.pbxproj b/samples/react-native/ios/sentryreactnativesample.xcodeproj/project.pbxproj index 0d2f979cb0..1350418ccb 100644 --- a/samples/react-native/ios/sentryreactnativesample.xcodeproj/project.pbxproj +++ b/samples/react-native/ios/sentryreactnativesample.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 5ACADB1A9924EDD0850FACBA /* libPods-sentryreactnativesample-sentryreactnativesampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AFC2BCCFBDE2DC231B5C04E5 /* libPods-sentryreactnativesample-sentryreactnativesampleTests.a */; }; 723FB93385E08A7032AE82F4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 916F55A329D66130A4DFF319 /* PrivacyInfo.xcprivacy */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + AE3C91AE2E3BB9B400DC7C20 /* SentryNativeInitializer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3C91AD2E3BB9B000DC7C20 /* SentryNativeInitializer.m */; }; F998F5A3F1731876C4EDA235 /* libPods-sentryreactnativesample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CA08EE94AE203638B8C8B74B /* libPods-sentryreactnativesample.a */; }; /* End PBXBuildFile section */ @@ -49,6 +50,8 @@ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = sentryreactnativesample/LaunchScreen.storyboard; sourceTree = ""; }; 89C6BE57DB24E9ADA2F236DE /* Pods-sentryreactnativesample-sentryreactnativesampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-sentryreactnativesample-sentryreactnativesampleTests.release.xcconfig"; path = "Target Support Files/Pods-sentryreactnativesample-sentryreactnativesampleTests/Pods-sentryreactnativesample-sentryreactnativesampleTests.release.xcconfig"; sourceTree = ""; }; 916F55A329D66130A4DFF319 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = sentryreactnativesample/PrivacyInfo.xcprivacy; sourceTree = ""; }; + AE3C91AC2E3BB98B00DC7C20 /* SentryNativeInitializer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryNativeInitializer.h; sourceTree = ""; }; + AE3C91AD2E3BB9B000DC7C20 /* SentryNativeInitializer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNativeInitializer.m; sourceTree = ""; }; AFC2BCCFBDE2DC231B5C04E5 /* libPods-sentryreactnativesample-sentryreactnativesampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-sentryreactnativesample-sentryreactnativesampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; CA08EE94AE203638B8C8B74B /* libPods-sentryreactnativesample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-sentryreactnativesample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; @@ -94,6 +97,8 @@ 13B07FAE1A68108700A75B9A /* sentryreactnativesample */ = { isa = PBXGroup; children = ( + AE3C91AD2E3BB9B000DC7C20 /* SentryNativeInitializer.m */, + AE3C91AC2E3BB98B00DC7C20 /* SentryNativeInitializer.h */, 338BBBC72B614FA10035844C /* NativePlatformSampleModule.h */, 338BBBC62B614FA10035844C /* NativePlatformSampleModule.mm */, 33E2D62929A7719600B5042B /* RCTAssetsModule.h */, @@ -427,6 +432,7 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */, 338BBBC82B614FA10035844C /* NativePlatformSampleModule.mm in Sources */, 33E2D62A29A7719600B5042B /* RCTAssetsModule.m in Sources */, + AE3C91AE2E3BB9B400DC7C20 /* SentryNativeInitializer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm b/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm index aedb222cbc..0df8934ff1 100644 --- a/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm +++ b/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm @@ -13,8 +13,7 @@ # import #endif -#import -#import +#import "SentryNativeInitializer.h" @interface AppDelegate () { @@ -23,44 +22,12 @@ @implementation AppDelegate -- (void)initializeSentry -{ - [SentrySDK startWithConfigureOptions:^(SentryOptions *options) { - // Only options set here will apply to the iOS SDK - // Options from JS are not passed to the iOS SDK when initialized manually - options.dsn = @"https://1df17bd4e543fdb31351dee1768bb679@o447951.ingest.sentry.io/5428561"; - options.debug = YES; // Enabled debug when first installing is always helpful - - options.beforeSend = ^SentryEvent *(SentryEvent *event) - { - // We don't want to send an event after startup that came from a Unhandled JS Exception - // of react native Because we sent it already before the app crashed. - if (nil != event.exceptions.firstObject.type && - [event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location - != NSNotFound) { - NSLog(@"Unhandled JS Exception"); - return nil; - } - - return event; - }; - - // Enable the App start and Frames tracking measurements - // If this is disabled the app start and frames tracking - // won't be passed from native to JS transactions - PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = true; -#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST - PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = true; -#endif - }]; -} - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // When the native init is enabled the `autoInitializeNativeSdk` // in JS has to be set to `false` - // [self initializeSentry]; + // [SentryNativeInitializer initializeSentry]; self.reactNativeFactory = [[RCTReactNativeFactory alloc] initWithDelegate:self]; self.dependencyProvider = [RCTAppDependencyProvider new];