@sentry/react-native 6.1.0 → 6.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +5 -9
  2. package/RNSentry.podspec +1 -1
  3. package/android/build.gradle +1 -1
  4. package/android/src/main/java/io/sentry/react/RNSentryBreadcrumb.java +6 -0
  5. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +183 -127
  6. package/android/src/main/java/io/sentry/react/RNSentryTimeToDisplay.java +42 -0
  7. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +5 -0
  8. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +5 -0
  9. package/dist/js/NativeRNSentry.d.ts +1 -0
  10. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  11. package/dist/js/NativeRNSentry.js.map +1 -1
  12. package/dist/js/client.d.ts.map +1 -1
  13. package/dist/js/client.js +7 -2
  14. package/dist/js/client.js.map +1 -1
  15. package/dist/js/index.d.ts +2 -2
  16. package/dist/js/index.d.ts.map +1 -1
  17. package/dist/js/index.js +1 -1
  18. package/dist/js/index.js.map +1 -1
  19. package/dist/js/integrations/debugsymbolicator.js +4 -37
  20. package/dist/js/integrations/debugsymbolicator.js.map +1 -1
  21. package/dist/js/integrations/debugsymbolicatorutils.d.ts +6 -2
  22. package/dist/js/integrations/debugsymbolicatorutils.d.ts.map +1 -1
  23. package/dist/js/integrations/debugsymbolicatorutils.js +44 -27
  24. package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -1
  25. package/dist/js/integrations/default.d.ts.map +1 -1
  26. package/dist/js/integrations/default.js +11 -7
  27. package/dist/js/integrations/default.js.map +1 -1
  28. package/dist/js/integrations/devicecontext.d.ts.map +1 -1
  29. package/dist/js/integrations/devicecontext.js +7 -3
  30. package/dist/js/integrations/devicecontext.js.map +1 -1
  31. package/dist/js/integrations/spotlight.d.ts +4 -0
  32. package/dist/js/integrations/spotlight.d.ts.map +1 -1
  33. package/dist/js/integrations/spotlight.js +4 -1
  34. package/dist/js/integrations/spotlight.js.map +1 -1
  35. package/dist/js/sdk.d.ts.map +1 -1
  36. package/dist/js/sdk.js +40 -2
  37. package/dist/js/sdk.js.map +1 -1
  38. package/dist/js/tools/metroMiddleware.d.ts +15 -0
  39. package/dist/js/tools/metroMiddleware.d.ts.map +1 -0
  40. package/dist/js/tools/metroMiddleware.js +105 -0
  41. package/dist/js/tools/metroMiddleware.js.map +1 -0
  42. package/dist/js/tools/metroconfig.d.ts +7 -1
  43. package/dist/js/tools/metroconfig.d.ts.map +1 -1
  44. package/dist/js/tools/metroconfig.js +9 -1
  45. package/dist/js/tools/metroconfig.js.map +1 -1
  46. package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
  47. package/dist/js/tracing/reactnativetracing.js +17 -1
  48. package/dist/js/tracing/reactnativetracing.js.map +1 -1
  49. package/dist/js/tracing/reactnavigation.js +7 -7
  50. package/dist/js/tracing/reactnavigation.js.map +1 -1
  51. package/dist/js/utils/ignorerequirecyclelogs.d.ts +6 -1
  52. package/dist/js/utils/ignorerequirecyclelogs.d.ts.map +1 -1
  53. package/dist/js/utils/ignorerequirecyclelogs.js +6 -2
  54. package/dist/js/utils/ignorerequirecyclelogs.js.map +1 -1
  55. package/dist/js/utils/sentryeventemitterfallback.d.ts +19 -0
  56. package/dist/js/utils/sentryeventemitterfallback.d.ts.map +1 -0
  57. package/dist/js/utils/sentryeventemitterfallback.js +78 -0
  58. package/dist/js/utils/sentryeventemitterfallback.js.map +1 -0
  59. package/dist/js/vendor/react-native/index.d.ts +1 -1
  60. package/dist/js/vendor/react-native/index.js.map +1 -1
  61. package/dist/js/version.d.ts +1 -1
  62. package/dist/js/version.d.ts.map +1 -1
  63. package/dist/js/version.js +1 -1
  64. package/dist/js/version.js.map +1 -1
  65. package/dist/js/wrapper.d.ts +4 -0
  66. package/dist/js/wrapper.d.ts.map +1 -1
  67. package/dist/js/wrapper.js +6 -0
  68. package/dist/js/wrapper.js.map +1 -1
  69. package/ios/RNSentry.h +8 -12
  70. package/ios/RNSentry.mm +417 -303
  71. package/ios/RNSentryBreadcrumb.h +2 -2
  72. package/ios/RNSentryBreadcrumb.m +13 -6
  73. package/ios/RNSentryDependencyContainer.h +2 -2
  74. package/ios/RNSentryDependencyContainer.m +7 -6
  75. package/ios/RNSentryFramesTrackerListener.h +6 -6
  76. package/ios/RNSentryFramesTrackerListener.m +10 -8
  77. package/ios/RNSentryId.m +2 -1
  78. package/ios/RNSentryOnDrawReporter.h +5 -5
  79. package/ios/RNSentryOnDrawReporter.m +26 -24
  80. package/ios/RNSentryRNSScreen.h +1 -1
  81. package/ios/RNSentryRNSScreen.m +18 -18
  82. package/ios/RNSentryReplay.m +42 -53
  83. package/ios/RNSentryReplayBreadcrumbConverter.h +3 -4
  84. package/ios/RNSentryReplayBreadcrumbConverter.m +139 -132
  85. package/ios/RNSentryTimeToDisplay.h +7 -0
  86. package/ios/RNSentryTimeToDisplay.m +44 -0
  87. package/package.json +17 -16
  88. package/scripts/expo-upload-sourcemaps.js +16 -0
  89. package/scripts/sentry-xcode-debug-files.sh +6 -0
  90. package/scripts/sentry-xcode.sh +4 -0
  91. package/sentry.gradle +13 -2
  92. package/src/js/NativeRNSentry.ts +1 -0
  93. package/ts3.8/dist/js/NativeRNSentry.d.ts +1 -0
  94. package/ts3.8/dist/js/index.d.ts +2 -2
  95. package/ts3.8/dist/js/integrations/debugsymbolicatorutils.d.ts +6 -2
  96. package/ts3.8/dist/js/integrations/spotlight.d.ts +4 -0
  97. package/ts3.8/dist/js/utils/ignorerequirecyclelogs.d.ts +6 -1
  98. package/ts3.8/dist/js/utils/sentryeventemitterfallback.d.ts +19 -0
  99. package/ts3.8/dist/js/vendor/react-native/index.d.ts +1 -1
  100. package/ts3.8/dist/js/version.d.ts +1 -1
  101. package/ts3.8/dist/js/wrapper.d.ts +4 -0
package/ios/RNSentry.mm CHANGED
@@ -1,53 +1,56 @@
1
- #import <dlfcn.h>
2
1
  #import "RNSentry.h"
2
+ #import "RNSentryTimeToDisplay.h"
3
+ #import <dlfcn.h>
3
4
 
4
5
  #if __has_include(<React/RCTConvert.h>)
5
- #import <React/RCTConvert.h>
6
+ # import <React/RCTConvert.h>
6
7
  #else
7
- #import "RCTConvert.h"
8
+ # import "RCTConvert.h"
8
9
  #endif
9
10
 
10
11
  #if __has_include(<hermes/hermes.h>) && SENTRY_PROFILING_SUPPORTED
11
- #define SENTRY_PROFILING_ENABLED 1
12
- #import <Sentry/SentryProfilingConditionals.h>
12
+ # define SENTRY_PROFILING_ENABLED 1
13
+ # import <Sentry/SentryProfilingConditionals.h>
13
14
  #else
