Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
### Internal

- Initialize `RNSentryTimeToDisplay` during native module `init` on iOS ([#4443](https://github.com/getsentry/sentry-react-native/pull/4443))
- Extract iOS native initialization to standalone structures ([#4442](https://github.com/getsentry/sentry-react-native/pull/4442))

### Dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
332D33482CDBDC7300547D76 /* RNSentry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSentry.h; path = ../ios/RNSentry.h; sourceTree = SOURCE_ROOT; };
332D33492CDCC8E100547D76 /* RNSentryTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSentryTests.h; sourceTree = "<group>"; };
332D334A2CDCC8EB00547D76 /* RNSentryCocoaTesterTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNSentryCocoaTesterTests-Bridging-Header.h"; sourceTree = "<group>"; };
333B58A82D35BA93000F8D04 /* RNSentryStart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSentryStart.h; path = ../ios/RNSentryStart.h; sourceTree = SOURCE_ROOT; };
333B58A92D35BB2D000F8D04 /* RNSentryStart+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "RNSentryStart+Test.h"; path = "RNSentryCocoaTesterTests/RNSentryStart+Test.h"; sourceTree = SOURCE_ROOT; };
336084382C32E382008CC412 /* RNSentryReplayBreadcrumbConverterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RNSentryReplayBreadcrumbConverterTests.swift; sourceTree = "<group>"; };
3360843A2C32E3A8008CC412 /* RNSentryReplayBreadcrumbConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSentryReplayBreadcrumbConverter.h; path = ../ios/RNSentryReplayBreadcrumbConverter.h; sourceTree = "<group>"; };
3360843C2C340C76008CC412 /* RNSentryBreadcrumbTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNSentryBreadcrumbTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -116,6 +118,8 @@
33AFE0122B8F319000AAB120 /* RNSentry */ = {
isa = PBXGroup;
children = (
333B58A92D35BB2D000F8D04 /* RNSentryStart+Test.h */,
333B58A82D35BA93000F8D04 /* RNSentryStart.h */,
3380C6C02CDEC56B0018B9B6 /* Replay */,
332D33482CDBDC7300547D76 /* RNSentry.h */,
3360843A2C32E3A8008CC412 /* RNSentryReplayBreadcrumbConverter.h */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import "RNSentryStart.h"

@interface
RNSentryStart (Test)

+ (void)setEventOriginTag:(SentryEvent *)event;

@end

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions packages/core/ios/RNSentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ SentrySDK (Private)

@interface RNSentry : RCTEventEmitter <RCTBridgeModule>

- (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
error:(NSError *_Nullable *_Nonnull)errorPointer;

- (void)setEventOriginTag:(SentryEvent *)event;

- (NSDictionary *_Nonnull)fetchNativeStackFramesBy:(NSArray<NSNumber *> *)instructionsAddr
symbolicate:(SymbolicateCallbackType)symbolicate;

Expand Down
171 changes: 3 additions & 168 deletions packages/core/ios/RNSentry.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
# import "RNSentryRNSScreen.h"
#endif

#import "RNSentryStart.h"
#import "RNSentryVersion.h"

@interface
Expand All @@ -63,7 +64,6 @@ + (void)storeEnvelope:(SentryEnvelope *)envelope;
static bool hasFetchedAppStart;

@implementation RNSentry {
bool sentHybridSdkDidBecomeActive;
bool hasListeners;
RNSentryTimeToDisplay *_timeToDisplay;
}
Expand Down Expand Up @@ -94,181 +94,16 @@ - (instancetype)init
: (RCTPromiseRejectBlock)reject)
{
NSError *error = nil;
SentryOptions *sentryOptions = [self createOptionsWithDictionary:options error:&error];
SentryOptions *sentryOptions = [RNSentryStart createOptionsWithDictionary:options error:&error];
if (error != nil) {
reject(@"SentryReactNative", error.localizedDescription, error);
return;
}

NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString];
[PrivateSentrySDKOnly setSdkName:NATIVE_SDK_NAME andVersionString:sdkVersion];
[PrivateSentrySDKOnly addSdkPackage:REACT_NATIVE_SDK_PACKAGE_NAME
version:REACT_NATIVE_SDK_PACKAGE_VERSION];

[SentrySDK startWithOptions:sentryOptions];

#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
BOOL appIsActive =
[[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
#else
BOOL appIsActive = [[NSApplication sharedApplication] isActive];
#endif

// If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive
// notification, send it.
if (appIsActive && !sentHybridSdkDidBecomeActive
&& (PrivateSentrySDKOnly.options.enableAutoSessionTracking
|| PrivateSentrySDKOnly.options.enableWatchdogTerminationTracking)) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"SentryHybridSdkDidBecomeActive"
object:nil];

sentHybridSdkDidBecomeActive = true;
}

#if SENTRY_TARGET_REPLAY_SUPPORTED
[RNSentryReplay postInit];
#endif

[RNSentryStart startWithOptions:sentryOptions];
resolve(@YES);
}

- (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
error:(NSError *_Nonnull *_Nonnull)errorPointer
{
SentryBeforeSendEventCallback 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) {
return nil;
}

[self setEventOriginTag:event];

return event;
};

NSMutableDictionary *mutableOptions = [options mutableCopy];
[mutableOptions setValue:beforeSend forKey:@"beforeSend"];

// remove performance traces sample rate and traces sampler since we don't want to synchronize
// these configurations to the Native SDKs. The user could tho initialize the SDK manually and
// set themselves.
[mutableOptions removeObjectForKey:@"tracesSampleRate"];
[mutableOptions removeObjectForKey:@"tracesSampler"];
[mutableOptions removeObjectForKey:@"enableTracing"];

#if SENTRY_TARGET_REPLAY_SUPPORTED
[RNSentryReplay updateOptions:mutableOptions];
#endif

SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions
didFailWithError:errorPointer];
if (*errorPointer != nil) {
return nil;
}

// Exclude Dev Server and Sentry Dsn request from Breadcrumbs
NSString *dsn = [self getURLFromDSN:[mutableOptions valueForKey:@"dsn"]];
NSString *devServerUrl = [mutableOptions valueForKey:@"devServerUrl"];
sentryOptions.beforeBreadcrumb
= ^SentryBreadcrumb *_Nullable(SentryBreadcrumb *_Nonnull breadcrumb)
{
NSString *url = breadcrumb.data[@"url"] ?: @"";

if ([@"http" isEqualToString:breadcrumb.type]
&& ((dsn != nil && [url hasPrefix:dsn])
|| (devServerUrl != nil && [url hasPrefix:devServerUrl]))) {
return nil;
}
return breadcrumb;
};

if ([mutableOptions valueForKey:@"enableNativeCrashHandling"] != nil) {
BOOL enableNativeCrashHandling = [mutableOptions[@"enableNativeCrashHandling"] boolValue];

if (!enableNativeCrashHandling) {
NSMutableArray *integrations = sentryOptions.integrations.mutableCopy;
[integrations removeObject:@"SentryCrashIntegration"];
sentryOptions.integrations = integrations;
}
}

// Set spotlight option
if ([mutableOptions valueForKey:@"spotlight"] != nil) {
id spotlightValue = [mutableOptions valueForKey:@"spotlight"];
if ([spotlightValue isKindOfClass:[NSString class]]) {
NSLog(@"Using Spotlight on address: %@", spotlightValue);
sentryOptions.enableSpotlight = true;
sentryOptions.spotlightUrl = spotlightValue;
} else if ([spotlightValue isKindOfClass:[NSNumber class]]) {
sentryOptions.enableSpotlight = [spotlightValue boolValue];
id defaultSpotlightUrl = [mutableOptions valueForKey:@"defaultSidecarUrl"];
if (defaultSpotlightUrl != nil) {
sentryOptions.spotlightUrl = defaultSpotlightUrl;
}
}
}

// Enable the App start and Frames tracking measurements
if ([mutableOptions valueForKey:@"enableAutoPerformanceTracing"] != nil) {
BOOL enableAutoPerformanceTracing =
[mutableOptions[@"enableAutoPerformanceTracing"] boolValue];
PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = enableAutoPerformanceTracing;
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = enableAutoPerformanceTracing;
#endif
}

// Failed requests can only be enabled in one SDK to avoid duplicates
sentryOptions.enableCaptureFailedRequests = NO;

return sentryOptions;
}

- (NSString *_Nullable)getURLFromDSN:(NSString *)dsn
{
NSURL *url = [NSURL URLWithString:dsn];
if (!url) {
return nil;
}
return [NSString stringWithFormat:@"%@://%@", url.scheme, url.host];
}

- (void)setEventOriginTag:(SentryEvent *)event
{
if (event.sdk != nil) {
NSString *sdkName = event.sdk[@"name"];

// If the event is from react native, it gets set
// there and we do not handle it here.
if ([sdkName isEqual:NATIVE_SDK_NAME]) {
[self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
}
}
}

- (void)setEventEnvironmentTag:(SentryEvent *)event
origin:(NSString *)origin
environment:(NSString *)environment
{
NSMutableDictionary *newTags = [NSMutableDictionary new];

if (nil != event.tags && [event.tags count] > 0) {
[newTags addEntriesFromDictionary:event.tags];
}
if (nil != origin) {
[newTags setValue:origin forKey:@"event.origin"];
}
if (nil != environment) {
[newTags setValue:environment forKey:@"event.environment"];
}

event.tags = newTags;
}

RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject)
Expand Down
20 changes: 20 additions & 0 deletions packages/core/ios/RNSentryStart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#import <Sentry/SentryDefines.h>
#import <Sentry/SentryOptions.h>

@interface RNSentryStart : NSObject
SENTRY_NO_INIT

+ (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
error:(NSError *_Nonnull *_Nonnull)errorPointer;

/**
* @experimental
* Inits and configures Sentry for React Native applications. Make sure to
* set a valid DSN.
*
* @discussion Call this method on the main thread. When calling it from a background thread, the
* SDK starts on the main thread async.
*/
+ (void)startWithOptions:(SentryOptions *)options NS_SWIFT_NAME(start(options:));

@end
Loading
Loading