14
- #define SENTRY_PROFILING_ENABLED 0
15
- #define SENTRY_TARGET_PROFILING_SUPPORTED 0
15
+ # define SENTRY_PROFILING_ENABLED 0
16
+ # define SENTRY_TARGET_PROFILING_SUPPORTED 0
16
17
  #endif
17
18
 
19
+ #import "RNSentryBreadcrumb.h"
20
+ #import "RNSentryId.h"
18
21
  #import <Sentry/PrivateSentrySDKOnly.h>
19
- #import <Sentry/SentryScreenFrames.h>
20
- #import <Sentry/SentryOptions+HybridSDKs.h>
22
+ #import <Sentry/SentryAppStartMeasurement.h>
21
23
  #import <Sentry/SentryBinaryImageCache.h>
24
+ #import <Sentry/SentryDebugImageProvider+HybridSDKs.h>
22
25
  #import <Sentry/SentryDependencyContainer.h>
23
26
  #import <Sentry/SentryFormatter.h>
24
- #import <Sentry/SentryAppStartMeasurement.h>
25
- #import "RNSentryId.h"
26
- #import "RNSentryBreadcrumb.h"
27
+ #import <Sentry/SentryOptions+HybridSDKs.h>
28
+ #import <Sentry/SentryScreenFrames.h>
27
29
 
28
30
  // This guard prevents importing Hermes in JSC apps
29
31
  #if SENTRY_PROFILING_ENABLED
30
- #import <hermes/hermes.h>
32
+ # import <hermes/hermes.h>
31
33
  #endif
32
34
 
33
35
  // Thanks to this guard, we won't import this header when we build for the old architecture.
34
36
  #ifdef RCT_NEW_ARCH_ENABLED
35
- #import "RNSentrySpec.h"
37
+ # import "RNSentrySpec.h"
36
38
  #endif
37
39
 
38
- #import "RNSentryEvents.h"
39
40
  #import "RNSentryDependencyContainer.h"
41
+ #import "RNSentryEvents.h"
40
42
 
41
43
  #if SENTRY_TARGET_REPLAY_SUPPORTED
42
- #import "RNSentryReplay.h"
44
+ # import "RNSentryReplay.h"
43
45
  #endif
44
46
 
45
47
  #if SENTRY_HAS_UIKIT
46
- #import "RNSentryRNSScreen.h"
47
- #import "RNSentryFramesTrackerListener.h"
48
+ # import "RNSentryFramesTrackerListener.h"
49
+ # import "RNSentryRNSScreen.h"
48
50
  #endif
49
51
 
50
- @interface SentrySDK (RNSentry)
52
+ @interface
53
+ SentrySDK (RNSentry)
51
54
 
52
55
  + (void)captureEnvelope:(SentryEnvelope *)envelope;
53
56
 
@@ -57,11 +60,12 @@
57
60
 
58
61
  static bool hasFetchedAppStart;
59
62
 
60
- static NSString* const nativeSdkName = @"sentry.cocoa.react-native";
63
+ static NSString *const nativeSdkName = @"sentry.cocoa.react-native";
61
64
 
62
65
  @implementation RNSentry {
63
66
  bool sentHybridSdkDidBecomeActive;
64
67
  bool hasListeners;
68
+ RNSentryTimeToDisplay *_timeToDisplay;
65
69
  }
66
70
 
67
71
  - (dispatch_queue_t)methodQueue
@@ -69,39 +73,44 @@ static NSString* const nativeSdkName = @"sentry.cocoa.react-native";
69
73
  return dispatch_get_main_queue();
70
74
  }
71
75
 
72
- + (BOOL)requiresMainQueueSetup {
76
+ + (BOOL)requiresMainQueueSetup
77
+ {
73
78
  return YES;
74
79
  }
75
80
 
76
81
  RCT_EXPORT_MODULE()
77
82
 
78
- RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
79
- resolve:(RCTPromiseResolveBlock)resolve
80
- rejecter:(RCTPromiseRejectBlock)reject)
83
+ RCT_EXPORT_METHOD(initNativeSdk
84
+ : (NSDictionary *_Nonnull)options resolve
85
+ : (RCTPromiseResolveBlock)resolve rejecter
86
+ : (RCTPromiseRejectBlock)reject)
81
87
  {
82
88
  NSError *error = nil;
83
- SentryOptions* sentryOptions = [self createOptionsWithDictionary:options error:&error];
89
+ SentryOptions *sentryOptions = [self createOptionsWithDictionary:options error:&error];
84
90
  if (error != nil) {
85
91
  reject(@"SentryReactNative", error.localizedDescription, error);
86
92
  return;
87
93
  }
88
94
 
89
95
  NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString];
90
- [PrivateSentrySDKOnly setSdkName: nativeSdkName andVersionString: sdkVersion];
96
+ [PrivateSentrySDKOnly setSdkName:nativeSdkName andVersionString:sdkVersion];
91
97
 
92
98
  [SentrySDK startWithOptions:sentryOptions];
93
99
 
94
100
  #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
95
- BOOL appIsActive = [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
101
+ BOOL appIsActive =
102
+ [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
96
103
  #else
97
104
  BOOL appIsActive = [[NSApplication sharedApplication] isActive];
98
105
  #endif
99
106
 
100
- // If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive notification, send it.
101
- if (appIsActive && !sentHybridSdkDidBecomeActive && (PrivateSentrySDKOnly.options.enableAutoSessionTracking || PrivateSentrySDKOnly.options.enableWatchdogTerminationTracking)) {
102
- [[NSNotificationCenter defaultCenter]
103
- postNotificationName:@"SentryHybridSdkDidBecomeActive"
104
- object:nil];
107
+ // If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive
108
+ // notification, send it.
109
+ if (appIsActive && !sentHybridSdkDidBecomeActive
110
+ && (PrivateSentrySDKOnly.options.enableAutoSessionTracking
111
+ || PrivateSentrySDKOnly.options.enableWatchdogTerminationTracking)) {
112
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"SentryHybridSdkDidBecomeActive"
113
+ object:nil];
105
114
 
106
115
  sentHybridSdkDidBecomeActive = true;
107
116
  }
@@ -114,13 +123,15 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
114
123
  }
115
124
 
116
125
  - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
117
- error: (NSError *_Nonnull *_Nonnull) errorPointer
126
+ error:(NSError *_Nonnull *_Nonnull)errorPointer
118
127
  {
119
- SentryBeforeSendEventCallback beforeSend = ^SentryEvent*(SentryEvent *event) {
120
- // We don't want to send an event after startup that came from a Unhandled JS Exception of react native
121
- // Because we sent it already before the app crashed.
128
+ SentryBeforeSendEventCallback beforeSend = ^SentryEvent *(SentryEvent *event)
129
+ {
130
+ // We don't want to send an event after startup that came from a Unhandled JS Exception of
131
+ // react native Because we sent it already before the app crashed.
122
132
  if (nil != event.exceptions.firstObject.type &&
123
- [event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location != NSNotFound) {
133
+ [event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location
134
+ != NSNotFound) {
124
135
  return nil;
125
136
  }
126
137
 
@@ -129,25 +140,44 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
129
140
  return event;
130
141
  };
131
142
 
132
- NSMutableDictionary * mutableOptions =[options mutableCopy];
143
+ NSMutableDictionary *mutableOptions = [options mutableCopy];
133
144
  [mutableOptions setValue:beforeSend forKey:@"beforeSend"];
134
145
 
135
- // remove performance traces sample rate and traces sampler since we don't want to synchronize these configurations
136
- // to the Native SDKs.
137
- // The user could tho initialize the SDK manually and set themselves.
146
+ // remove performance traces sample rate and traces sampler since we don't want to synchronize
147
+ // these configurations to the Native SDKs. The user could tho initialize the SDK manually and
148
+ // set themselves.
138
149
  [mutableOptions removeObjectForKey:@"tracesSampleRate"];
139
150
  [mutableOptions removeObjectForKey:@"tracesSampler"];
140
151
  [mutableOptions removeObjectForKey:@"enableTracing"];
141
152
 
153
+ _timeToDisplay = [[RNSentryTimeToDisplay alloc] init];
154
+
142
155
  #if SENTRY_TARGET_REPLAY_SUPPORTED
143
156
  [RNSentryReplay updateOptions:mutableOptions];
144
157
  #endif
145
158
 
146
- SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions didFailWithError:errorPointer];
159
+ SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions
160
+ didFailWithError:errorPointer];
147
161
  if (*errorPointer != nil) {
148
162
  return nil;
149
163
  }
150
164
 
165
+ // Exclude Dev Server and Sentry Dsn request from Breadcrumbs
166
+ NSString *dsn = [self getURLFromDSN:[mutableOptions valueForKey:@"dsn"]];
167
+ NSString *devServerUrl = [mutableOptions valueForKey:@"devServerUrl"];
168
+ sentryOptions.beforeBreadcrumb
169
+ = ^SentryBreadcrumb *_Nullable(SentryBreadcrumb *_Nonnull breadcrumb)
170
+ {
171
+ NSString *url = breadcrumb.data[@"url"] ?: @"";
172
+
173
+ if ([@"http" isEqualToString:breadcrumb.type]
174
+ && ((dsn != nil && [url hasPrefix:dsn])
175
+ || (devServerUrl != nil && [url hasPrefix:devServerUrl]))) {
176
+ return nil;
177
+ }
178
+ return breadcrumb;
179
+ };
180
+
151
181
  if ([mutableOptions valueForKey:@"enableNativeCrashHandling"] != nil) {
152
182
  BOOL enableNativeCrashHandling = [mutableOptions[@"enableNativeCrashHandling"] boolValue];
153
183
 
@@ -158,58 +188,88 @@ RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options
158
188
  }
159
189
  }
160
190
 
191
+ // Set spotlight option
192
+ if ([mutableOptions valueForKey:@"spotlight"] != nil) {
193
+ id spotlightValue = [mutableOptions valueForKey:@"spotlight"];
194
+ if ([spotlightValue isKindOfClass:[NSString class]]) {
195
+ NSLog(@"Using Spotlight on address: %@", spotlightValue);
196
+ sentryOptions.enableSpotlight = true;
197
+ sentryOptions.spotlightUrl = spotlightValue;
198
+ } else if ([spotlightValue isKindOfClass:[NSNumber class]]) {
199
+ sentryOptions.enableSpotlight = [spotlightValue boolValue];
200
+ id defaultSpotlightUrl = [mutableOptions valueForKey:@"defaultSidecarUrl"];
201
+ if (defaultSpotlightUrl != nil) {
202
+ sentryOptions.spotlightUrl = defaultSpotlightUrl;
203
+ }
204
+ }
205
+ }
206
+
161
207
  // Enable the App start and Frames tracking measurements
162
208
  if ([mutableOptions valueForKey:@"enableAutoPerformanceTracing"] != nil) {
163
- BOOL enableAutoPerformanceTracing = [mutableOptions[@"enableAutoPerformanceTracing"] boolValue];
209
+ BOOL enableAutoPerformanceTracing =
210
+ [mutableOptions[@"enableAutoPerformanceTracing"] boolValue];
164
211
  PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = enableAutoPerformanceTracing;
165
212
  #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
166
213
  PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = enableAutoPerformanceTracing;
167
214
  #endif
168
215
  }
169
216
 
217
+ // Failed requests can only be enabled in one SDK to avoid duplicates
218
+ sentryOptions.enableCaptureFailedRequests = @NO;
219
+
170
220
  return sentryOptions;
171
221
  }
172
222
 
173
- - (void)setEventOriginTag:(SentryEvent *)event {
174
- if (event.sdk != nil) {
175
- NSString *sdkName = event.sdk[@"name"];
223
+ - (NSString *_Nullable)getURLFromDSN:(NSString *)dsn
224
+ {
225
+ NSURL *url = [NSURL URLWithString:dsn];
226
+ if (!url) {
227
+ return nil;
228
+ }
229
+ return [NSString stringWithFormat:@"%@://%@", url.scheme, url.host];
230
+ }
231
+
232
+ - (void)setEventOriginTag:(SentryEvent *)event
233
+ {
234
+ if (event.sdk != nil) {
235
+ NSString *sdkName = event.sdk[@"name"];
176
236
 
177
- // If the event is from react native, it gets set
178
- // there and we do not handle it here.
179
- if ([sdkName isEqual:nativeSdkName]) {
180
- [self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
237
+ // If the event is from react native, it gets set
238
+ // there and we do not handle it here.
239
+ if ([sdkName isEqual:nativeSdkName]) {
240
+ [self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
241
+ }
181
242
  }
182
- }
183
243
  }
184
244
 
185
245
  - (void)setEventEnvironmentTag:(SentryEvent *)event
186
246
  origin:(NSString *)origin
187
- environment:(NSString *)environment {
188
- NSMutableDictionary *newTags = [NSMutableDictionary new];
247
+ environment:(NSString *)environment
248
+ {
249
+ NSMutableDictionary *newTags = [NSMutableDictionary new];
189
250
 
190
- if (nil != event.tags && [event.tags count] > 0) {
191
- [newTags addEntriesFromDictionary:event.tags];
192
- }
193
- if (nil != origin) {
194
- [newTags setValue:origin forKey:@"event.origin"];
195
- }
196
- if (nil != environment) {
197
- [newTags setValue:environment forKey:@"event.environment"];
198
- }
251
+ if (nil != event.tags && [event.tags count] > 0) {
252
+ [newTags addEntriesFromDictionary:event.tags];
253
+ }
254
+ if (nil != origin) {
255
+ [newTags setValue:origin forKey:@"event.origin"];
256
+ }
257
+ if (nil != environment) {
258
+ [newTags setValue:environment forKey:@"event.environment"];
259
+ }
199
260
 
200
- event.tags = newTags;
261
+ event.tags = newTags;
201
262
  }
202
263
 
203
- RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking:(RCTPromiseResolveBlock)resolve
204
- rejecter:(RCTPromiseRejectBlock)reject)
264
+ RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking
265
+ : (RCTPromiseResolveBlock)resolve rejecter
266
+ : (RCTPromiseRejectBlock)reject)
205
267
  {
206
268
  #if SENTRY_HAS_UIKIT
207
269
  if ([[NSThread currentThread] isMainThread]) {
208
270
  [RNSentryRNSScreen swizzleViewDidAppear];
209
271
  } else {
210
- dispatch_async(dispatch_get_main_queue(), ^{
211
- [RNSentryRNSScreen swizzleViewDidAppear];
212
- });
272
+ dispatch_async(dispatch_get_main_queue(), ^{ [RNSentryRNSScreen swizzleViewDidAppear]; });
213
273
  }
214
274
 
215
275
  [self initFramesTracking];
@@ -217,48 +277,57 @@ RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking:(RCTPromiseResolveBl
217
277
  resolve(nil);
218
278
  }
219
279
 
220
- - (void)initFramesTracking {
280
+ - (void)initFramesTracking
281
+ {
221
282
  #if SENTRY_HAS_UIKIT
222
283
 
223
- RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) {
224
- if (self->hasListeners) {
225
- [self sendEventWithName:RNSentryNewFrameEvent body:@{ @"newFrameTimestampInSeconds": newFrameTimestampInSeconds }];
226
- }
227
- };
228
- [[RNSentryDependencyContainer sharedInstance] initializeFramesTrackerListenerWith: emitNewFrameEvent];
284
+ RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) {
285
+ if (self->hasListeners) {
286
+ [self
287
+ sendEventWithName:RNSentryNewFrameEvent
288
+ body:@{ @"newFrameTimestampInSeconds" : newFrameTimestampInSeconds }];
289
+ }
290
+ };
291
+ [[RNSentryDependencyContainer sharedInstance]
292
+ initializeFramesTrackerListenerWith:emitNewFrameEvent];
229
293
  #endif
230
294
  }
231
295
 
232
296
  // Will be called when this module's first listener is added.
233
- -(void)startObserving {
297
+ - (void)startObserving
298
+ {
234
299
  hasListeners = YES;
235
300
  }
236
301
 
237
302
  // Will be called when this module's last listener is removed, or on dealloc.
238
- -(void)stopObserving {
303
+ - (void)stopObserving
304
+ {
239
305
  hasListeners = NO;
240
306
  }
241
307
 
242
- - (NSArray<NSString *> *)supportedEvents {
243
- return @[RNSentryNewFrameEvent];
308
+ - (NSArray<NSString *> *)supportedEvents
309
+ {
310
+ return @[ RNSentryNewFrameEvent ];
244
311
  }
245
312
 
246
- RCT_EXPORT_METHOD(fetchNativeSdkInfo:(RCTPromiseResolveBlock)resolve
247
- rejecter:(RCTPromiseRejectBlock)reject)
313
+ RCT_EXPORT_METHOD(fetchNativeSdkInfo
314
+ : (RCTPromiseResolveBlock)resolve rejecter
315
+ : (RCTPromiseRejectBlock)reject)
248
316
  {
249
- resolve(@{
250
- @"name": PrivateSentrySDKOnly.getSdkName,
251
- @"version": PrivateSentrySDKOnly.getSdkVersionString
252
- });
317
+ resolve(@ {
318
+ @"name" : PrivateSentrySDKOnly.getSdkName,
319
+ @"version" : PrivateSentrySDKOnly.getSdkVersionString
320
+ });
253
321
  }
254
322
 
255
- RCT_EXPORT_METHOD(fetchModules:(RCTPromiseResolveBlock)resolve
256
- rejecter:(RCTPromiseRejectBlock)reject)
323
+ RCT_EXPORT_METHOD(fetchModules
324
+ : (RCTPromiseResolveBlock)resolve rejecter
325
+ : (RCTPromiseRejectBlock)reject)
257
326
  {
258
327
  NSString *filePath = [[NSBundle mainBundle] pathForResource:@"modules" ofType:@"json"];
259
- NSString* modulesString = [NSString stringWithContentsOfFile:filePath
260
- encoding:NSUTF8StringEncoding
261
- error:nil];
328
+ NSString *modulesString = [NSString stringWithContentsOfFile:filePath
329
+ encoding:NSUTF8StringEncoding
330
+ error:nil];
262
331
  resolve(modulesString);
263
332
  }
264
333
 
@@ -268,79 +337,90 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, fetchNativePackageName)
268
337
  return packageName;
269
338
  }
270
339
 
271
- - (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAddr
272
- symbolicate: (SymbolicateCallbackType) symbolicate
340
+ - (NSDictionary *)fetchNativeStackFramesBy:(NSArray<NSNumber *> *)instructionsAddr
341
+ symbolicate:(SymbolicateCallbackType)symbolicate
273
342
  {
274
- BOOL shouldSymbolicateLocally = [SentrySDK.options debug];
275
- NSString *appPackageName = [[NSBundle mainBundle] executablePath];
276
-
277
- NSMutableSet<NSString *> * _Nonnull imagesAddrToRetrieveDebugMetaImages = [[NSMutableSet alloc] init];
278
- NSMutableArray<NSDictionary<NSString *, id> *> * _Nonnull serializedFrames = [[NSMutableArray alloc] init];
279
-
280
- for (NSNumber *addr in instructionsAddr) {
281
- SentryBinaryImageInfo * _Nullable image = [[[SentryDependencyContainer sharedInstance] binaryImageCache] imageByAddress:[addr unsignedLongLongValue]];
282
- if (image != nil) {
283
- NSString * imageAddr = sentry_formatHexAddressUInt64([image address]);
284
- [imagesAddrToRetrieveDebugMetaImages addObject: imageAddr];
285
-
286
- NSDictionary<NSString *, id> * _Nonnull nativeFrame = @{
287
- @"platform": @"cocoa",
288
- @"instruction_addr": sentry_formatHexAddress(addr),
289
- @"package": [image name],
290
- @"image_addr": imageAddr,
291
- @"in_app": [NSNumber numberWithBool:[appPackageName isEqualToString:[image name]]],
292
- };
293
-
294
- if (shouldSymbolicateLocally) {
295
- Dl_info symbolsBuffer;
296
- bool symbols_succeed = false;
297
- symbols_succeed = symbolicate((void *) [addr unsignedLongLongValue], &symbolsBuffer) != 0;
298
- if (symbols_succeed) {
299
- NSMutableDictionary<NSString *, id> * _Nonnull symbolicated = nativeFrame.mutableCopy;
300
- symbolicated[@"symbol_addr"] = sentry_formatHexAddressUInt64((uintptr_t)symbolsBuffer.dli_saddr);
301
- symbolicated[@"function"] = [NSString stringWithCString:symbolsBuffer.dli_sname encoding:NSUTF8StringEncoding];
343
+ BOOL shouldSymbolicateLocally = [SentrySDK.options debug];
344
+ NSString *appPackageName = [[NSBundle mainBundle] executablePath];
345
+
346
+ NSMutableSet<NSString *> *_Nonnull imagesAddrToRetrieveDebugMetaImages =
347
+ [[NSMutableSet alloc] init];
348
+ NSMutableArray<NSDictionary<NSString *, id> *> *_Nonnull serializedFrames =
349
+ [[NSMutableArray alloc] init];
350
+
351
+ for (NSNumber *addr in instructionsAddr) {
352
+ SentryBinaryImageInfo *_Nullable image = [[[SentryDependencyContainer sharedInstance]
353
+ binaryImageCache] imageByAddress:[addr unsignedLongLongValue]];
354
+ if (image != nil) {
355
+ NSString *imageAddr = sentry_formatHexAddressUInt64([image address]);
356
+ [imagesAddrToRetrieveDebugMetaImages addObject:imageAddr];
357
+
358
+ NSDictionary<NSString *, id> *_Nonnull nativeFrame = @{
359
+ @"platform" : @"cocoa",
360
+ @"instruction_addr" : sentry_formatHexAddress(addr),
361
+ @"package" : [image name],
362
+ @"image_addr" : imageAddr,
363
+ @"in_app" : [NSNumber numberWithBool:[appPackageName isEqualToString:[image name]]],
364
+ };
365
+
366
+ if (shouldSymbolicateLocally) {
367
+ Dl_info symbolsBuffer;
368
+ bool symbols_succeed = false;
369
+ symbols_succeed
370
+ = symbolicate((void *)[addr unsignedLongLongValue], &symbolsBuffer) != 0;
371
+ if (symbols_succeed) {
372
+ NSMutableDictionary<NSString *, id> *_Nonnull symbolicated
373
+ = nativeFrame.mutableCopy;
374
+ symbolicated[@"symbol_addr"]
375
+ = sentry_formatHexAddressUInt64((uintptr_t)symbolsBuffer.dli_saddr);
376
+ symbolicated[@"function"] = [NSString stringWithCString:symbolsBuffer.dli_sname
377
+ encoding:NSUTF8StringEncoding];
378
+
379
+ nativeFrame = symbolicated;
380
+ }
381
+ }
302
382
 
303
- nativeFrame = symbolicated;
383
+ [serializedFrames addObject:nativeFrame];
384
+ } else {
385
+ [serializedFrames addObject:@{
386
+ @"platform" : @"cocoa",
387
+ @"instruction_addr" : sentry_formatHexAddress(addr),
388
+ }];
304
389
  }
305
- }
390
+ }
306
391
 
307
- [serializedFrames addObject:nativeFrame];
392
+ if (shouldSymbolicateLocally) {
393
+ return @{
394
+ @"frames" : serializedFrames,
395
+ };
308
396
  } else {
309
- [serializedFrames addObject: @{
310
- @"platform": @"cocoa",
311
- @"instruction_addr": sentry_formatHexAddress(addr),
312
- }];
313
- }
314
- }
397
+ NSMutableArray<NSDictionary<NSString *, id> *> *_Nonnull serializedDebugMetaImages =
398
+ [[NSMutableArray alloc] init];
315
399
 
316
- if (shouldSymbolicateLocally) {
317
- return @{
318
- @"frames": serializedFrames,
319
- };
320
- } else {
321
- NSMutableArray<NSDictionary<NSString *, id> *> * _Nonnull serializedDebugMetaImages = [[NSMutableArray alloc] init];
400
+ NSArray<SentryDebugMeta *> *debugMetaImages =
401
+ [[[SentryDependencyContainer sharedInstance] debugImageProvider]
402
+ getDebugImagesForImageAddressesFromCache:imagesAddrToRetrieveDebugMetaImages];
322
403
 
323
- NSArray<SentryDebugMeta *> *debugMetaImages = [[[SentryDependencyContainer sharedInstance] debugImageProvider] getDebugImagesForAddresses:imagesAddrToRetrieveDebugMetaImages isCrash:false];
404
+ for (SentryDebugMeta *debugImage in debugMetaImages) {
405
+ [serializedDebugMetaImages addObject:[debugImage serialize]];
406
+ }
324
407
 
325
- for (SentryDebugMeta *debugImage in debugMetaImages) {
326
- [serializedDebugMetaImages addObject:[debugImage serialize]];
408
+ return @{
409
+ @"frames" : serializedFrames,
410
+ @"debugMetaImages" : serializedDebugMetaImages,
411
+ };
327
412
  }
328
-
329
- return @{
330
- @"frames": serializedFrames,
331
- @"debugMetaImages": serializedDebugMetaImages,
332
- };
333
- }
334
413
  }
335
414
 
336
- RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy:(NSArray *)instructionsAddr)
415
+ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy
416
+ : (NSArray *)instructionsAddr)
337
417
  {
338
- return [self fetchNativeStackFramesBy:instructionsAddr
339
- symbolicate:dladdr];
418
+ return [self fetchNativeStackFramesBy:instructionsAddr symbolicate:dladdr];
340
419
  }
341
420
 
342
- RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve
343
- rejecter:(RCTPromiseRejectBlock)reject)
421
+ RCT_EXPORT_METHOD(fetchNativeDeviceContexts
422
+ : (RCTPromiseResolveBlock)resolve rejecter
423
+ : (RCTPromiseRejectBlock)reject)
344
424
  {
345
425
  if (PrivateSentrySDKOnly.options.debug) {
346
426
  NSLog(@"Bridge call to: deviceContexts");
@@ -348,55 +428,74 @@ RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve
348
428
  __block NSMutableDictionary<NSString *, id> *serializedScope;
349
429
  // Temp work around until sorted out this API in sentry-cocoa.
350
430
  // TODO: If the callback isnt' executed the promise wouldn't be resolved.
351
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
431
+ [SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
352
432
  serializedScope = [[scope serialize] mutableCopy];
353
433
 
354
- NSDictionary<NSString *, id> *user = [serializedScope valueForKey:@"user"];
434
+ NSDictionary<NSString *, id> *user = [serializedScope valueForKey:@"user"];
355
435
  if (user == nil) {
356
- [serializedScope
357
- setValue:@{ @"id": PrivateSentrySDKOnly.installationID }
358
- forKey:@"user"];
436
+ [serializedScope setValue:@ { @"id" : PrivateSentrySDKOnly.installationID }
437
+ forKey:@"user"];
359
438
  }
360
439
 
361
440
  if (PrivateSentrySDKOnly.options.debug) {
362
- NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope options:0 error:nil];
363
- NSString *debugContext = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
441
+ NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope
442
+ options:0
443
+ error:nil];
444
+ NSString *debugContext = [[NSString alloc] initWithData:data
445
+ encoding:NSUTF8StringEncoding];
364
446
  NSLog(@"Contexts: %@", debugContext);
365
447
  }
366
448
  }];
367
449
 
368
450
  NSDictionary<NSString *, id> *extraContext = [PrivateSentrySDKOnly getExtraContext];
369
- NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *contexts = [serializedScope[@"context"] mutableCopy];
451
+ NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *contexts =
452
+ [serializedScope[@"context"] mutableCopy];
370
453
 
371
454
  if (extraContext && [extraContext[@"device"] isKindOfClass:[NSDictionary class]]) {
372
- NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *deviceContext = [contexts[@"device"] mutableCopy];
373
- [deviceContext addEntriesFromDictionary:extraContext[@"device"]];
374
- [contexts setValue:deviceContext forKey:@"device"];
455
+ NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *deviceContext =
456
+ [contexts[@"device"] mutableCopy];
457
+ [deviceContext addEntriesFromDictionary:extraContext[@"device"]];
458
+ [contexts setValue:deviceContext forKey:@"device"];
375
459
  }
376
460
 
377
461
  if (extraContext && [extraContext[@"app"] isKindOfClass:[NSDictionary class]]) {
378
- NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *appContext = [contexts[@"app"] mutableCopy];
379
- [appContext addEntriesFromDictionary:extraContext[@"app"]];
380
- [contexts setValue:appContext forKey:@"app"];
462
+ NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *appContext =
463
+ [contexts[@"app"] mutableCopy];
464
+ [appContext addEntriesFromDictionary:extraContext[@"app"]];
465
+ [contexts setValue:appContext forKey:@"app"];
381
466
  }
382
467
 
383
468
  [serializedScope setValue:contexts forKey:@"contexts"];
384
469
  [serializedScope removeObjectForKey:@"context"];
470
+
471
+ // Remove react-native breadcrumbs
472
+ NSPredicate *removeRNBreadcrumbsPredicate =
473
+ [NSPredicate predicateWithBlock:^BOOL(NSDictionary *breadcrumb, NSDictionary *bindings) {
474
+ return ![breadcrumb[@"origin"] isEqualToString:@"react-native"];
475
+ }];
476
+ NSArray *breadcrumbs = [[serializedScope[@"breadcrumbs"] mutableCopy]
477
+ filteredArrayUsingPredicate:removeRNBreadcrumbsPredicate];
478
+ [serializedScope setValue:breadcrumbs forKey:@"breadcrumbs"];
479
+
385
480
  resolve(serializedScope);
386
481
  }
387
482
 
388
- RCT_EXPORT_METHOD(fetchNativeAppStart:(RCTPromiseResolveBlock)resolve
389
- rejecter:(RCTPromiseRejectBlock)reject)
483
+ RCT_EXPORT_METHOD(fetchNativeAppStart
484
+ : (RCTPromiseResolveBlock)resolve rejecter
485
+ : (RCTPromiseRejectBlock)reject)
390
486
  {
391
487
  #if SENTRY_HAS_UIKIT
392
- NSDictionary<NSString *, id> *measurements = [PrivateSentrySDKOnly appStartMeasurementWithSpans];
488
+ NSDictionary<NSString *, id> *measurements =
489
+ [PrivateSentrySDKOnly appStartMeasurementWithSpans];
393
490
  if (measurements == nil) {
394
491
  resolve(nil);
395
492
  return;
396
493
  }
397
494
 
398
- NSMutableDictionary<NSString *, id> *mutableMeasurements = [[NSMutableDictionary alloc] initWithDictionary:measurements];
399
- [mutableMeasurements setValue:[NSNumber numberWithBool:hasFetchedAppStart] forKey:@"has_fetched"];
495
+ NSMutableDictionary<NSString *, id> *mutableMeasurements =
496
+ [[NSMutableDictionary alloc] initWithDictionary:measurements];
497
+ [mutableMeasurements setValue:[NSNumber numberWithBool:hasFetchedAppStart]
498
+ forKey:@"has_fetched"];
400
499
 
401
500
  // This is always set to true, as we would only allow an app start fetch to only happen once
402
501
  // in the case of a JS bundle reload, we do not want it to be instrumented again.
@@ -408,8 +507,9 @@ RCT_EXPORT_METHOD(fetchNativeAppStart:(RCTPromiseResolveBlock)resolve
408
507
  #endif
409
508
  }
410
509
 
411
- RCT_EXPORT_METHOD(fetchNativeFrames:(RCTPromiseResolveBlock)resolve
412
- rejecter:(RCTPromiseRejectBlock)reject)
510
+ RCT_EXPORT_METHOD(fetchNativeFrames
511
+ : (RCTPromiseResolveBlock)resolve rejecter
512
+ : (RCTPromiseRejectBlock)reject)
413
513
  {
414
514
 
415
515
  #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
@@ -425,79 +525,82 @@ RCT_EXPORT_METHOD(fetchNativeFrames:(RCTPromiseResolveBlock)resolve
425
525
  NSNumber *frozen = [NSNumber numberWithLong:frames.frozen];
426
526
  NSNumber *slow = [NSNumber numberWithLong:frames.slow];
427
527
 
428
- resolve(@{
429
- @"totalFrames": total,
430
- @"frozenFrames": frozen,
431
- @"slowFrames": slow,
528
+ resolve(@ {
529
+ @"totalFrames" : total,
530
+ @"frozenFrames" : frozen,
531
+ @"slowFrames" : slow,
432
532
  });
433
533
  } else {
434
- resolve(nil);
534
+ resolve(nil);
435
535
  }
436
536
  #else
437
537
  resolve(nil);
438
538
  #endif
439
539
  }
440
540
 
441
- RCT_EXPORT_METHOD(fetchNativeRelease:(RCTPromiseResolveBlock)resolve
442
- rejecter:(RCTPromiseRejectBlock)reject)
541
+ RCT_EXPORT_METHOD(fetchNativeRelease
542
+ : (RCTPromiseResolveBlock)resolve rejecter
543
+ : (RCTPromiseRejectBlock)reject)
443
544
  {
444
545
  NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
445
- resolve(@{
446
- @"id": infoDict[@"CFBundleIdentifier"],
447
- @"version": infoDict[@"CFBundleShortVersionString"],
448
- @"build": infoDict[@"CFBundleVersion"],
449
- });
450
- }
451
-
452
- RCT_EXPORT_METHOD(captureEnvelope:(NSString * _Nonnull)rawBytes
453
- options: (NSDictionary * _Nonnull)options
454
- resolve:(RCTPromiseResolveBlock)resolve
455
- rejecter:(RCTPromiseRejectBlock)reject)
546
+ resolve(@ {
547
+ @"id" : infoDict[@"CFBundleIdentifier"],
548
+ @"version" : infoDict[@"CFBundleShortVersionString"],
549
+ @"build" : infoDict[@"CFBundleVersion"],
550
+ });
551
+ }
552
+
553
+ RCT_EXPORT_METHOD(captureEnvelope
554
+ : (NSString *_Nonnull)rawBytes options
555
+ : (NSDictionary *_Nonnull)options resolve
556
+ : (RCTPromiseResolveBlock)resolve rejecter
557
+ : (RCTPromiseRejectBlock)reject)
456
558
  {
457
559
  NSData *data = [[NSData alloc] initWithBase64EncodedString:rawBytes options:0];
458
560
 
459
561
  SentryEnvelope *envelope = [PrivateSentrySDKOnly envelopeWithData:data];
460
562
  if (envelope == nil) {
461
- reject(@"SentryReactNative",@"Failed to parse envelope from byte array.", nil);
563
+ reject(@"SentryReactNative", @"Failed to parse envelope from byte array.", nil);
462
564
  return;
463
565
  }
464
566
 
465
- #if DEBUG
567
+ #if DEBUG
568
+ [PrivateSentrySDKOnly captureEnvelope:envelope];
569
+ #else
570
+ if ([[options objectForKey:@"hardCrashed"] boolValue]) {
571
+ // Storing to disk happens asynchronously with captureEnvelope
572
+ [PrivateSentrySDKOnly storeEnvelope:envelope];
573
+ } else {
466
574
  [PrivateSentrySDKOnly captureEnvelope:envelope];
467
- #else
468
- if ([[options objectForKey:@"hardCrashed"] boolValue]) {
469
- // Storing to disk happens asynchronously with captureEnvelope
470
- [PrivateSentrySDKOnly storeEnvelope:envelope];
471
- } else {
472
- [PrivateSentrySDKOnly captureEnvelope:envelope];
473
- }
474
- #endif
575
+ }
576
+ #endif
475
577
  resolve(@YES);
476
578
  }
477
579
 
478
- RCT_EXPORT_METHOD(captureScreenshot: (RCTPromiseResolveBlock)resolve
479
- rejecter: (RCTPromiseRejectBlock)reject)
580
+ RCT_EXPORT_METHOD(captureScreenshot
581
+ : (RCTPromiseResolveBlock)resolve rejecter
582
+ : (RCTPromiseRejectBlock)reject)
480
583
  {
481
584
  #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
482
- NSArray<NSData *>* rawScreenshots = [PrivateSentrySDKOnly captureScreenshots];
585
+ NSArray<NSData *> *rawScreenshots = [PrivateSentrySDKOnly captureScreenshots];
483
586
  NSMutableArray *screenshotsArray = [NSMutableArray arrayWithCapacity:[rawScreenshots count]];
484
587
 
485
588
  int counter = 1;
486
- for (NSData* raw in rawScreenshots) {
589
+ for (NSData *raw in rawScreenshots) {
487
590
  NSMutableArray *screenshot = [NSMutableArray arrayWithCapacity:raw.length];
488
- const char *bytes = (char*) [raw bytes];
591
+ const char *bytes = (char *)[raw bytes];
489
592
  for (int i = 0; i < [raw length]; i++) {
490
593
  [screenshot addObject:[[NSNumber alloc] initWithChar:bytes[i]]];
491
594
  }
492
595
 
493
- NSString* filename = @"screenshot.png";
596
+ NSString *filename = @"screenshot.png";
494
597
  if (counter > 1) {
495
598
  filename = [NSString stringWithFormat:@"screenshot-%d.png", counter];
496
599
  }
497
- [screenshotsArray addObject:@{
498
- @"data": screenshot,
499
- @"contentType": @"image/png",
500
- @"filename": filename,
600
+ [screenshotsArray addObject:@ {
601
+ @"data" : screenshot,
602
+ @"contentType" : @"image/png",
603
+ @"filename" : filename,
501
604
  }];
502
605
  counter++;
503
606
  }
@@ -508,14 +611,15 @@ RCT_EXPORT_METHOD(captureScreenshot: (RCTPromiseResolveBlock)resolve
508
611
  #endif
509
612
  }
510
613
 
511
- RCT_EXPORT_METHOD(fetchViewHierarchy: (RCTPromiseResolveBlock)resolve
512
- rejecter: (RCTPromiseRejectBlock)reject)
614
+ RCT_EXPORT_METHOD(fetchViewHierarchy
615
+ : (RCTPromiseResolveBlock)resolve rejecter
616
+ : (RCTPromiseRejectBlock)reject)
513
617
  {
514
618
  #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
515
- NSData * rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy];
619
+ NSData *rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy];
516
620
 
517
621
  NSMutableArray *viewHierarchy = [NSMutableArray arrayWithCapacity:rawViewHierarchy.length];
518
- const char *bytes = (char*) [rawViewHierarchy bytes];
622
+ const char *bytes = (char *)[rawViewHierarchy bytes];
519
623
  for (int i = 0; i < [rawViewHierarchy length]; i++) {
520
624
  [viewHierarchy addObject:[[NSNumber alloc] initWithChar:bytes[i]]];
521
625
  }
@@ -526,16 +630,13 @@ RCT_EXPORT_METHOD(fetchViewHierarchy: (RCTPromiseResolveBlock)resolve
526
630
  #endif
527
631
  }
528
632
 
529
-
530
- RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys
531
- otherUserKeys:(NSDictionary *)userDataKeys
532
- )
633
+ RCT_EXPORT_METHOD(setUser : (NSDictionary *)userKeys otherUserKeys : (NSDictionary *)userDataKeys)
533
634
  {
534
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
635
+ [SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
535
636
  if (nil == userKeys && nil == userDataKeys) {
536
637
  [scope setUser:nil];
537
638
  } else {
538
- SentryUser* userInstance = [[SentryUser alloc] init];
639
+ SentryUser *userInstance = [[SentryUser alloc] init];
539
640
 
540
641
  if (nil != userKeys) {
541
642
  [userInstance setUserId:userKeys[@"id"]];
@@ -554,9 +655,9 @@ RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys
554
655
  }];
555
656
  }
556
657
 
557
- RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb)
658
+ RCT_EXPORT_METHOD(addBreadcrumb : (NSDictionary *)breadcrumb)
558
659
  {
559
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
660
+ [SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
560
661
  [scope addBreadcrumb:[RNSentryBreadcrumb from:breadcrumb]];
561
662
  }];
562
663
 
@@ -565,33 +666,27 @@ RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb)
565
666
  if (screen != nil) {
566
667
  [PrivateSentrySDKOnly setCurrentScreen:screen];
567
668
  }
568
- #endif //SENTRY_HAS_UIKIT
669
+ #endif // SENTRY_HAS_UIKIT
569
670
  }
570
671
 
571
- RCT_EXPORT_METHOD(clearBreadcrumbs) {
572
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
573
- [scope clearBreadcrumbs];
574
- }];
672
+ RCT_EXPORT_METHOD(clearBreadcrumbs)
673
+ {
674
+ [SentrySDK configureScope:^(SentryScope *_Nonnull scope) { [scope clearBreadcrumbs]; }];
575
675
  }
576
676
 
577
- RCT_EXPORT_METHOD(setExtra:(NSString *)key
578
- extra:(NSString *)extra
579
- )
677
+ RCT_EXPORT_METHOD(setExtra : (NSString *)key extra : (NSString *)extra)
580
678
  {
581
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
582
- [scope setExtraValue:extra forKey:key];
583
- }];
679
+ [SentrySDK
680
+ configureScope:^(SentryScope *_Nonnull scope) { [scope setExtraValue:extra forKey:key]; }];
584
681
  }
585
682
 
586
- RCT_EXPORT_METHOD(setContext:(NSString *)key
587
- context:(NSDictionary *)context
588
- )
683
+ RCT_EXPORT_METHOD(setContext : (NSString *)key context : (NSDictionary *)context)
589
684
  {
590
685
  if (key == nil) {
591
686
  return;
592
687
  }
593
688
 
594
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
689
+ [SentrySDK configureScope:^(SentryScope *_Nonnull scope) {
595
690
  if (context == nil) {
596
691
  [scope removeContextForKey:key];
597
692
  } else {
@@ -600,25 +695,20 @@ RCT_EXPORT_METHOD(setContext:(NSString *)key
600
695
  }];
601
696
  }
602
697
 
603
- RCT_EXPORT_METHOD(setTag:(NSString *)key
604
- value:(NSString *)value
605
- )
698
+ RCT_EXPORT_METHOD(setTag : (NSString *)key value : (NSString *)value)
606
699
  {
607
- [SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
608
- [scope setTagValue:value forKey:key];
609
- }];
700
+ [SentrySDK
701
+ configureScope:^(SentryScope *_Nonnull scope) { [scope setTagValue:value forKey:key]; }];
610
702
  }
611
703
 
612
- RCT_EXPORT_METHOD(crash)
613
- {
614
- [SentrySDK crash];
615
- }
704
+ RCT_EXPORT_METHOD(crash) { [SentrySDK crash]; }
616
705
 
617
- RCT_EXPORT_METHOD(closeNativeSdk:(RCTPromiseResolveBlock)resolve
618
- rejecter:(RCTPromiseRejectBlock)reject)
706
+ RCT_EXPORT_METHOD(closeNativeSdk
707
+ : (RCTPromiseResolveBlock)resolve rejecter
708
+ : (RCTPromiseRejectBlock)reject)
619
709
  {
620
- [SentrySDK close];
621
- resolve(@YES);
710
+ [SentrySDK close];
711
+ resolve(@YES);
622
712
  }
623
713
 
624
714
  RCT_EXPORT_METHOD(disableNativeFramesTracking)
@@ -634,70 +724,76 @@ RCT_EXPORT_METHOD(enableNativeFramesTracking)
634
724
  // the 'tracesSampleRate' or 'tracesSampler' option.
635
725
  }
636
726
 
637
- RCT_EXPORT_METHOD(captureReplay: (BOOL)isHardCrash
638
- resolver:(RCTPromiseResolveBlock)resolve
639
- rejecter:(RCTPromiseRejectBlock)reject)
727
+ RCT_EXPORT_METHOD(captureReplay
728
+ : (BOOL)isHardCrash resolver
729
+ : (RCTPromiseResolveBlock)resolve rejecter
730
+ : (RCTPromiseRejectBlock)reject)
640
731
  {
641
732
  #if SENTRY_TARGET_REPLAY_SUPPORTED
642
- [PrivateSentrySDKOnly captureReplay];
643
- resolve([PrivateSentrySDKOnly getReplayId]);
733
+ [PrivateSentrySDKOnly captureReplay];
734
+ resolve([PrivateSentrySDKOnly getReplayId]);
644
735
  #else
645
- resolve(nil);
736
+ resolve(nil);
646
737
  #endif
647
738
  }
648
739
 
649
740
  RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getCurrentReplayId)
650
741
  {
651
742
  #if SENTRY_TARGET_REPLAY_SUPPORTED
652
- return [PrivateSentrySDKOnly getReplayId];
743
+ return [PrivateSentrySDKOnly getReplayId];
653
744
  #else
654
- return nil;
745
+ return nil;
655
746
  #endif
656
747
  }
657
748
 
658
- static NSString* const enabledProfilingMessage = @"Enable Hermes to use Sentry Profiling.";
659
- static SentryId* nativeProfileTraceId = nil;
749
+ static NSString *const enabledProfilingMessage = @"Enable Hermes to use Sentry Profiling.";
750
+ static SentryId *nativeProfileTraceId = nil;
660
751
  static uint64_t nativeProfileStartTime = 0;
661
752
 
662
- RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling: (BOOL)platformProfilers)
753
+ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling : (BOOL)platformProfilers)
663
754
  {
664
755
  #if SENTRY_PROFILING_ENABLED
665
756
  try {
666
757
  facebook::hermes::HermesRuntime::enableSamplingProfiler();
667
758
  if (nativeProfileTraceId == nil && nativeProfileStartTime == 0 && platformProfilers) {
668
- #if SENTRY_TARGET_PROFILING_SUPPORTED
759
+ # if SENTRY_TARGET_PROFILING_SUPPORTED
669
760
  nativeProfileTraceId = [RNSentryId newId];
670
- nativeProfileStartTime = [PrivateSentrySDKOnly startProfilerForTrace: nativeProfileTraceId];
671
- #endif
761
+ nativeProfileStartTime =
762
+ [PrivateSentrySDKOnly startProfilerForTrace:nativeProfileTraceId];
763
+ # endif
672
764
  } else {
673
765
  if (!platformProfilers) {
674
766
  NSLog(@"Native profiling is disabled. Only starting Hermes profiling.");
675
767
  } else {
676
- NSLog(@"Native profiling already in progress. Currently existing trace: %@", nativeProfileTraceId);
768
+ NSLog(@"Native profiling already in progress. Currently existing trace: %@",
769
+ nativeProfileTraceId);
677
770
  }
678
771
  }
679
- return @{ @"started": @YES };
680
- } catch (const std::exception& ex) {
772
+ return @{@"started" : @YES};
773
+ } catch (const std::exception &ex) {
681
774
  if (nativeProfileTraceId != nil) {
682
- #if SENTRY_TARGET_PROFILING_SUPPORTED
683
- [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
684
- #endif
775
+ # if SENTRY_TARGET_PROFILING_SUPPORTED
776
+ [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
777
+ # endif
685
778
  nativeProfileTraceId = nil;
686
779
  }
687
780
  nativeProfileStartTime = 0;
688
- return @{ @"error": [NSString stringWithCString: ex.what() encoding:[NSString defaultCStringEncoding]] };
781
+ return @ {
782
+ @"error" : [NSString stringWithCString:ex.what()
783
+ encoding:[NSString defaultCStringEncoding]]
784
+ };
689
785
  } catch (...) {
690
786
  if (nativeProfileTraceId != nil) {
691
- #if SENTRY_TARGET_PROFILING_SUPPORTED
692
- [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
693
- #endif
787
+ # if SENTRY_TARGET_PROFILING_SUPPORTED
788
+ [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
789
+ # endif
694
790
  nativeProfileTraceId = nil;
695
791
  }
696
792
  nativeProfileStartTime = 0;
697
- return @{ @"error": @"Failed to start profiling" };
793
+ return @ { @"error" : @"Failed to start profiling" };
698
794
  }
699
795
  #else
700
- return @{ @"error": enabledProfilingMessage };
796
+ return @ { @"error" : enabledProfilingMessage };
701
797
  #endif
702
798
  }
703
799
 
@@ -705,12 +801,14 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, stopProfiling)
705
801
  {
706
802
  #if SENTRY_PROFILING_ENABLED
707
803
  try {
708
- NSDictionary<NSString *, id> * nativeProfile = nil;
804
+ NSDictionary<NSString *, id> *nativeProfile = nil;
709
805
  if (nativeProfileTraceId != nil && nativeProfileStartTime != 0) {
710
- #if SENTRY_TARGET_PROFILING_SUPPORTED
806
+ # if SENTRY_TARGET_PROFILING_SUPPORTED
711
807
  uint64_t nativeProfileStopTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
712
- nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime and:nativeProfileStopTime forTrace:nativeProfileTraceId];
713
- #endif
808
+ nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime
809
+ and:nativeProfileStopTime
810
+ forTrace:nativeProfileTraceId];
811
+ # endif
714
812
  }
715
813
  // Cleanup native profiles
716
814
  nativeProfileTraceId = nil;
@@ -722,57 +820,66 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, stopProfiling)
722
820
  facebook::hermes::HermesRuntime::dumpSampledTraceToStream(ss);
723
821
 
724
822
  std::string s = ss.str();
725
- NSString *data = [NSString stringWithCString:s.c_str() encoding:[NSString defaultCStringEncoding]];
823
+ NSString *data = [NSString stringWithCString:s.c_str()
824
+ encoding:[NSString defaultCStringEncoding]];
726
825
 
727
- #if SENTRY_PROFILING_DEBUG_ENABLED
826
+ # if SENTRY_PROFILING_DEBUG_ENABLED
728
827
  NSString *rawProfileFileName = @"hermes.profile";
729
828
  NSError *error = nil;
730
- NSString *rawProfileFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:rawProfileFileName];
731
- if (![data writeToFile:rawProfileFilePath atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
829
+ NSString *rawProfileFilePath =
830
+ [NSTemporaryDirectory() stringByAppendingPathComponent:rawProfileFileName];
831
+ if (![data writeToFile:rawProfileFilePath
832
+ atomically:YES
833
+ encoding:NSUTF8StringEncoding
834
+ error:&error]) {
732
835
  NSLog(@"Error writing Raw Hermes Profile to %@: %@", rawProfileFilePath, error);
733
836
  } else {
734
837
  NSLog(@"Raw Hermes Profile saved to %@", rawProfileFilePath);
735
838
  }
736
- #endif
839
+ # endif
737
840
 
738
841
  if (data == nil) {
739
- return @{ @"error": @"Failed to retrieve Hermes profile." };
842
+ return @ { @"error" : @"Failed to retrieve Hermes profile." };
740
843
  }
741
844
 
742
845
  if (nativeProfile == nil) {
743
- return @{ @"profile": data };
846
+ return @ { @"profile" : data };
744
847
  }
745
848
 
746
- return @{
747
- @"profile": data,
748
- @"nativeProfile": nativeProfile,
849
+ return @ {
850
+ @"profile" : data,
851
+ @"nativeProfile" : nativeProfile,
749
852
  };
750
- } catch (const std::exception& ex) {
853
+ } catch (const std::exception &ex) {
751
854
  if (nativeProfileTraceId != nil) {
752
- #if SENTRY_TARGET_PROFILING_SUPPORTED
753
- [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
754
- #endif
755
- nativeProfileTraceId = nil;
855
+ # if SENTRY_TARGET_PROFILING_SUPPORTED
856
+ [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
857
+ # endif
858
+ nativeProfileTraceId = nil;
756
859
  }
757
860
  nativeProfileStartTime = 0;
758
- return @{ @"error": [NSString stringWithCString: ex.what() encoding:[NSString defaultCStringEncoding]] };
861
+ return @ {
862
+ @"error" : [NSString stringWithCString:ex.what()
863
+ encoding:[NSString defaultCStringEncoding]]
864
+ };
759
865
  } catch (...) {
760
866
  if (nativeProfileTraceId != nil) {
761
- #if SENTRY_TARGET_PROFILING_SUPPORTED
762
- [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId];
763
- #endif
764
- nativeProfileTraceId = nil;
867
+ # if SENTRY_TARGET_PROFILING_SUPPORTED
868
+ [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId];
869
+ # endif
870
+ nativeProfileTraceId = nil;
765
871
  }
766
872
  nativeProfileStartTime = 0;
767
- return @{ @"error": @"Failed to stop profiling" };
873
+ return @ { @"error" : @"Failed to stop profiling" };
768
874
  }
769
875
  #else
770
- return @{ @"error": enabledProfilingMessage };
876
+ return @ { @"error" : enabledProfilingMessage };
771
877
  #endif
772
878
  }
773
879
 
774
- RCT_EXPORT_METHOD(crashedLastRun:(RCTPromiseResolveBlock)resolve
775
- rejecter:(RCTPromiseRejectBlock)reject)
880
+ RCT_EXPORT_METHOD(crashedLastRun
881
+ : (RCTPromiseResolveBlock)resolve rejecter
882
+ : (RCTPromiseRejectBlock)reject)
776
883
  {
777
884
  resolve(@([SentrySDK crashedLastRun]));
778
885
  }
@@ -786,4 +893,11 @@ RCT_EXPORT_METHOD(crashedLastRun:(RCTPromiseResolveBlock)resolve
786
893
  }
787
894
  #endif
788
895
 
896
+ RCT_EXPORT_METHOD(getNewScreenTimeToDisplay
897
+ : (RCTPromiseResolveBlock)resolve rejecter
898
+ : (RCTPromiseRejectBlock)reject)
899
+ {
900
+ [_timeToDisplay getTimeToDisplay:resolve];
901
+ }
902
+
789
903
  @end