diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..45e033d570 --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +BasedOnStyle: WebKit +IndentWidth: 4 +IndentPPDirectives: AfterHash +ColumnLimit: 100 +AlwaysBreakAfterDefinitionReturnType: All +PointerAlignment: Right diff --git a/package.json b/package.json index 9d48508851..7dfaed4c81 100644 --- a/package.json +++ b/package.json @@ -7,20 +7,24 @@ "clean": "lerna run clean", "circularDepCheck": "lerna run circularDepCheck", "test": "lerna run test", - "fix": "run-s fix:lerna fix:android", + "fix": "run-s fix:lerna fix:android fix:clang", "fix:lerna": "lerna run fix", "fix:android": "run-s 'java:format fix' java:pmd", - "lint": "run-s lint:lerna lint:android", + "fix:clang": "run-s 'clang:format fix'", + "lint": "run-s lint:lerna lint:android lint:clang", "lint:lerna": "lerna run lint", "lint:android": "run-s 'java:format lint' java:pmd", + "lint:clang": "run-s 'clang:format lint'", "java:format": "./scripts/google-java-format.sh", "java:pmd": "./scripts/pmd.sh", + "clang:format": "./scripts/clang-format.sh", "run-ios": "cd samples/react-native && yarn react-native run-ios", "run-android": "cd samples/react-native && yarn react-native run-android", "set-version-samples": "lerna run set-version" }, "devDependencies": { "@sentry/cli": "2.38.1", + "clang-format": "^1.8.0", "downlevel-dts": "^0.11.0", "google-java-format": "^1.4.0", "lerna": "^8.1.8", diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryCocoaTesterTests-Bridging-Header.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryCocoaTesterTests-Bridging-Header.h index e177d453fb..6b949b5967 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryCocoaTesterTests-Bridging-Header.h +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryCocoaTesterTests-Bridging-Header.h @@ -2,5 +2,5 @@ // Use this file to import your target's public headers that you would like to expose to Swift. // -#import "RNSentryReplayBreadcrumbConverter.h" #import "RNSentryBreadcrumb.h" +#import "RNSentryReplayBreadcrumbConverter.h" diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h index 9d98d08b4a..3b3055e2f3 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.h @@ -1,10 +1,10 @@ +#import "SentryFramesTracker.h" #import #import -#import "SentryFramesTracker.h" @interface SentrySDK (PrivateTests) -- (nullable SentryOptions *) options; +- (nullable SentryOptions *)options; @end @interface SentryDependencyContainer : NSObject diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryDependencyContainerTests.m index 4bed149b72..ab81eb658b 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 "RNSentryDependencyContainer.h" @interface RNSentryDependencyContainerTests : XCTestCase @@ -12,17 +12,20 @@ @implementation RNSentryDependencyContainerTests - (void)testRNSentryDependencyContainerInitializesFrameTracker { - XCTAssertNil([[RNSentryDependencyContainer sharedInstance] framesTrackerListener]); + XCTAssertNil([[RNSentryDependencyContainer sharedInstance] framesTrackerListener]); - id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); - OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])).andReturn(sentryDependencyContainerMock); + id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); + OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])) + .andReturn(sentryDependencyContainerMock); - id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); - OCMStub([(SentryDependencyContainer*) sentryDependencyContainerMock framesTracker]).andReturn(frameTrackerMock); + id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); + OCMStub([(SentryDependencyContainer *)sentryDependencyContainerMock framesTracker]) + .andReturn(frameTrackerMock); - RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) {}; - [[RNSentryDependencyContainer sharedInstance] initializeFramesTrackerListenerWith: emitNewFrameEvent]; - XCTAssertNotNil([[RNSentryDependencyContainer sharedInstance] framesTrackerListener]); + RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) {}; + [[RNSentryDependencyContainer sharedInstance] + initializeFramesTrackerListenerWith:emitNewFrameEvent]; + XCTAssertNotNil([[RNSentryDependencyContainer sharedInstance] framesTrackerListener]); } @end diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h index 9d98d08b4a..3b3055e2f3 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.h @@ -1,10 +1,10 @@ +#import "SentryFramesTracker.h" #import #import -#import "SentryFramesTracker.h" @interface SentrySDK (PrivateTests) -- (nullable SentryOptions *) options; +- (nullable SentryOptions *)options; @end @interface SentryDependencyContainer : NSObject diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m index 2a3336fb25..ee33d109e4 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryFramesTrackerListenerTests.m @@ -1,8 +1,8 @@ #import "RNSentryFramesTrackerListenerTests.h" +#import "RNSentryDependencyContainer.h" #import #import #import -#import "RNSentryDependencyContainer.h" @interface RNSentryFramesTrackerListenerTests : XCTestCase @@ -12,58 +12,68 @@ @implementation RNSentryFramesTrackerListenerTests - (void)testRNSentryFramesTrackerCallsGivenEventEmitterOnNewFrame { - id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); - OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])).andReturn(sentryDependencyContainerMock); + id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); + OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])) + .andReturn(sentryDependencyContainerMock); - id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); - OCMStub([(SentryDependencyContainer*) sentryDependencyContainerMock framesTracker]).andReturn(frameTrackerMock); + id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); + OCMStub([(SentryDependencyContainer *)sentryDependencyContainerMock framesTracker]) + .andReturn(frameTrackerMock); - XCTestExpectation *blockExpectation = [self expectationWithDescription:@"Block Expectation"]; + XCTestExpectation *blockExpectation = [self expectationWithDescription:@"Block Expectation"]; - RNSentryEmitNewFrameEvent mockEventEmitter = ^(NSNumber *newFrameTimestampInSeconds) { - XCTAssertTrue([newFrameTimestampInSeconds isKindOfClass:[NSNumber class]], @"The variable should be of type NSNumber."); - [blockExpectation fulfill]; - }; + RNSentryEmitNewFrameEvent mockEventEmitter = ^(NSNumber *newFrameTimestampInSeconds) { + XCTAssertTrue([newFrameTimestampInSeconds isKindOfClass:[NSNumber class]], + @"The variable should be of type NSNumber."); + [blockExpectation fulfill]; + }; - RNSentryFramesTrackerListener* actualListener = [[RNSentryFramesTrackerListener alloc] initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] - andEventEmitter: mockEventEmitter]; + RNSentryFramesTrackerListener *actualListener = [[RNSentryFramesTrackerListener alloc] + initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] + andEventEmitter:mockEventEmitter]; - [actualListener framesTrackerHasNewFrame: [NSDate date]]; - [self waitForExpectationsWithTimeout:1.0 handler:nil]; + [actualListener framesTrackerHasNewFrame:[NSDate date]]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; } - (void)testRNSentryFramesTrackerIsOneTimeListener { - id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); - OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])).andReturn(sentryDependencyContainerMock); + id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); + OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])) + .andReturn(sentryDependencyContainerMock); - id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); - OCMStub([(SentryDependencyContainer*) sentryDependencyContainerMock framesTracker]).andReturn(frameTrackerMock); + id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); + OCMStub([(SentryDependencyContainer *)sentryDependencyContainerMock framesTracker]) + .andReturn(frameTrackerMock); - RNSentryEmitNewFrameEvent mockEventEmitter = ^(NSNumber *newFrameTimestampInSeconds) {}; + RNSentryEmitNewFrameEvent mockEventEmitter = ^(NSNumber *newFrameTimestampInSeconds) {}; - RNSentryFramesTrackerListener* actualListener = [[RNSentryFramesTrackerListener alloc] initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] - andEventEmitter: mockEventEmitter]; + RNSentryFramesTrackerListener *actualListener = [[RNSentryFramesTrackerListener alloc] + initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] + andEventEmitter:mockEventEmitter]; - [actualListener framesTrackerHasNewFrame: [NSDate date]]; - OCMVerify([frameTrackerMock removeListener:actualListener]); + [actualListener framesTrackerHasNewFrame:[NSDate date]]; + OCMVerify([frameTrackerMock removeListener:actualListener]); } - (void)testRNSentryFramesTrackerAddsItselfAsListener { - id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); - OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])).andReturn(sentryDependencyContainerMock); + id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); + OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])) + .andReturn(sentryDependencyContainerMock); - id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); - OCMStub([(SentryDependencyContainer*) sentryDependencyContainerMock framesTracker]).andReturn(frameTrackerMock); + id frameTrackerMock = OCMClassMock([SentryFramesTracker class]); + OCMStub([(SentryDependencyContainer *)sentryDependencyContainerMock framesTracker]) + .andReturn(frameTrackerMock); - RNSentryEmitNewFrameEvent mockEventEmitter = ^(NSNumber *newFrameTimestampInSeconds) {}; + RNSentryEmitNewFrameEvent mockEventEmitter = ^(NSNumber *newFrameTimestampInSeconds) {}; - RNSentryFramesTrackerListener* actualListener = [[RNSentryFramesTrackerListener alloc] initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] - andEventEmitter: mockEventEmitter]; + RNSentryFramesTrackerListener *actualListener = [[RNSentryFramesTrackerListener alloc] + initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] + andEventEmitter:mockEventEmitter]; - [actualListener startListening]; - OCMVerify([frameTrackerMock addListener:actualListener]); + [actualListener startListening]; + OCMVerify([frameTrackerMock addListener:actualListener]); } @end diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporterTests.m b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporterTests.m index 022dc89951..13de6a12c9 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporterTests.m +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporterTests.m @@ -1,5 +1,5 @@ -#import #import "RNSentryOnDrawReporter.h" +#import @interface RNSentryOnDrawReporterTests : XCTestCase @@ -9,8 +9,8 @@ @implementation RNSentryOnDrawReporterTests - (void)testRNSentryOnDrawReporterViewIsAvailableWhenUIKitIs { - RNSentryOnDrawReporterView* view = [[RNSentryOnDrawReporterView alloc] init]; - XCTAssertNotNil(view); + RNSentryOnDrawReporterView *view = [[RNSentryOnDrawReporterView alloc] init]; + XCTAssertNotNil(view); } @end diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h index 47d5e60493..8c2fddad03 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.h @@ -3,7 +3,7 @@ @interface SentrySDK (PrivateTests) -- (nullable SentryOptions *) options; +- (nullable SentryOptions *)options; @end @interface SentryBinaryImageInfo : NSObject diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.mm b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.mm index 1ef91af466..297022311e 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.mm +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryTests.mm @@ -1,8 +1,8 @@ #import "RNSentryTests.h" #import +#import #import #import -#import @interface RNSentryInitNativeSdkTests : XCTestCase @@ -12,176 +12,195 @@ @implementation RNSentryInitNativeSdkTests - (void)testCreateOptionsWithDictionaryRemovesPerformanceProperties { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; - - NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"beforeSend": @"will_be_overwritten", - @"tracesSampleRate": @1, - @"tracesSampler": ^(SentrySamplingContext *_Nonnull samplingContext) { - return @1; - }, - @"enableTracing": @YES, - }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; - - XCTAssertNotNil(actualOptions, @"Did not create sentry options"); - XCTAssertNil(error, @"Should not pass no error"); - XCTAssertNotNil(actualOptions.beforeSend, @"Before send is overwriten by the native RNSentry implementation"); - 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"); + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; + + NSDictionary *_Nonnull mockedReactNativeDictionary = + @{ @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"beforeSend" : @"will_be_overwritten", + @"tracesSampleRate" : @1, + @"tracesSampler" : ^(SentrySamplingContext *_Nonnull samplingContext) { return @1; +} +, @"enableTracing" : @YES, +} +; +SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; + +XCTAssertNotNil(actualOptions, @"Did not create sentry options"); +XCTAssertNil(error, @"Should not pass no error"); +XCTAssertNotNil( + actualOptions.beforeSend, @"Before send is overwriten by the native RNSentry implementation"); +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)testCreateOptionsWithDictionaryNativeCrashHandlingDefault { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertEqual([actualOptions.integrations containsObject:@"SentryCrashIntegration"], true, @"Did not set native crash handling"); + XCTAssertEqual([actualOptions.integrations containsObject:@"SentryCrashIntegration"], true, + @"Did not set native crash handling"); } - (void)testCreateOptionsWithDictionaryAutoPerformanceTracingDefault { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertEqual(actualOptions.enableAutoPerformanceTracing, true, @"Did not set Auto Performance Tracing"); + XCTAssertEqual( + actualOptions.enableAutoPerformanceTracing, true, @"Did not set Auto Performance Tracing"); } - (void)testCreateOptionsWithDictionaryNativeCrashHandlingEnabled { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"enableNativeCrashHandling": @YES, + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"enableNativeCrashHandling" : @YES, }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertEqual([actualOptions.integrations containsObject:@"SentryCrashIntegration"], true, @"Did not set native crash handling"); + XCTAssertEqual([actualOptions.integrations containsObject:@"SentryCrashIntegration"], true, + @"Did not set native crash handling"); } - (void)testCreateOptionsWithDictionaryAutoPerformanceTracingEnabled { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"enableAutoPerformanceTracing": @YES, + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"enableAutoPerformanceTracing" : @YES, }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertEqual(actualOptions.enableAutoPerformanceTracing, true, @"Did not set Auto Performance Tracing"); + XCTAssertEqual( + actualOptions.enableAutoPerformanceTracing, true, @"Did not set Auto Performance Tracing"); } - (void)testCreateOptionsWithDictionaryNativeCrashHandlingDisabled { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"enableNativeCrashHandling": @NO, + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"enableNativeCrashHandling" : @NO, }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertEqual([actualOptions.integrations containsObject:@"SentryCrashIntegration"], false, @"Did not disable native crash handling"); + XCTAssertEqual([actualOptions.integrations containsObject:@"SentryCrashIntegration"], false, + @"Did not disable native crash handling"); } - (void)testCreateOptionsWithDictionaryAutoPerformanceTracingDisabled { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"enableAutoPerformanceTracing": @NO, + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"enableAutoPerformanceTracing" : @NO, }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertEqual(actualOptions.enableAutoPerformanceTracing, false, @"Did not disable Auto Performance Tracing"); + XCTAssertEqual(actualOptions.enableAutoPerformanceTracing, false, + @"Did not disable Auto Performance Tracing"); } - (void)testCreateOptionsWithDictionarySpotlightEnabled { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"spotlight": @YES, - @"defaultSidecarUrl": @"http://localhost:8969/teststream", + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"spotlight" : @YES, + @"defaultSidecarUrl" : @"http://localhost:8969/teststream", }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertTrue(actualOptions.enableSpotlight , @"Did not enable spotlight"); - XCTAssertEqual(actualOptions.spotlightUrl , @"http://localhost:8969/teststream"); + XCTAssertTrue(actualOptions.enableSpotlight, @"Did not enable spotlight"); + XCTAssertEqual(actualOptions.spotlightUrl, @"http://localhost:8969/teststream"); } - (void)testCreateOptionsWithDictionarySpotlightOne { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"spotlight": @1, - @"defaultSidecarUrl": @"http://localhost:8969/teststream", + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"spotlight" : @1, + @"defaultSidecarUrl" : @"http://localhost:8969/teststream", }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertTrue(actualOptions.enableSpotlight , @"Did not enable spotlight"); - XCTAssertEqual(actualOptions.spotlightUrl , @"http://localhost:8969/teststream"); + XCTAssertTrue(actualOptions.enableSpotlight, @"Did not enable spotlight"); + XCTAssertEqual(actualOptions.spotlightUrl, @"http://localhost:8969/teststream"); } - (void)testCreateOptionsWithDictionarySpotlightUrl { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"spotlight": @"http://localhost:8969/teststream", + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"spotlight" : @"http://localhost:8969/teststream", }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); - XCTAssertTrue(actualOptions.enableSpotlight , @"Did not enable spotlight"); - XCTAssertEqual(actualOptions.spotlightUrl , @"http://localhost:8969/teststream"); + XCTAssertTrue(actualOptions.enableSpotlight, @"Did not enable spotlight"); + XCTAssertEqual(actualOptions.spotlightUrl, @"http://localhost:8969/teststream"); } - (void)testCreateOptionsWithDictionarySpotlightDisabled { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"spotlight": @NO, + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"spotlight" : @NO, }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); XCTAssertFalse(actualOptions.enableSpotlight, @"Did not disable spotlight"); @@ -189,14 +208,15 @@ - (void)testCreateOptionsWithDictionarySpotlightDisabled - (void)testCreateOptionsWithDictionarySpotlightZero { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"https://abcd@efgh.ingest.sentry.io/123456", - @"spotlight": @0, + @"dsn" : @"https://abcd@efgh.ingest.sentry.io/123456", + @"spotlight" : @0, }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNotNil(actualOptions, @"Did not create sentry options"); XCTAssertNil(error, @"Should not pass no error"); XCTAssertFalse(actualOptions.enableSpotlight, @"Did not disable spotlight"); @@ -204,13 +224,14 @@ - (void)testCreateOptionsWithDictionarySpotlightZero - (void)testPassesErrorOnWrongDsn { - RNSentry * rnSentry = [[RNSentry alloc] init]; - NSError* error = nil; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSError *error = nil; NSDictionary *_Nonnull mockedReactNativeDictionary = @{ - @"dsn": @"not_a_valid_dsn", + @"dsn" : @"not_a_valid_dsn", }; - SentryOptions* actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary error:&error]; + SentryOptions *actualOptions = [rnSentry createOptionsWithDictionary:mockedReactNativeDictionary + error:&error]; XCTAssertNil(actualOptions, @"Created invalid sentry options"); XCTAssertNotNil(error, @"Did not created error on invalid dsn"); @@ -218,154 +239,169 @@ - (void)testPassesErrorOnWrongDsn - (void)testEventFromSentryCocoaReactNativeHasOriginAndEnvironmentTags { - RNSentry* rnSentry = [[RNSentry alloc] init]; - SentryEvent* testEvent = [[SentryEvent alloc] init]; - testEvent.sdk = @{ - @"name": @"sentry.cocoa.react-native", - }; - - [rnSentry setEventOriginTag: testEvent]; - - XCTAssertEqual(testEvent.tags[@"event.origin"], @"ios"); - XCTAssertEqual(testEvent.tags[@"event.environment"], @"native"); + RNSentry *rnSentry = [[RNSentry alloc] init]; + SentryEvent *testEvent = [[SentryEvent alloc] init]; + testEvent.sdk = @{ + @"name" : @"sentry.cocoa.react-native", + }; + + [rnSentry setEventOriginTag:testEvent]; + + XCTAssertEqual(testEvent.tags[@"event.origin"], @"ios"); + XCTAssertEqual(testEvent.tags[@"event.environment"], @"native"); } - (void)testEventFromSentryReactNativeOriginAndEnvironmentTagsAreOverwritten { - RNSentry* rnSentry = [[RNSentry alloc] init]; - SentryEvent* testEvent = [[SentryEvent alloc] init]; - testEvent.sdk = @{ - @"name": @"sentry.cocoa.react-native", - }; - testEvent.tags = @{ - @"event.origin": @"testEventOriginTag", - @"event.environment": @"testEventEnvironmentTag", - }; - - [rnSentry setEventOriginTag: testEvent]; - - XCTAssertEqual(testEvent.tags[@"event.origin"], @"ios"); - XCTAssertEqual(testEvent.tags[@"event.environment"], @"native"); + RNSentry *rnSentry = [[RNSentry alloc] init]; + SentryEvent *testEvent = [[SentryEvent alloc] init]; + testEvent.sdk = @{ + @"name" : @"sentry.cocoa.react-native", + }; + testEvent.tags = @{ + @"event.origin" : @"testEventOriginTag", + @"event.environment" : @"testEventEnvironmentTag", + }; + + [rnSentry setEventOriginTag:testEvent]; + + XCTAssertEqual(testEvent.tags[@"event.origin"], @"ios"); + XCTAssertEqual(testEvent.tags[@"event.environment"], @"native"); } -void (^expectRejecterNotCalled)(NSString*, NSString*, NSError*) = ^(NSString *code, NSString *message, NSError *error) { - @throw [NSException exceptionWithName:@"Promise Rejector should not be called." reason:nil userInfo:nil]; -}; +void (^expectRejecterNotCalled)(NSString *, NSString *, NSError *) + = ^(NSString *code, NSString *message, NSError *error) { + @throw [NSException exceptionWithName:@"Promise Rejector should not be called." + reason:nil + userInfo:nil]; + }; uint64_t MOCKED_SYMBOL_ADDRESS = 123; -char const* MOCKED_SYMBOL_NAME = "symbolicatedname"; +char const *MOCKED_SYMBOL_NAME = "symbolicatedname"; -int sucessfulSymbolicate(const void *, Dl_info *info){ - info->dli_saddr = (void *) MOCKED_SYMBOL_ADDRESS; - info->dli_sname = MOCKED_SYMBOL_NAME; - return 1; +int +sucessfulSymbolicate(const void *, Dl_info *info) +{ + info->dli_saddr = (void *)MOCKED_SYMBOL_ADDRESS; + info->dli_sname = MOCKED_SYMBOL_NAME; + return 1; } -- (void)prepareNativeFrameMocksWithLocalSymbolication: (BOOL) debug +- (void)prepareNativeFrameMocksWithLocalSymbolication:(BOOL)debug { - SentryOptions* sentryOptions = [[SentryOptions alloc] init]; - sentryOptions.debug = debug; //no local symbolication - - id sentrySDKMock = OCMClassMock([SentrySDK class]); - OCMStub([(SentrySDK*) sentrySDKMock options]).andReturn(sentryOptions); - - id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); - OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])).andReturn(sentryDependencyContainerMock); - - id sentryBinaryImageInfoMockOne = OCMClassMock([SentryBinaryImageInfo class]); - OCMStub([(SentryBinaryImageInfo*) sentryBinaryImageInfoMockOne address]).andReturn([@112233 unsignedLongLongValue]); - OCMStub([sentryBinaryImageInfoMockOne name]).andReturn(@"testnameone"); - - id sentryBinaryImageInfoMockTwo = OCMClassMock([SentryBinaryImageInfo class]); - OCMStub([(SentryBinaryImageInfo*) sentryBinaryImageInfoMockTwo address]).andReturn([@112233 unsignedLongLongValue]); - OCMStub([sentryBinaryImageInfoMockTwo name]).andReturn(@"testnametwo"); - - id sentryBinaryImageCacheMock = OCMClassMock([SentryBinaryImageCache class]); - OCMStub([(SentryDependencyContainer*) sentryDependencyContainerMock binaryImageCache]).andReturn(sentryBinaryImageCacheMock); - OCMStub([sentryBinaryImageCacheMock imageByAddress:[@123 unsignedLongLongValue]]).andReturn(sentryBinaryImageInfoMockOne); - OCMStub([sentryBinaryImageCacheMock imageByAddress:[@456 unsignedLongLongValue]]).andReturn(sentryBinaryImageInfoMockTwo); - - NSDictionary* serializedDebugImage = @{ - @"uuid": @"mockuuid", - @"debug_id": @"mockdebugid", - @"type": @"macho", - @"image_addr": @"0x000000000001b669", - }; - id sentryDebugImageMock = OCMClassMock([SentryDebugMeta class]); - OCMStub([sentryDebugImageMock serialize]).andReturn(serializedDebugImage); - - id sentryDebugImageProviderMock = OCMClassMock([SentryDebugImageProvider class]); - OCMStub([sentryDebugImageProviderMock getDebugImagesForAddresses:[NSSet setWithObject:@"0x000000000001b669"] isCrash:false]).andReturn(@[sentryDebugImageMock]); - - OCMStub([sentryDependencyContainerMock debugImageProvider]).andReturn(sentryDebugImageProviderMock); + SentryOptions *sentryOptions = [[SentryOptions alloc] init]; + sentryOptions.debug = debug; // no local symbolication + + id sentrySDKMock = OCMClassMock([SentrySDK class]); + OCMStub([(SentrySDK *)sentrySDKMock options]).andReturn(sentryOptions); + + id sentryDependencyContainerMock = OCMClassMock([SentryDependencyContainer class]); + OCMStub(ClassMethod([sentryDependencyContainerMock sharedInstance])) + .andReturn(sentryDependencyContainerMock); + + id sentryBinaryImageInfoMockOne = OCMClassMock([SentryBinaryImageInfo class]); + OCMStub([(SentryBinaryImageInfo *)sentryBinaryImageInfoMockOne address]) + .andReturn([@112233 unsignedLongLongValue]); + OCMStub([sentryBinaryImageInfoMockOne name]).andReturn(@"testnameone"); + + id sentryBinaryImageInfoMockTwo = OCMClassMock([SentryBinaryImageInfo class]); + OCMStub([(SentryBinaryImageInfo *)sentryBinaryImageInfoMockTwo address]) + .andReturn([@112233 unsignedLongLongValue]); + OCMStub([sentryBinaryImageInfoMockTwo name]).andReturn(@"testnametwo"); + + id sentryBinaryImageCacheMock = OCMClassMock([SentryBinaryImageCache class]); + OCMStub([(SentryDependencyContainer *)sentryDependencyContainerMock binaryImageCache]) + .andReturn(sentryBinaryImageCacheMock); + OCMStub([sentryBinaryImageCacheMock imageByAddress:[@123 unsignedLongLongValue]]) + .andReturn(sentryBinaryImageInfoMockOne); + OCMStub([sentryBinaryImageCacheMock imageByAddress:[@456 unsignedLongLongValue]]) + .andReturn(sentryBinaryImageInfoMockTwo); + + NSDictionary *serializedDebugImage = @{ + @"uuid" : @"mockuuid", + @"debug_id" : @"mockdebugid", + @"type" : @"macho", + @"image_addr" : @"0x000000000001b669", + }; + id sentryDebugImageMock = OCMClassMock([SentryDebugMeta class]); + OCMStub([sentryDebugImageMock serialize]).andReturn(serializedDebugImage); + + id sentryDebugImageProviderMock = OCMClassMock([SentryDebugImageProvider class]); + OCMStub([sentryDebugImageProviderMock + getDebugImagesForAddresses:[NSSet setWithObject:@"0x000000000001b669"] + isCrash:false]) + .andReturn(@[ sentryDebugImageMock ]); + + OCMStub([sentryDependencyContainerMock debugImageProvider]) + .andReturn(sentryDebugImageProviderMock); } - (void)testFetchNativeStackFramesByInstructionsServerSymbolication { - [self prepareNativeFrameMocksWithLocalSymbolication:NO]; - RNSentry* rnSentry = [[RNSentry alloc] init]; - NSDictionary* actual = [rnSentry fetchNativeStackFramesBy: @[@123, @456] - symbolicate: sucessfulSymbolicate]; - - NSDictionary* expected = @{ - @"debugMetaImages": @[ - @{ - @"uuid": @"mockuuid", - @"debug_id": @"mockdebugid", - @"type": @"macho", - @"image_addr": @"0x000000000001b669", - }, - ], - @"frames": @[ - @{ - @"package": @"testnameone", - @"in_app": @NO, - @"platform": @"cocoa", - @"instruction_addr": @"0x000000000000007b", //123 - @"image_addr": @"0x000000000001b669", //112233 - }, - @{ - @"package": @"testnametwo", - @"in_app": @NO, - @"platform": @"cocoa", - @"instruction_addr": @"0x00000000000001c8", //456 - @"image_addr": @"0x000000000001b669", //445566 - }, - ], - }; - XCTAssertTrue([actual isEqualToDictionary:expected]); + [self prepareNativeFrameMocksWithLocalSymbolication:NO]; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSDictionary *actual = [rnSentry fetchNativeStackFramesBy:@[ @123, @456 ] + symbolicate:sucessfulSymbolicate]; + + NSDictionary *expected = @{ + @"debugMetaImages" : @[ + @{ + @"uuid" : @"mockuuid", + @"debug_id" : @"mockdebugid", + @"type" : @"macho", + @"image_addr" : @"0x000000000001b669", + }, + ], + @"frames" : @[ + @{ + @"package" : @"testnameone", + @"in_app" : @NO, + @"platform" : @"cocoa", + @"instruction_addr" : @"0x000000000000007b", // 123 + @"image_addr" : @"0x000000000001b669", // 112233 + }, + @{ + @"package" : @"testnametwo", + @"in_app" : @NO, + @"platform" : @"cocoa", + @"instruction_addr" : @"0x00000000000001c8", // 456 + @"image_addr" : @"0x000000000001b669", // 445566 + }, + ], + }; + XCTAssertTrue([actual isEqualToDictionary:expected]); } - (void)testFetchNativeStackFramesByInstructionsOnDeviceSymbolication { - [self prepareNativeFrameMocksWithLocalSymbolication:YES]; - RNSentry* rnSentry = [[RNSentry alloc] init]; - NSDictionary* actual = [rnSentry fetchNativeStackFramesBy: @[@123, @456] - symbolicate: sucessfulSymbolicate]; - - NSDictionary* expected = @{ - @"frames": @[ - @{ - @"function": @"symbolicatedname", - @"package": @"testnameone", - @"in_app": @NO, - @"platform": @"cocoa", - @"symbol_addr": @"0x000000000000007b", //123 - @"instruction_addr": @"0x000000000000007b", //123 - @"image_addr": @"0x000000000001b669", //112233 - }, - @{ - @"function": @"symbolicatedname", - @"package": @"testnametwo", - @"in_app": @NO, - @"platform": @"cocoa", - @"symbol_addr": @"0x000000000000007b", //123 - @"instruction_addr": @"0x00000000000001c8", //456 - @"image_addr": @"0x000000000001b669", //445566 - }, - ], - }; - XCTAssertTrue([actual isEqualToDictionary:expected]); + [self prepareNativeFrameMocksWithLocalSymbolication:YES]; + RNSentry *rnSentry = [[RNSentry alloc] init]; + NSDictionary *actual = [rnSentry fetchNativeStackFramesBy:@[ @123, @456 ] + symbolicate:sucessfulSymbolicate]; + + NSDictionary *expected = @{ + @"frames" : @[ + @{ + @"function" : @"symbolicatedname", + @"package" : @"testnameone", + @"in_app" : @NO, + @"platform" : @"cocoa", + @"symbol_addr" : @"0x000000000000007b", // 123 + @"instruction_addr" : @"0x000000000000007b", // 123 + @"image_addr" : @"0x000000000001b669", // 112233 + }, + @{ + @"function" : @"symbolicatedname", + @"package" : @"testnametwo", + @"in_app" : @NO, + @"platform" : @"cocoa", + @"symbol_addr" : @"0x000000000000007b", // 123 + @"instruction_addr" : @"0x00000000000001c8", // 456 + @"image_addr" : @"0x000000000001b669", // 445566 + }, + ], + }; + XCTAssertTrue([actual isEqualToDictionary:expected]); } @end diff --git a/packages/core/ios/RNSentry.h b/packages/core/ios/RNSentry.h index 4b5233c985..06e1569a16 100644 --- a/packages/core/ios/RNSentry.h +++ b/packages/core/ios/RNSentry.h @@ -1,20 +1,23 @@ #if __has_include() -#import +# import #else -#import "RCTBridge.h" +# import "RCTBridge.h" #endif -#import #import +#import #import -#import #import +#import typedef int (*SymbolicateCallbackType)(const void *, Dl_info *); -@interface SentryDebugImageProvider () -- (NSArray * _Nonnull)getDebugImagesForAddresses:(NSSet * _Nonnull)addresses isCrash:(BOOL)isCrash; +@interface +SentryDebugImageProvider () +- (NSArray *_Nonnull)getDebugImagesForAddresses: + (NSSet *_Nonnull)addresses + isCrash:(BOOL)isCrash; @end @interface @@ -25,11 +28,11 @@ SentrySDK (Private) @interface RNSentry : RCTEventEmitter - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options - error:(NSError *_Nullable*_Nonnull)errorPointer; + error:(NSError *_Nullable *_Nonnull)errorPointer; -- (void) setEventOriginTag: (SentryEvent*) event; +- (void)setEventOriginTag:(SentryEvent *)event; -- (NSDictionary*_Nonnull) fetchNativeStackFramesBy: (NSArray*)instructionsAddr - symbolicate: (SymbolicateCallbackType) symbolicate; +- (NSDictionary *_Nonnull)fetchNativeStackFramesBy:(NSArray *)instructionsAddr + symbolicate:(SymbolicateCallbackType)symbolicate; @end diff --git a/packages/core/ios/RNSentry.mm b/packages/core/ios/RNSentry.mm index 98bb3e5ae8..7728a1b70a 100644 --- a/packages/core/ios/RNSentry.mm +++ b/packages/core/ios/RNSentry.mm @@ -1,54 +1,55 @@ -#import #import "RNSentry.h" #import "RNSentryTimeToDisplay.h" +#import #if __has_include() -#import +# import #else -#import "RCTConvert.h" +# import "RCTConvert.h" #endif #if __has_include() && SENTRY_PROFILING_SUPPORTED -#define SENTRY_PROFILING_ENABLED 1 -#import +# define SENTRY_PROFILING_ENABLED 1 +# import #else -#define SENTRY_PROFILING_ENABLED 0 -#define SENTRY_TARGET_PROFILING_SUPPORTED 0 +# define SENTRY_PROFILING_ENABLED 0 +# define SENTRY_TARGET_PROFILING_SUPPORTED 0 #endif +#import "RNSentryBreadcrumb.h" +#import "RNSentryId.h" #import -#import -#import +#import #import #import #import -#import -#import "RNSentryId.h" -#import "RNSentryBreadcrumb.h" +#import +#import // This guard prevents importing Hermes in JSC apps #if SENTRY_PROFILING_ENABLED -#import +# import #endif // Thanks to this guard, we won't import this header when we build for the old architecture. #ifdef RCT_NEW_ARCH_ENABLED -#import "RNSentrySpec.h" +# import "RNSentrySpec.h" #endif -#import "RNSentryEvents.h" #import "RNSentryDependencyContainer.h" +#import "RNSentryEvents.h" #if SENTRY_TARGET_REPLAY_SUPPORTED -#import "RNSentryReplay.h" +# import "RNSentryReplay.h" #endif #if SENTRY_HAS_UIKIT -#import "RNSentryRNSScreen.h" -#import "RNSentryFramesTrackerListener.h" +# import "RNSentryFramesTrackerListener.h" +# import "RNSentryRNSScreen.h" #endif -@interface SentrySDK (RNSentry) +@interface +SentrySDK (RNSentry) + (void)captureEnvelope:(SentryEnvelope *)envelope; @@ -58,7 +59,7 @@ + (void)storeEnvelope:(SentryEnvelope *)envelope; static bool hasFetchedAppStart; -static NSString* const nativeSdkName = @"sentry.cocoa.react-native"; +static NSString *const nativeSdkName = @"sentry.cocoa.react-native"; @implementation RNSentry { bool sentHybridSdkDidBecomeActive; @@ -71,39 +72,44 @@ - (dispatch_queue_t)methodQueue return dispatch_get_main_queue(); } -+ (BOOL)requiresMainQueueSetup { ++ (BOOL)requiresMainQueueSetup +{ return YES; } RCT_EXPORT_MODULE() -RCT_EXPORT_METHOD(initNativeSdk:(NSDictionary *_Nonnull)options - resolve:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(initNativeSdk + : (NSDictionary *_Nonnull)options resolve + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { NSError *error = nil; - SentryOptions* sentryOptions = [self createOptionsWithDictionary:options error:&error]; + SentryOptions *sentryOptions = [self createOptionsWithDictionary:options error:&error]; if (error != nil) { reject(@"SentryReactNative", error.localizedDescription, error); return; } NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString]; - [PrivateSentrySDKOnly setSdkName: nativeSdkName andVersionString: sdkVersion]; + [PrivateSentrySDKOnly setSdkName:nativeSdkName andVersionString:sdkVersion]; [SentrySDK startWithOptions:sentryOptions]; #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST - BOOL appIsActive = [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive; + 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]; + // 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; } @@ -116,13 +122,15 @@ + (BOOL)requiresMainQueueSetup { } - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options - error: (NSError *_Nonnull *_Nonnull) errorPointer + 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. + 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) { + [event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location + != NSNotFound) { return nil; } @@ -131,12 +139,12 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull) return event; }; - NSMutableDictionary * mutableOptions =[options mutableCopy]; + 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. + // 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"]; @@ -147,7 +155,8 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull) [RNSentryReplay updateOptions:mutableOptions]; #endif - SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions didFailWithError:errorPointer]; + SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:mutableOptions + didFailWithError:errorPointer]; if (*errorPointer != nil) { return nil; } @@ -161,7 +170,7 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull) sentryOptions.integrations = integrations; } } - + // Set spotlight option if ([mutableOptions valueForKey:@"spotlight"] != nil) { id spotlightValue = [mutableOptions valueForKey:@"spotlight"]; @@ -180,7 +189,8 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull) // Enable the App start and Frames tracking measurements if ([mutableOptions valueForKey:@"enableAutoPerformanceTracing"] != nil) { - BOOL enableAutoPerformanceTracing = [mutableOptions[@"enableAutoPerformanceTracing"] boolValue]; + BOOL enableAutoPerformanceTracing = + [mutableOptions[@"enableAutoPerformanceTracing"] boolValue]; PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = enableAutoPerformanceTracing; #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = enableAutoPerformanceTracing; @@ -190,46 +200,47 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull) return sentryOptions; } -- (void)setEventOriginTag:(SentryEvent *)event { - if (event.sdk != nil) { - NSString *sdkName = event.sdk[@"name"]; +- (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:nativeSdkName]) { - [self setEventEnvironmentTag:event origin:@"ios" environment:@"native"]; + // If the event is from react native, it gets set + // there and we do not handle it here. + if ([sdkName isEqual:nativeSdkName]) { + [self setEventEnvironmentTag:event origin:@"ios" environment:@"native"]; + } } - } } - (void)setEventEnvironmentTag:(SentryEvent *)event origin:(NSString *)origin - environment:(NSString *)environment { - NSMutableDictionary *newTags = [NSMutableDictionary new]; + 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"]; - } + 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; + event.tags = newTags; } -RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { #if SENTRY_HAS_UIKIT if ([[NSThread currentThread] isMainThread]) { [RNSentryRNSScreen swizzleViewDidAppear]; } else { - dispatch_async(dispatch_get_main_queue(), ^{ - [RNSentryRNSScreen swizzleViewDidAppear]; - }); + dispatch_async(dispatch_get_main_queue(), ^{ [RNSentryRNSScreen swizzleViewDidAppear]; }); } [self initFramesTracking]; @@ -237,48 +248,57 @@ - (void)setEventEnvironmentTag:(SentryEvent *)event resolve(nil); } -- (void)initFramesTracking { +- (void)initFramesTracking +{ #if SENTRY_HAS_UIKIT - RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) { - if (self->hasListeners) { - [self sendEventWithName:RNSentryNewFrameEvent body:@{ @"newFrameTimestampInSeconds": newFrameTimestampInSeconds }]; - } - }; - [[RNSentryDependencyContainer sharedInstance] initializeFramesTrackerListenerWith: emitNewFrameEvent]; + RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) { + if (self->hasListeners) { + [self + sendEventWithName:RNSentryNewFrameEvent + body:@{ @"newFrameTimestampInSeconds" : newFrameTimestampInSeconds }]; + } + }; + [[RNSentryDependencyContainer sharedInstance] + initializeFramesTrackerListenerWith:emitNewFrameEvent]; #endif } // Will be called when this module's first listener is added. --(void)startObserving { +- (void)startObserving +{ hasListeners = YES; } // Will be called when this module's last listener is removed, or on dealloc. --(void)stopObserving { +- (void)stopObserving +{ hasListeners = NO; } -- (NSArray *)supportedEvents { - return @[RNSentryNewFrameEvent]; +- (NSArray *)supportedEvents +{ + return @[ RNSentryNewFrameEvent ]; } -RCT_EXPORT_METHOD(fetchNativeSdkInfo:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchNativeSdkInfo + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { - resolve(@{ - @"name": PrivateSentrySDKOnly.getSdkName, - @"version": PrivateSentrySDKOnly.getSdkVersionString - }); + resolve(@ { + @"name" : PrivateSentrySDKOnly.getSdkName, + @"version" : PrivateSentrySDKOnly.getSdkVersionString + }); } -RCT_EXPORT_METHOD(fetchModules:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchModules + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { NSString *filePath = [[NSBundle mainBundle] pathForResource:@"modules" ofType:@"json"]; - NSString* modulesString = [NSString stringWithContentsOfFile:filePath - encoding:NSUTF8StringEncoding - error:nil]; + NSString *modulesString = [NSString stringWithContentsOfFile:filePath + encoding:NSUTF8StringEncoding + error:nil]; resolve(modulesString); } @@ -288,79 +308,90 @@ -(void)stopObserving { return packageName; } -- (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAddr - symbolicate: (SymbolicateCallbackType) symbolicate +- (NSDictionary *)fetchNativeStackFramesBy:(NSArray *)instructionsAddr + symbolicate:(SymbolicateCallbackType)symbolicate { - BOOL shouldSymbolicateLocally = [SentrySDK.options debug]; - NSString *appPackageName = [[NSBundle mainBundle] executablePath]; - - NSMutableSet * _Nonnull imagesAddrToRetrieveDebugMetaImages = [[NSMutableSet alloc] init]; - NSMutableArray *> * _Nonnull serializedFrames = [[NSMutableArray alloc] init]; - - for (NSNumber *addr in instructionsAddr) { - SentryBinaryImageInfo * _Nullable image = [[[SentryDependencyContainer sharedInstance] binaryImageCache] imageByAddress:[addr unsignedLongLongValue]]; - if (image != nil) { - NSString * imageAddr = sentry_formatHexAddressUInt64([image address]); - [imagesAddrToRetrieveDebugMetaImages addObject: imageAddr]; - - NSDictionary * _Nonnull nativeFrame = @{ - @"platform": @"cocoa", - @"instruction_addr": sentry_formatHexAddress(addr), - @"package": [image name], - @"image_addr": imageAddr, - @"in_app": [NSNumber numberWithBool:[appPackageName isEqualToString:[image name]]], - }; - - if (shouldSymbolicateLocally) { - Dl_info symbolsBuffer; - bool symbols_succeed = false; - symbols_succeed = symbolicate((void *) [addr unsignedLongLongValue], &symbolsBuffer) != 0; - if (symbols_succeed) { - NSMutableDictionary * _Nonnull symbolicated = nativeFrame.mutableCopy; - symbolicated[@"symbol_addr"] = sentry_formatHexAddressUInt64((uintptr_t)symbolsBuffer.dli_saddr); - symbolicated[@"function"] = [NSString stringWithCString:symbolsBuffer.dli_sname encoding:NSUTF8StringEncoding]; + BOOL shouldSymbolicateLocally = [SentrySDK.options debug]; + NSString *appPackageName = [[NSBundle mainBundle] executablePath]; + + NSMutableSet *_Nonnull imagesAddrToRetrieveDebugMetaImages = + [[NSMutableSet alloc] init]; + NSMutableArray *> *_Nonnull serializedFrames = + [[NSMutableArray alloc] init]; + + for (NSNumber *addr in instructionsAddr) { + SentryBinaryImageInfo *_Nullable image = [[[SentryDependencyContainer sharedInstance] + binaryImageCache] imageByAddress:[addr unsignedLongLongValue]]; + if (image != nil) { + NSString *imageAddr = sentry_formatHexAddressUInt64([image address]); + [imagesAddrToRetrieveDebugMetaImages addObject:imageAddr]; + + NSDictionary *_Nonnull nativeFrame = @{ + @"platform" : @"cocoa", + @"instruction_addr" : sentry_formatHexAddress(addr), + @"package" : [image name], + @"image_addr" : imageAddr, + @"in_app" : [NSNumber numberWithBool:[appPackageName isEqualToString:[image name]]], + }; + + if (shouldSymbolicateLocally) { + Dl_info symbolsBuffer; + bool symbols_succeed = false; + symbols_succeed + = symbolicate((void *)[addr unsignedLongLongValue], &symbolsBuffer) != 0; + if (symbols_succeed) { + NSMutableDictionary *_Nonnull symbolicated + = nativeFrame.mutableCopy; + symbolicated[@"symbol_addr"] + = sentry_formatHexAddressUInt64((uintptr_t)symbolsBuffer.dli_saddr); + symbolicated[@"function"] = [NSString stringWithCString:symbolsBuffer.dli_sname + encoding:NSUTF8StringEncoding]; + + nativeFrame = symbolicated; + } + } - nativeFrame = symbolicated; + [serializedFrames addObject:nativeFrame]; + } else { + [serializedFrames addObject:@{ + @"platform" : @"cocoa", + @"instruction_addr" : sentry_formatHexAddress(addr), + }]; } - } + } - [serializedFrames addObject:nativeFrame]; + if (shouldSymbolicateLocally) { + return @{ + @"frames" : serializedFrames, + }; } else { - [serializedFrames addObject: @{ - @"platform": @"cocoa", - @"instruction_addr": sentry_formatHexAddress(addr), - }]; - } - } + NSMutableArray *> *_Nonnull serializedDebugMetaImages = + [[NSMutableArray alloc] init]; - if (shouldSymbolicateLocally) { - return @{ - @"frames": serializedFrames, - }; - } else { - NSMutableArray *> * _Nonnull serializedDebugMetaImages = [[NSMutableArray alloc] init]; + NSArray *debugMetaImages = [[[SentryDependencyContainer sharedInstance] + debugImageProvider] getDebugImagesForAddresses:imagesAddrToRetrieveDebugMetaImages + isCrash:false]; - NSArray *debugMetaImages = [[[SentryDependencyContainer sharedInstance] debugImageProvider] getDebugImagesForAddresses:imagesAddrToRetrieveDebugMetaImages isCrash:false]; + for (SentryDebugMeta *debugImage in debugMetaImages) { + [serializedDebugMetaImages addObject:[debugImage serialize]]; + } - for (SentryDebugMeta *debugImage in debugMetaImages) { - [serializedDebugMetaImages addObject:[debugImage serialize]]; + return @{ + @"frames" : serializedFrames, + @"debugMetaImages" : serializedDebugMetaImages, + }; } - - return @{ - @"frames": serializedFrames, - @"debugMetaImages": serializedDebugMetaImages, - }; - } } -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy:(NSArray *)instructionsAddr) +RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy + : (NSArray *)instructionsAddr) { - return [self fetchNativeStackFramesBy:instructionsAddr - symbolicate:dladdr]; + return [self fetchNativeStackFramesBy:instructionsAddr symbolicate:dladdr]; } -RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchNativeDeviceContexts + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { if (PrivateSentrySDKOnly.options.debug) { NSLog(@"Bridge call to: deviceContexts"); @@ -368,36 +399,41 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd __block NSMutableDictionary *serializedScope; // Temp work around until sorted out this API in sentry-cocoa. // TODO: If the callback isnt' executed the promise wouldn't be resolved. - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { + [SentrySDK configureScope:^(SentryScope *_Nonnull scope) { serializedScope = [[scope serialize] mutableCopy]; - NSDictionary *user = [serializedScope valueForKey:@"user"]; + NSDictionary *user = [serializedScope valueForKey:@"user"]; if (user == nil) { - [serializedScope - setValue:@{ @"id": PrivateSentrySDKOnly.installationID } - forKey:@"user"]; + [serializedScope setValue:@ { @"id" : PrivateSentrySDKOnly.installationID } + forKey:@"user"]; } if (PrivateSentrySDKOnly.options.debug) { - NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope options:0 error:nil]; - NSString *debugContext = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSData *data = [NSJSONSerialization dataWithJSONObject:serializedScope + options:0 + error:nil]; + NSString *debugContext = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; NSLog(@"Contexts: %@", debugContext); } }]; NSDictionary *extraContext = [PrivateSentrySDKOnly getExtraContext]; - NSMutableDictionary *> *contexts = [serializedScope[@"context"] mutableCopy]; + NSMutableDictionary *> *contexts = + [serializedScope[@"context"] mutableCopy]; if (extraContext && [extraContext[@"device"] isKindOfClass:[NSDictionary class]]) { - NSMutableDictionary *> *deviceContext = [contexts[@"device"] mutableCopy]; - [deviceContext addEntriesFromDictionary:extraContext[@"device"]]; - [contexts setValue:deviceContext forKey:@"device"]; + NSMutableDictionary *> *deviceContext = + [contexts[@"device"] mutableCopy]; + [deviceContext addEntriesFromDictionary:extraContext[@"device"]]; + [contexts setValue:deviceContext forKey:@"device"]; } if (extraContext && [extraContext[@"app"] isKindOfClass:[NSDictionary class]]) { - NSMutableDictionary *> *appContext = [contexts[@"app"] mutableCopy]; - [appContext addEntriesFromDictionary:extraContext[@"app"]]; - [contexts setValue:appContext forKey:@"app"]; + NSMutableDictionary *> *appContext = + [contexts[@"app"] mutableCopy]; + [appContext addEntriesFromDictionary:extraContext[@"app"]]; + [contexts setValue:appContext forKey:@"app"]; } [serializedScope setValue:contexts forKey:@"contexts"]; @@ -405,18 +441,22 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd resolve(serializedScope); } -RCT_EXPORT_METHOD(fetchNativeAppStart:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchNativeAppStart + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { #if SENTRY_HAS_UIKIT - NSDictionary *measurements = [PrivateSentrySDKOnly appStartMeasurementWithSpans]; + NSDictionary *measurements = + [PrivateSentrySDKOnly appStartMeasurementWithSpans]; if (measurements == nil) { resolve(nil); return; } - NSMutableDictionary *mutableMeasurements = [[NSMutableDictionary alloc] initWithDictionary:measurements]; - [mutableMeasurements setValue:[NSNumber numberWithBool:hasFetchedAppStart] forKey:@"has_fetched"]; + NSMutableDictionary *mutableMeasurements = + [[NSMutableDictionary alloc] initWithDictionary:measurements]; + [mutableMeasurements setValue:[NSNumber numberWithBool:hasFetchedAppStart] + forKey:@"has_fetched"]; // This is always set to true, as we would only allow an app start fetch to only happen once // in the case of a JS bundle reload, we do not want it to be instrumented again. @@ -428,8 +468,9 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd #endif } -RCT_EXPORT_METHOD(fetchNativeFrames:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchNativeFrames + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST @@ -445,79 +486,82 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd NSNumber *frozen = [NSNumber numberWithLong:frames.frozen]; NSNumber *slow = [NSNumber numberWithLong:frames.slow]; - resolve(@{ - @"totalFrames": total, - @"frozenFrames": frozen, - @"slowFrames": slow, + resolve(@ { + @"totalFrames" : total, + @"frozenFrames" : frozen, + @"slowFrames" : slow, }); } else { - resolve(nil); + resolve(nil); } #else resolve(nil); #endif } -RCT_EXPORT_METHOD(fetchNativeRelease:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchNativeRelease + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; - resolve(@{ - @"id": infoDict[@"CFBundleIdentifier"], - @"version": infoDict[@"CFBundleShortVersionString"], - @"build": infoDict[@"CFBundleVersion"], - }); -} - -RCT_EXPORT_METHOD(captureEnvelope:(NSString * _Nonnull)rawBytes - options: (NSDictionary * _Nonnull)options - resolve:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) + resolve(@ { + @"id" : infoDict[@"CFBundleIdentifier"], + @"version" : infoDict[@"CFBundleShortVersionString"], + @"build" : infoDict[@"CFBundleVersion"], + }); +} + +RCT_EXPORT_METHOD(captureEnvelope + : (NSString *_Nonnull)rawBytes options + : (NSDictionary *_Nonnull)options resolve + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { NSData *data = [[NSData alloc] initWithBase64EncodedString:rawBytes options:0]; SentryEnvelope *envelope = [PrivateSentrySDKOnly envelopeWithData:data]; if (envelope == nil) { - reject(@"SentryReactNative",@"Failed to parse envelope from byte array.", nil); + reject(@"SentryReactNative", @"Failed to parse envelope from byte array.", nil); return; } - #if DEBUG +#if DEBUG + [PrivateSentrySDKOnly captureEnvelope:envelope]; +#else + if ([[options objectForKey:@"hardCrashed"] boolValue]) { + // Storing to disk happens asynchronously with captureEnvelope + [PrivateSentrySDKOnly storeEnvelope:envelope]; + } else { [PrivateSentrySDKOnly captureEnvelope:envelope]; - #else - if ([[options objectForKey:@"hardCrashed"] boolValue]) { - // Storing to disk happens asynchronously with captureEnvelope - [PrivateSentrySDKOnly storeEnvelope:envelope]; - } else { - [PrivateSentrySDKOnly captureEnvelope:envelope]; - } - #endif + } +#endif resolve(@YES); } -RCT_EXPORT_METHOD(captureScreenshot: (RCTPromiseResolveBlock)resolve - rejecter: (RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(captureScreenshot + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST - NSArray* rawScreenshots = [PrivateSentrySDKOnly captureScreenshots]; + NSArray *rawScreenshots = [PrivateSentrySDKOnly captureScreenshots]; NSMutableArray *screenshotsArray = [NSMutableArray arrayWithCapacity:[rawScreenshots count]]; int counter = 1; - for (NSData* raw in rawScreenshots) { + for (NSData *raw in rawScreenshots) { NSMutableArray *screenshot = [NSMutableArray arrayWithCapacity:raw.length]; - const char *bytes = (char*) [raw bytes]; + const char *bytes = (char *)[raw bytes]; for (int i = 0; i < [raw length]; i++) { [screenshot addObject:[[NSNumber alloc] initWithChar:bytes[i]]]; } - NSString* filename = @"screenshot.png"; + NSString *filename = @"screenshot.png"; if (counter > 1) { filename = [NSString stringWithFormat:@"screenshot-%d.png", counter]; } - [screenshotsArray addObject:@{ - @"data": screenshot, - @"contentType": @"image/png", - @"filename": filename, + [screenshotsArray addObject:@ { + @"data" : screenshot, + @"contentType" : @"image/png", + @"filename" : filename, }]; counter++; } @@ -528,14 +572,15 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd #endif } -RCT_EXPORT_METHOD(fetchViewHierarchy: (RCTPromiseResolveBlock)resolve - rejecter: (RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(fetchViewHierarchy + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { #if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST - NSData * rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy]; + NSData *rawViewHierarchy = [PrivateSentrySDKOnly captureViewHierarchy]; NSMutableArray *viewHierarchy = [NSMutableArray arrayWithCapacity:rawViewHierarchy.length]; - const char *bytes = (char*) [rawViewHierarchy bytes]; + const char *bytes = (char *)[rawViewHierarchy bytes]; for (int i = 0; i < [rawViewHierarchy length]; i++) { [viewHierarchy addObject:[[NSNumber alloc] initWithChar:bytes[i]]]; } @@ -546,16 +591,13 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd #endif } - -RCT_EXPORT_METHOD(setUser:(NSDictionary *)userKeys - otherUserKeys:(NSDictionary *)userDataKeys -) +RCT_EXPORT_METHOD(setUser : (NSDictionary *)userKeys otherUserKeys : (NSDictionary *)userDataKeys) { - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { + [SentrySDK configureScope:^(SentryScope *_Nonnull scope) { if (nil == userKeys && nil == userDataKeys) { [scope setUser:nil]; } else { - SentryUser* userInstance = [[SentryUser alloc] init]; + SentryUser *userInstance = [[SentryUser alloc] init]; if (nil != userKeys) { [userInstance setUserId:userKeys[@"id"]]; @@ -574,9 +616,9 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd }]; } -RCT_EXPORT_METHOD(addBreadcrumb:(NSDictionary *)breadcrumb) +RCT_EXPORT_METHOD(addBreadcrumb : (NSDictionary *)breadcrumb) { - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { + [SentrySDK configureScope:^(SentryScope *_Nonnull scope) { [scope addBreadcrumb:[RNSentryBreadcrumb from:breadcrumb]]; }]; @@ -585,33 +627,27 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd if (screen != nil) { [PrivateSentrySDKOnly setCurrentScreen:screen]; } -#endif //SENTRY_HAS_UIKIT +#endif // SENTRY_HAS_UIKIT } -RCT_EXPORT_METHOD(clearBreadcrumbs) { - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { - [scope clearBreadcrumbs]; - }]; +RCT_EXPORT_METHOD(clearBreadcrumbs) +{ + [SentrySDK configureScope:^(SentryScope *_Nonnull scope) { [scope clearBreadcrumbs]; }]; } -RCT_EXPORT_METHOD(setExtra:(NSString *)key - extra:(NSString *)extra -) +RCT_EXPORT_METHOD(setExtra : (NSString *)key extra : (NSString *)extra) { - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { - [scope setExtraValue:extra forKey:key]; - }]; + [SentrySDK + configureScope:^(SentryScope *_Nonnull scope) { [scope setExtraValue:extra forKey:key]; }]; } -RCT_EXPORT_METHOD(setContext:(NSString *)key - context:(NSDictionary *)context -) +RCT_EXPORT_METHOD(setContext : (NSString *)key context : (NSDictionary *)context) { if (key == nil) { return; } - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { + [SentrySDK configureScope:^(SentryScope *_Nonnull scope) { if (context == nil) { [scope removeContextForKey:key]; } else { @@ -620,25 +656,20 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd }]; } -RCT_EXPORT_METHOD(setTag:(NSString *)key - value:(NSString *)value -) +RCT_EXPORT_METHOD(setTag : (NSString *)key value : (NSString *)value) { - [SentrySDK configureScope:^(SentryScope * _Nonnull scope) { - [scope setTagValue:value forKey:key]; - }]; + [SentrySDK + configureScope:^(SentryScope *_Nonnull scope) { [scope setTagValue:value forKey:key]; }]; } -RCT_EXPORT_METHOD(crash) -{ - [SentrySDK crash]; -} +RCT_EXPORT_METHOD(crash) { [SentrySDK crash]; } -RCT_EXPORT_METHOD(closeNativeSdk:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(closeNativeSdk + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { - [SentrySDK close]; - resolve(@YES); + [SentrySDK close]; + resolve(@YES); } RCT_EXPORT_METHOD(disableNativeFramesTracking) @@ -654,70 +685,76 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd // the 'tracesSampleRate' or 'tracesSampler' option. } -RCT_EXPORT_METHOD(captureReplay: (BOOL)isHardCrash - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(captureReplay + : (BOOL)isHardCrash resolver + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { #if SENTRY_TARGET_REPLAY_SUPPORTED - [PrivateSentrySDKOnly captureReplay]; - resolve([PrivateSentrySDKOnly getReplayId]); + [PrivateSentrySDKOnly captureReplay]; + resolve([PrivateSentrySDKOnly getReplayId]); #else - resolve(nil); + resolve(nil); #endif } RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getCurrentReplayId) { #if SENTRY_TARGET_REPLAY_SUPPORTED - return [PrivateSentrySDKOnly getReplayId]; + return [PrivateSentrySDKOnly getReplayId]; #else - return nil; + return nil; #endif } -static NSString* const enabledProfilingMessage = @"Enable Hermes to use Sentry Profiling."; -static SentryId* nativeProfileTraceId = nil; +static NSString *const enabledProfilingMessage = @"Enable Hermes to use Sentry Profiling."; +static SentryId *nativeProfileTraceId = nil; static uint64_t nativeProfileStartTime = 0; -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling: (BOOL)platformProfilers) +RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, startProfiling : (BOOL)platformProfilers) { #if SENTRY_PROFILING_ENABLED try { facebook::hermes::HermesRuntime::enableSamplingProfiler(); if (nativeProfileTraceId == nil && nativeProfileStartTime == 0 && platformProfilers) { -#if SENTRY_TARGET_PROFILING_SUPPORTED +# if SENTRY_TARGET_PROFILING_SUPPORTED nativeProfileTraceId = [RNSentryId newId]; - nativeProfileStartTime = [PrivateSentrySDKOnly startProfilerForTrace: nativeProfileTraceId]; -#endif + nativeProfileStartTime = + [PrivateSentrySDKOnly startProfilerForTrace:nativeProfileTraceId]; +# endif } else { if (!platformProfilers) { NSLog(@"Native profiling is disabled. Only starting Hermes profiling."); } else { - NSLog(@"Native profiling already in progress. Currently existing trace: %@", nativeProfileTraceId); + NSLog(@"Native profiling already in progress. Currently existing trace: %@", + nativeProfileTraceId); } } - return @{ @"started": @YES }; - } catch (const std::exception& ex) { + return @{@"started" : @YES}; + } catch (const std::exception &ex) { if (nativeProfileTraceId != nil) { -#if SENTRY_TARGET_PROFILING_SUPPORTED - [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId]; -#endif +# if SENTRY_TARGET_PROFILING_SUPPORTED + [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId]; +# endif nativeProfileTraceId = nil; } nativeProfileStartTime = 0; - return @{ @"error": [NSString stringWithCString: ex.what() encoding:[NSString defaultCStringEncoding]] }; + return @ { + @"error" : [NSString stringWithCString:ex.what() + encoding:[NSString defaultCStringEncoding]] + }; } catch (...) { if (nativeProfileTraceId != nil) { -#if SENTRY_TARGET_PROFILING_SUPPORTED - [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId]; -#endif +# if SENTRY_TARGET_PROFILING_SUPPORTED + [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId]; +# endif nativeProfileTraceId = nil; } nativeProfileStartTime = 0; - return @{ @"error": @"Failed to start profiling" }; + return @ { @"error" : @"Failed to start profiling" }; } #else - return @{ @"error": enabledProfilingMessage }; + return @ { @"error" : enabledProfilingMessage }; #endif } @@ -725,12 +762,14 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd { #if SENTRY_PROFILING_ENABLED try { - NSDictionary * nativeProfile = nil; + NSDictionary *nativeProfile = nil; if (nativeProfileTraceId != nil && nativeProfileStartTime != 0) { -#if SENTRY_TARGET_PROFILING_SUPPORTED +# if SENTRY_TARGET_PROFILING_SUPPORTED uint64_t nativeProfileStopTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); - nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime and:nativeProfileStopTime forTrace:nativeProfileTraceId]; -#endif + nativeProfile = [PrivateSentrySDKOnly collectProfileBetween:nativeProfileStartTime + and:nativeProfileStopTime + forTrace:nativeProfileTraceId]; +# endif } // Cleanup native profiles nativeProfileTraceId = nil; @@ -742,57 +781,66 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd facebook::hermes::HermesRuntime::dumpSampledTraceToStream(ss); std::string s = ss.str(); - NSString *data = [NSString stringWithCString:s.c_str() encoding:[NSString defaultCStringEncoding]]; + NSString *data = [NSString stringWithCString:s.c_str() + encoding:[NSString defaultCStringEncoding]]; -#if SENTRY_PROFILING_DEBUG_ENABLED +# if SENTRY_PROFILING_DEBUG_ENABLED NSString *rawProfileFileName = @"hermes.profile"; NSError *error = nil; - NSString *rawProfileFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:rawProfileFileName]; - if (![data writeToFile:rawProfileFilePath atomically:YES encoding:NSUTF8StringEncoding error:&error]) { + NSString *rawProfileFilePath = + [NSTemporaryDirectory() stringByAppendingPathComponent:rawProfileFileName]; + if (![data writeToFile:rawProfileFilePath + atomically:YES + encoding:NSUTF8StringEncoding + error:&error]) { NSLog(@"Error writing Raw Hermes Profile to %@: %@", rawProfileFilePath, error); } else { NSLog(@"Raw Hermes Profile saved to %@", rawProfileFilePath); } -#endif +# endif if (data == nil) { - return @{ @"error": @"Failed to retrieve Hermes profile." }; + return @ { @"error" : @"Failed to retrieve Hermes profile." }; } if (nativeProfile == nil) { - return @{ @"profile": data }; + return @ { @"profile" : data }; } - return @{ - @"profile": data, - @"nativeProfile": nativeProfile, + return @ { + @"profile" : data, + @"nativeProfile" : nativeProfile, }; - } catch (const std::exception& ex) { + } catch (const std::exception &ex) { if (nativeProfileTraceId != nil) { -#if SENTRY_TARGET_PROFILING_SUPPORTED - [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId]; -#endif - nativeProfileTraceId = nil; +# if SENTRY_TARGET_PROFILING_SUPPORTED + [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId]; +# endif + nativeProfileTraceId = nil; } nativeProfileStartTime = 0; - return @{ @"error": [NSString stringWithCString: ex.what() encoding:[NSString defaultCStringEncoding]] }; + return @ { + @"error" : [NSString stringWithCString:ex.what() + encoding:[NSString defaultCStringEncoding]] + }; } catch (...) { if (nativeProfileTraceId != nil) { -#if SENTRY_TARGET_PROFILING_SUPPORTED - [PrivateSentrySDKOnly discardProfilerForTrace: nativeProfileTraceId]; -#endif - nativeProfileTraceId = nil; +# if SENTRY_TARGET_PROFILING_SUPPORTED + [PrivateSentrySDKOnly discardProfilerForTrace:nativeProfileTraceId]; +# endif + nativeProfileTraceId = nil; } nativeProfileStartTime = 0; - return @{ @"error": @"Failed to stop profiling" }; + return @ { @"error" : @"Failed to stop profiling" }; } #else - return @{ @"error": enabledProfilingMessage }; + return @ { @"error" : enabledProfilingMessage }; #endif } -RCT_EXPORT_METHOD(crashedLastRun:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(crashedLastRun + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { resolve(@([SentrySDK crashedLastRun])); } @@ -806,8 +854,10 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray*)instructionsAdd } #endif -RCT_EXPORT_METHOD(getNewScreenTimeToDisplay:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { +RCT_EXPORT_METHOD(getNewScreenTimeToDisplay + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) +{ [_timeToDisplay getTimeToDisplay:resolve]; } diff --git a/packages/core/ios/RNSentryBreadcrumb.h b/packages/core/ios/RNSentryBreadcrumb.h index 083670aefe..c7ee01dec9 100644 --- a/packages/core/ios/RNSentryBreadcrumb.h +++ b/packages/core/ios/RNSentryBreadcrumb.h @@ -6,8 +6,8 @@ @interface RNSentryBreadcrumb : NSObject -+ (SentryBreadcrumb *)from: (NSDictionary *) dict; ++ (SentryBreadcrumb *)from:(NSDictionary *)dict; -+ (NSString *_Nullable) getCurrentScreenFrom: (NSDictionary *) dict; ++ (NSString *_Nullable)getCurrentScreenFrom:(NSDictionary *)dict; @end diff --git a/packages/core/ios/RNSentryBreadcrumb.m b/packages/core/ios/RNSentryBreadcrumb.m index e900ba4833..c849b5a5f9 100644 --- a/packages/core/ios/RNSentryBreadcrumb.m +++ b/packages/core/ios/RNSentryBreadcrumb.m @@ -3,11 +3,11 @@ @implementation RNSentryBreadcrumb -+(SentryBreadcrumb*) from: (NSDictionary *) dict ++ (SentryBreadcrumb *)from:(NSDictionary *)dict { - SentryBreadcrumb* crumb = [[SentryBreadcrumb alloc] init]; + SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] init]; - NSString * levelString = dict[@"level"]; + NSString *levelString = dict[@"level"]; SentryLevel sentryLevel; if ([levelString isEqualToString:@"fatal"]) { sentryLevel = kSentryLevelFatal; @@ -30,13 +30,14 @@ +(SentryBreadcrumb*) from: (NSDictionary *) dict return crumb; } -+ (NSString *_Nullable) getCurrentScreenFrom: (NSDictionary *_Nonnull) dict { ++ (NSString *_Nullable)getCurrentScreenFrom:(NSDictionary *_Nonnull)dict +{ NSString *_Nullable maybeCategory = [dict valueForKey:@"category"]; if (![maybeCategory isEqualToString:@"navigation"]) { return nil; } - NSDictionary *_Nullable maybeData = [dict valueForKey:@"data"]; + NSDictionary *_Nullable maybeData = [dict valueForKey:@"data"]; if (![maybeData isKindOfClass:[NSDictionary class]]) { return nil; } @@ -45,7 +46,7 @@ + (NSString *_Nullable) getCurrentScreenFrom: (NSDictionary *_Non if (![maybeCurrentScreen isKindOfClass:[NSString class]]) { return nil; } - + return maybeCurrentScreen; } diff --git a/packages/core/ios/RNSentryDependencyContainer.h b/packages/core/ios/RNSentryDependencyContainer.h index ad5b72e4a2..cd3eca59c7 100644 --- a/packages/core/ios/RNSentryDependencyContainer.h +++ b/packages/core/ios/RNSentryDependencyContainer.h @@ -5,13 +5,13 @@ @interface RNSentryDependencyContainer : NSObject SENTRY_NO_INIT -@property (class, readonly, strong) RNSentryDependencyContainer* sharedInstance; +@property (class, readonly, strong) RNSentryDependencyContainer *sharedInstance; #if SENTRY_HAS_UIKIT @property (nonatomic, strong) RNSentryFramesTrackerListener *framesTrackerListener; -- (void)initializeFramesTrackerListenerWith:(RNSentryEmitNewFrameEvent) eventEmitter; +- (void)initializeFramesTrackerListenerWith:(RNSentryEmitNewFrameEvent)eventEmitter; #endif diff --git a/packages/core/ios/RNSentryDependencyContainer.m b/packages/core/ios/RNSentryDependencyContainer.m index a1e703f87b..e91cac7f81 100644 --- a/packages/core/ios/RNSentryDependencyContainer.m +++ b/packages/core/ios/RNSentryDependencyContainer.m @@ -2,8 +2,8 @@ #import @implementation RNSentryDependencyContainer { - NSObject *sentryDependencyContainerLock; - } + NSObject *sentryDependencyContainerLock; +} + (instancetype)sharedInstance { @@ -25,10 +25,11 @@ - (instancetype)init - (void)initializeFramesTrackerListenerWith:(RNSentryEmitNewFrameEvent)eventEmitter { - @synchronized(sentryDependencyContainerLock) { - _framesTrackerListener = [[RNSentryFramesTrackerListener alloc] initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] - andEventEmitter: eventEmitter]; - } + @synchronized(sentryDependencyContainerLock) { + _framesTrackerListener = [[RNSentryFramesTrackerListener alloc] + initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] + andEventEmitter:eventEmitter]; + } } #endif diff --git a/packages/core/ios/RNSentryFramesTrackerListener.h b/packages/core/ios/RNSentryFramesTrackerListener.h index c554fd00df..e0de09dfd9 100644 --- a/packages/core/ios/RNSentryFramesTrackerListener.h +++ b/packages/core/ios/RNSentryFramesTrackerListener.h @@ -2,18 +2,18 @@ #if SENTRY_HAS_UIKIT -#import -#import -#import +# import +# import +# import typedef void (^RNSentryEmitNewFrameEvent)(NSNumber *newFrameTimestampInSeconds); @interface RNSentryFramesTrackerListener : NSObject -- (instancetype)initWithSentryFramesTracker:(SentryFramesTracker *) framesTracker - andEventEmitter:(RNSentryEmitNewFrameEvent) emitNewFrameEvent; +- (instancetype)initWithSentryFramesTracker:(SentryFramesTracker *)framesTracker + andEventEmitter:(RNSentryEmitNewFrameEvent)emitNewFrameEvent; -- (void) startListening; +- (void)startListening; @property (strong, nonatomic) SentryFramesTracker *framesTracker; @property (strong, nonatomic) RNSentryEmitNewFrameEvent emitNewFrameEvent; diff --git a/packages/core/ios/RNSentryFramesTrackerListener.m b/packages/core/ios/RNSentryFramesTrackerListener.m index 24de9ffb92..4a3c7d99cd 100644 --- a/packages/core/ios/RNSentryFramesTrackerListener.m +++ b/packages/core/ios/RNSentryFramesTrackerListener.m @@ -5,7 +5,7 @@ @implementation RNSentryFramesTrackerListener - (instancetype)initWithSentryFramesTracker:(SentryFramesTracker *)framesTracker - andEventEmitter:(RNSentryEmitNewFrameEvent) emitNewFrameEvent; + andEventEmitter:(RNSentryEmitNewFrameEvent)emitNewFrameEvent; { self = [super init]; if (self) { @@ -17,16 +17,18 @@ - (instancetype)initWithSentryFramesTracker:(SentryFramesTracker *)framesTracker - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate { - [_framesTracker removeListener:self]; - NSNumber *newFrameTimestampInSeconds = [NSNumber numberWithDouble:[newFrameDate timeIntervalSince1970]]; + [_framesTracker removeListener:self]; + NSNumber *newFrameTimestampInSeconds = + [NSNumber numberWithDouble:[newFrameDate timeIntervalSince1970]]; - if (_emitNewFrameEvent) { - _emitNewFrameEvent(newFrameTimestampInSeconds); - } + if (_emitNewFrameEvent) { + _emitNewFrameEvent(newFrameTimestampInSeconds); + } } -- (void)startListening { - [_framesTracker addListener:self]; +- (void)startListening +{ + [_framesTracker addListener:self]; } @end diff --git a/packages/core/ios/RNSentryId.m b/packages/core/ios/RNSentryId.m index bbb832aaff..7618c60893 100644 --- a/packages/core/ios/RNSentryId.m +++ b/packages/core/ios/RNSentryId.m @@ -3,7 +3,8 @@ @implementation RNSentryId -+ (SentryId *)newId { ++ (SentryId *)newId +{ return [[SentryId alloc] init]; } diff --git a/packages/core/ios/RNSentryOnDrawReporter.h b/packages/core/ios/RNSentryOnDrawReporter.h index 5a2585dc96..1cf9fb6245 100644 --- a/packages/core/ios/RNSentryOnDrawReporter.h +++ b/packages/core/ios/RNSentryOnDrawReporter.h @@ -2,9 +2,9 @@ #if SENTRY_HAS_UIKIT -#import -#import -#import "RNSentryFramesTrackerListener.h" +# import "RNSentryFramesTrackerListener.h" +# import +# import @interface RNSentryOnDrawReporter : RCTViewManager @@ -12,11 +12,11 @@ @interface RNSentryOnDrawReporterView : UIView -@property (nonatomic, strong) RNSentryFramesTrackerListener* framesListener; +@property (nonatomic, strong) RNSentryFramesTrackerListener *framesListener; @property (nonatomic, copy) RCTBubblingEventBlock onDrawNextFrame; @property (nonatomic) bool fullDisplay; @property (nonatomic) bool initialDisplay; -@property (nonatomic, weak) RNSentryOnDrawReporter* delegate; +@property (nonatomic, weak) RNSentryOnDrawReporter *delegate; @end diff --git a/packages/core/ios/RNSentryOnDrawReporter.m b/packages/core/ios/RNSentryOnDrawReporter.m index b6f4cabfdc..d8266c73a5 100644 --- a/packages/core/ios/RNSentryOnDrawReporter.m +++ b/packages/core/ios/RNSentryOnDrawReporter.m @@ -2,7 +2,7 @@ #if SENTRY_HAS_UIKIT -#import +# import @implementation RNSentryOnDrawReporter @@ -13,45 +13,47 @@ @implementation RNSentryOnDrawReporter - (UIView *)view { - RNSentryOnDrawReporterView* view = [[RNSentryOnDrawReporterView alloc] init]; - return view; + RNSentryOnDrawReporterView *view = [[RNSentryOnDrawReporterView alloc] init]; + return view; } @end @implementation RNSentryOnDrawReporterView -- (instancetype)init { +- (instancetype)init +{ self = [super init]; if (self) { RNSentryEmitNewFrameEvent emitNewFrameEvent = ^(NSNumber *newFrameTimestampInSeconds) { - if (self->_fullDisplay) { - self.onDrawNextFrame(@{ - @"newFrameTimestampInSeconds": newFrameTimestampInSeconds, - @"type": @"fullDisplay" - }); - return; - } - - if (self->_initialDisplay) { - self.onDrawNextFrame(@{ - @"newFrameTimestampInSeconds": newFrameTimestampInSeconds, - @"type": @"initialDisplay" - }); - return; - } + if (self->_fullDisplay) { + self.onDrawNextFrame(@{ + @"newFrameTimestampInSeconds" : newFrameTimestampInSeconds, + @"type" : @"fullDisplay" + }); + return; + } + + if (self->_initialDisplay) { + self.onDrawNextFrame(@{ + @"newFrameTimestampInSeconds" : newFrameTimestampInSeconds, + @"type" : @"initialDisplay" + }); + return; + } }; - _framesListener = [[RNSentryFramesTrackerListener alloc] initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] - andEventEmitter:emitNewFrameEvent]; + _framesListener = [[RNSentryFramesTrackerListener alloc] + initWithSentryFramesTracker:[[SentryDependencyContainer sharedInstance] framesTracker] + andEventEmitter:emitNewFrameEvent]; } return self; } - (void)didSetProps:(NSArray *)changedProps { - if (_fullDisplay || _initialDisplay) { - [_framesListener startListening]; - } + if (_fullDisplay || _initialDisplay) { + [_framesListener startListening]; + } } @end diff --git a/packages/core/ios/RNSentryRNSScreen.h b/packages/core/ios/RNSentryRNSScreen.h index 53f72fa5b2..dfc2f7281b 100644 --- a/packages/core/ios/RNSentryRNSScreen.h +++ b/packages/core/ios/RNSentryRNSScreen.h @@ -2,7 +2,7 @@ #if SENTRY_HAS_UIKIT -#import +# import @interface RNSentryRNSScreen : NSObject diff --git a/packages/core/ios/RNSentryRNSScreen.m b/packages/core/ios/RNSentryRNSScreen.m index daa4569cf4..20c42ab4c4 100644 --- a/packages/core/ios/RNSentryRNSScreen.m +++ b/packages/core/ios/RNSentryRNSScreen.m @@ -2,28 +2,28 @@ #if SENTRY_HAS_UIKIT -#import -#import -#import +# import +# import +# import -#import "RNSentryDependencyContainer.h" +# import "RNSentryDependencyContainer.h" @implementation RNSentryRNSScreen -+ (void)swizzleViewDidAppear { - Class rnsscreenclass = NSClassFromString(@"RNSScreen"); - if (rnsscreenclass == nil) - { - return; - } - - SEL selector = NSSelectorFromString(@"viewDidAppear:"); - SentrySwizzleInstanceMethod(rnsscreenclass, selector, SentrySWReturnType(void), - SentrySWArguments(BOOL animated), SentrySWReplacement({ - [[[RNSentryDependencyContainer sharedInstance] framesTrackerListener] startListening]; - SentrySWCallOriginal(animated); - }), - SentrySwizzleModeOncePerClass, (void *)selector); ++ (void)swizzleViewDidAppear +{ + Class rnsscreenclass = NSClassFromString(@"RNSScreen"); + if (rnsscreenclass == nil) { + return; + } + + SEL selector = NSSelectorFromString(@"viewDidAppear:"); + SentrySwizzleInstanceMethod(rnsscreenclass, selector, SentrySWReturnType(void), + SentrySWArguments(BOOL animated), SentrySWReplacement({ + [[[RNSentryDependencyContainer sharedInstance] framesTrackerListener] startListening]; + SentrySWCallOriginal(animated); + }), + SentrySwizzleModeOncePerClass, (void *)selector); } @end diff --git a/packages/core/ios/RNSentryReplay.m b/packages/core/ios/RNSentryReplay.m index de6a0c240e..9ef2c4efc0 100644 --- a/packages/core/ios/RNSentryReplay.m +++ b/packages/core/ios/RNSentryReplay.m @@ -6,70 +6,71 @@ @implementation RNSentryReplay { } -+ (void)updateOptions:(NSMutableDictionary *)options { - NSDictionary *experiments = options[@"_experiments"]; - [options removeObjectForKey:@"_experiments"]; - if (experiments == nil) { - NSLog(@"Session replay disabled via configuration"); - return; - } ++ (void)updateOptions:(NSMutableDictionary *)options +{ + NSDictionary *experiments = options[@"_experiments"]; + [options removeObjectForKey:@"_experiments"]; + if (experiments == nil) { + NSLog(@"Session replay disabled via configuration"); + return; + } - if (experiments[@"replaysSessionSampleRate"] == nil && - experiments[@"replaysOnErrorSampleRate"] == nil) { - NSLog(@"Session replay disabled via configuration"); - return; - } + if (experiments[@"replaysSessionSampleRate"] == nil + && experiments[@"replaysOnErrorSampleRate"] == nil) { + NSLog(@"Session replay disabled via configuration"); + return; + } - NSLog(@"Setting up session replay"); - NSDictionary *replayOptions = options[@"mobileReplayOptions"] ?: @{}; + NSLog(@"Setting up session replay"); + NSDictionary *replayOptions = options[@"mobileReplayOptions"] ?: @{}; - [options setValue:@{ - @"sessionReplay" : @{ - @"sessionSampleRate" : experiments[@"replaysSessionSampleRate"] - ?: [NSNull null], - @"errorSampleRate" : experiments[@"replaysOnErrorSampleRate"] - ?: [NSNull null], - @"redactAllImages" : replayOptions[@"maskAllImages"] ?: [NSNull null], - @"redactAllText" : replayOptions[@"maskAllText"] ?: [NSNull null], + [options setValue:@{ + @"sessionReplay" : @ { + @"sessionSampleRate" : experiments[@"replaysSessionSampleRate"] ?: [NSNull null], + @"errorSampleRate" : experiments[@"replaysOnErrorSampleRate"] ?: [NSNull null], + @"redactAllImages" : replayOptions[@"maskAllImages"] ?: [NSNull null], + @"redactAllText" : replayOptions[@"maskAllText"] ?: [NSNull null], + } } - } - forKey:@"experimental"]; + forKey:@"experimental"]; - [RNSentryReplay addReplayRNRedactClasses:replayOptions]; + [RNSentryReplay addReplayRNRedactClasses:replayOptions]; } -+ (void)addReplayRNRedactClasses:(NSDictionary *_Nullable)replayOptions { - NSMutableArray *_Nonnull classesToRedact = [[NSMutableArray alloc] init]; - if ([replayOptions[@"maskAllVectors"] boolValue] == YES) { - Class _Nullable maybeRNSVGViewClass = NSClassFromString(@"RNSVGSvgView"); - if (maybeRNSVGViewClass != nil) { - [classesToRedact addObject:maybeRNSVGViewClass]; - } - } - if ([replayOptions[@"maskAllImages"] boolValue] == YES) { - Class _Nullable maybeRCTImageClass = NSClassFromString(@"RCTImageView"); - if (maybeRCTImageClass != nil) { - [classesToRedact addObject:maybeRCTImageClass]; ++ (void)addReplayRNRedactClasses:(NSDictionary *_Nullable)replayOptions +{ + NSMutableArray *_Nonnull classesToRedact = [[NSMutableArray alloc] init]; + if ([replayOptions[@"maskAllVectors"] boolValue] == YES) { + Class _Nullable maybeRNSVGViewClass = NSClassFromString(@"RNSVGSvgView"); + if (maybeRNSVGViewClass != nil) { + [classesToRedact addObject:maybeRNSVGViewClass]; + } } - } - if ([replayOptions[@"maskAllText"] boolValue] == YES) { - Class _Nullable maybeRCTTextClass = NSClassFromString(@"RCTTextView"); - if (maybeRCTTextClass != nil) { - [classesToRedact addObject:maybeRCTTextClass]; + if ([replayOptions[@"maskAllImages"] boolValue] == YES) { + Class _Nullable maybeRCTImageClass = NSClassFromString(@"RCTImageView"); + if (maybeRCTImageClass != nil) { + [classesToRedact addObject:maybeRCTImageClass]; + } } - Class _Nullable maybeRCTParagraphComponentViewClass = NSClassFromString(@"RCTParagraphComponentView"); - if (maybeRCTParagraphComponentViewClass != nil) { - [classesToRedact addObject:maybeRCTParagraphComponentViewClass]; + if ([replayOptions[@"maskAllText"] boolValue] == YES) { + Class _Nullable maybeRCTTextClass = NSClassFromString(@"RCTTextView"); + if (maybeRCTTextClass != nil) { + [classesToRedact addObject:maybeRCTTextClass]; + } + Class _Nullable maybeRCTParagraphComponentViewClass + = NSClassFromString(@"RCTParagraphComponentView"); + if (maybeRCTParagraphComponentViewClass != nil) { + [classesToRedact addObject:maybeRCTParagraphComponentViewClass]; + } } - } - [PrivateSentrySDKOnly addReplayRedactClasses:classesToRedact]; + [PrivateSentrySDKOnly addReplayRedactClasses:classesToRedact]; } -+ (void)postInit { - RNSentryReplayBreadcrumbConverter *breadcrumbConverter = - [[RNSentryReplayBreadcrumbConverter alloc] init]; - [PrivateSentrySDKOnly configureSessionReplayWith:breadcrumbConverter - screenshotProvider:nil]; ++ (void)postInit +{ + RNSentryReplayBreadcrumbConverter *breadcrumbConverter = + [[RNSentryReplayBreadcrumbConverter alloc] init]; + [PrivateSentrySDKOnly configureSessionReplayWith:breadcrumbConverter screenshotProvider:nil]; } @end diff --git a/packages/core/ios/RNSentryReplayBreadcrumbConverter.h b/packages/core/ios/RNSentryReplayBreadcrumbConverter.h index ce12fcf39c..2eee190e26 100644 --- a/packages/core/ios/RNSentryReplayBreadcrumbConverter.h +++ b/packages/core/ios/RNSentryReplayBreadcrumbConverter.h @@ -3,14 +3,13 @@ #if SENTRY_TARGET_REPLAY_SUPPORTED @class SentryRRWebEvent; -@interface RNSentryReplayBreadcrumbConverter - : NSObject +@interface RNSentryReplayBreadcrumbConverter : NSObject - (instancetype _Nonnull)init; -+ (NSString* _Nullable) getTouchPathMessageFrom:(NSArray* _Nullable) path; ++ (NSString *_Nullable)getTouchPathMessageFrom:(NSArray *_Nullable)path; -- (id _Nullable)convertFrom:(SentryBreadcrumb *_Nonnull) breadcrumb; +- (id _Nullable)convertFrom:(SentryBreadcrumb *_Nonnull)breadcrumb; @end #endif diff --git a/packages/core/ios/RNSentryReplayBreadcrumbConverter.m b/packages/core/ios/RNSentryReplayBreadcrumbConverter.m index 251ada8903..14dfdc32a0 100644 --- a/packages/core/ios/RNSentryReplayBreadcrumbConverter.m +++ b/packages/core/ios/RNSentryReplayBreadcrumbConverter.m @@ -5,162 +5,169 @@ #if SENTRY_TARGET_REPLAY_SUPPORTED @implementation RNSentryReplayBreadcrumbConverter { - SentrySRDefaultBreadcrumbConverter *defaultConverter; + SentrySRDefaultBreadcrumbConverter *defaultConverter; } -- (instancetype _Nonnull)init { - if (self = [super init]) { - self->defaultConverter = - [SentrySessionReplayIntegration createDefaultBreadcrumbConverter]; - } - return self; +- (instancetype _Nonnull)init +{ + if (self = [super init]) { + self->defaultConverter = [SentrySessionReplayIntegration createDefaultBreadcrumbConverter]; + } + return self; } -- (id _Nullable)convertFrom: - (SentryBreadcrumb *_Nonnull)breadcrumb { - assert(breadcrumb.timestamp != nil); +- (id _Nullable)convertFrom:(SentryBreadcrumb *_Nonnull)breadcrumb +{ + assert(breadcrumb.timestamp != nil); - if ([breadcrumb.category isEqualToString:@"sentry.event"] || - [breadcrumb.category isEqualToString:@"sentry.transaction"]) { - // Do not add Sentry Event breadcrumbs to replay - return nil; - } + if ([breadcrumb.category isEqualToString:@"sentry.event"] || + [breadcrumb.category isEqualToString:@"sentry.transaction"]) { + // Do not add Sentry Event breadcrumbs to replay + return nil; + } - if ([breadcrumb.category isEqualToString:@"http"]) { - // Drop native network breadcrumbs to avoid duplicates - return nil; - } + if ([breadcrumb.category isEqualToString:@"http"]) { + // Drop native network breadcrumbs to avoid duplicates + return nil; + } - if ([breadcrumb.category isEqualToString:@"touch"]) { - return [self convertTouch:breadcrumb]; - } + if ([breadcrumb.category isEqualToString:@"touch"]) { + return [self convertTouch:breadcrumb]; + } - if ([breadcrumb.category isEqualToString:@"navigation"]) { - return [SentrySessionReplayIntegration - createBreadcrumbwithTimestamp:breadcrumb.timestamp - category:breadcrumb.category - message:nil - level:breadcrumb.level - data:breadcrumb.data]; - } - - if ([breadcrumb.category isEqualToString:@"xhr"]) { - return [self convertNavigation:breadcrumb]; - } - - SentryRRWebEvent *nativeBreadcrumb = - [self->defaultConverter convertFrom:breadcrumb]; - - // ignore native navigation breadcrumbs - if (nativeBreadcrumb && nativeBreadcrumb.data && - nativeBreadcrumb.data[@"payload"] && - nativeBreadcrumb.data[@"payload"][@"category"] && - [nativeBreadcrumb.data[@"payload"][@"category"] - isEqualToString:@"navigation"]) { - return nil; - } - - return nativeBreadcrumb; -} + if ([breadcrumb.category isEqualToString:@"navigation"]) { + return [SentrySessionReplayIntegration createBreadcrumbwithTimestamp:breadcrumb.timestamp + category:breadcrumb.category + message:nil + level:breadcrumb.level + data:breadcrumb.data]; + } -- (id _Nullable) convertTouch:(SentryBreadcrumb *_Nonnull)breadcrumb { - if (breadcrumb.data == nil) { - return nil; - } + if ([breadcrumb.category isEqualToString:@"xhr"]) { + return [self convertNavigation:breadcrumb]; + } - NSMutableArray *path = [breadcrumb.data valueForKey:@"path"]; - NSString* message = [RNSentryReplayBreadcrumbConverter getTouchPathMessageFrom:path]; + SentryRRWebEvent *nativeBreadcrumb = [self->defaultConverter convertFrom:breadcrumb]; - return [SentrySessionReplayIntegration - createBreadcrumbwithTimestamp:breadcrumb.timestamp - category:@"ui.tap" - message:message - level:breadcrumb.level - data:breadcrumb.data]; + // ignore native navigation breadcrumbs + if (nativeBreadcrumb && nativeBreadcrumb.data && nativeBreadcrumb.data[@"payload"] + && nativeBreadcrumb.data[@"payload"][@"category"] && + [nativeBreadcrumb.data[@"payload"][@"category"] isEqualToString:@"navigation"]) { + return nil; + } + + return nativeBreadcrumb; } -+ (NSString* _Nullable) getTouchPathMessageFrom:(NSArray* _Nullable) path { - if (path == nil) { - return nil; - } +- (id _Nullable)convertTouch:(SentryBreadcrumb *_Nonnull)breadcrumb +{ + if (breadcrumb.data == nil) { + return nil; + } + + NSMutableArray *path = [breadcrumb.data valueForKey:@"path"]; + NSString *message = [RNSentryReplayBreadcrumbConverter getTouchPathMessageFrom:path]; - NSInteger pathCount = [path count]; - if (pathCount <= 0) { - return nil; - } + return [SentrySessionReplayIntegration createBreadcrumbwithTimestamp:breadcrumb.timestamp + category:@"ui.tap" + message:message + level:breadcrumb.level + data:breadcrumb.data]; +} - NSMutableString *message = [[NSMutableString alloc] init]; - for (NSInteger i = MIN(3, pathCount - 1); i >= 0; i--) { - NSDictionary *item = [path objectAtIndex:i]; - if (item == nil) { - return nil; // There should be no nil (undefined) from JS, but to be safe we check it here ++ (NSString *_Nullable)getTouchPathMessageFrom:(NSArray *_Nullable)path +{ + if (path == nil) { + return nil; } - id name = [item objectForKey:@"name"]; - id label = [item objectForKey:@"label"]; - BOOL hasName = [name isKindOfClass:[NSString class]]; - BOOL hasLabel = [label isKindOfClass:[NSString class]]; - if (!hasName && !hasLabel) { - return nil; // This again should never be allowed in JS, but to be safe we check it here - } - if (hasLabel) { - [message appendString:(NSString *)label]; - } else if (hasName) { - [message appendString:(NSString *)name]; + NSInteger pathCount = [path count]; + if (pathCount <= 0) { + return nil; } - id element = [item objectForKey:@"element"]; - id file = [item objectForKey:@"file"]; - BOOL hasElement = [element isKindOfClass:[NSString class]]; - BOOL hasFile = [file isKindOfClass:[NSString class]]; - if (hasElement && hasFile) { - [message appendFormat:@"(%@, %@)", (NSString *)element, (NSString *)file]; - } else if (hasElement) { - [message appendFormat:@"(%@)", (NSString *)element]; - } else if (hasFile) { - [message appendFormat:@"(%@)", (NSString *)file]; + NSMutableString *message = [[NSMutableString alloc] init]; + for (NSInteger i = MIN(3, pathCount - 1); i >= 0; i--) { + NSDictionary *item = [path objectAtIndex:i]; + if (item == nil) { + return nil; // There should be no nil (undefined) from JS, but to be safe we check it + // here + } + + id name = [item objectForKey:@"name"]; + id label = [item objectForKey:@"label"]; + BOOL hasName = [name isKindOfClass:[NSString class]]; + BOOL hasLabel = [label isKindOfClass:[NSString class]]; + if (!hasName && !hasLabel) { + return nil; // This again should never be allowed in JS, but to be safe we check it here + } + if (hasLabel) { + [message appendString:(NSString *)label]; + } else if (hasName) { + [message appendString:(NSString *)name]; + } + + id element = [item objectForKey:@"element"]; + id file = [item objectForKey:@"file"]; + BOOL hasElement = [element isKindOfClass:[NSString class]]; + BOOL hasFile = [file isKindOfClass:[NSString class]]; + if (hasElement && hasFile) { + [message appendFormat:@"(%@, %@)", (NSString *)element, (NSString *)file]; + } else if (hasElement) { + [message appendFormat:@"(%@)", (NSString *)element]; + } else if (hasFile) { + [message appendFormat:@"(%@)", (NSString *)file]; + } + + if (i > 0) { + [message appendString:@" > "]; + } } - if (i > 0) { - [message appendString:@" > "]; + return message; +} + +- (id _Nullable)convertNavigation:(SentryBreadcrumb *_Nonnull)breadcrumb +{ + NSNumber *startTimestamp = [breadcrumb.data[@"start_timestamp"] isKindOfClass:[NSNumber class]] + ? breadcrumb.data[@"start_timestamp"] + : nil; + NSNumber *endTimestamp = [breadcrumb.data[@"end_timestamp"] isKindOfClass:[NSNumber class]] + ? breadcrumb.data[@"end_timestamp"] + : nil; + NSString *url = + [breadcrumb.data[@"url"] isKindOfClass:[NSString class]] ? breadcrumb.data[@"url"] : nil; + + if (startTimestamp == nil || endTimestamp == nil || url == nil) { + return nil; } - } - return message; -} + NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; + if ([breadcrumb.data[@"method"] isKindOfClass:[NSString class]]) { + data[@"method"] = breadcrumb.data[@"method"]; + } + if ([breadcrumb.data[@"status_code"] isKindOfClass:[NSNumber class]]) { + data[@"statusCode"] = breadcrumb.data[@"status_code"]; + } + if ([breadcrumb.data[@"request_body_size"] isKindOfClass:[NSNumber class]]) { + data[@"requestBodySize"] = breadcrumb.data[@"request_body_size"]; + } + if ([breadcrumb.data[@"response_body_size"] isKindOfClass:[NSNumber class]]) { + data[@"responseBodySize"] = breadcrumb.data[@"response_body_size"]; + } -- (id _Nullable)convertNavigation: (SentryBreadcrumb *_Nonnull)breadcrumb { - NSNumber* startTimestamp = [breadcrumb.data[@"start_timestamp"] isKindOfClass:[NSNumber class]] - ? breadcrumb.data[@"start_timestamp"] : nil; - NSNumber* endTimestamp = [breadcrumb.data[@"end_timestamp"] isKindOfClass:[NSNumber class]] - ? breadcrumb.data[@"end_timestamp"] : nil; - NSString* url = [breadcrumb.data[@"url"] isKindOfClass:[NSString class]] - ? breadcrumb.data[@"url"] : nil; - - if (startTimestamp == nil || endTimestamp == nil || url == nil) { - return nil; - } - - NSMutableDictionary* data = [[NSMutableDictionary alloc] init]; - if ([breadcrumb.data[@"method"] isKindOfClass:[NSString class]]) { - data[@"method"] = breadcrumb.data[@"method"]; - } - if ([breadcrumb.data[@"status_code"] isKindOfClass:[NSNumber class]]) { - data[@"statusCode"] = breadcrumb.data[@"status_code"]; - } - if ([breadcrumb.data[@"request_body_size"] isKindOfClass:[NSNumber class]]) { - data[@"requestBodySize"] = breadcrumb.data[@"request_body_size"]; - } - if ([breadcrumb.data[@"response_body_size"] isKindOfClass:[NSNumber class]]) { - data[@"responseBodySize"] = breadcrumb.data[@"response_body_size"]; - } - - return [SentrySessionReplayIntegration - createNetworkBreadcrumbWithTimestamp:[NSDate dateWithTimeIntervalSince1970:(startTimestamp.doubleValue / 1000)] - endTimestamp:[NSDate dateWithTimeIntervalSince1970:(endTimestamp.doubleValue / 1000)] - operation:@"resource.http" - description:url - data:data]; + return [SentrySessionReplayIntegration + createNetworkBreadcrumbWithTimestamp:[NSDate + dateWithTimeIntervalSince1970:(startTimestamp + .doubleValue + / 1000)] + endTimestamp:[NSDate + dateWithTimeIntervalSince1970:(endTimestamp + .doubleValue + / 1000)] + operation:@"resource.http" + description:url + data:data]; } @end diff --git a/packages/core/ios/RNSentryTimeToDisplay.m b/packages/core/ios/RNSentryTimeToDisplay.m index 88e24eedc7..9404cf5088 100644 --- a/packages/core/ios/RNSentryTimeToDisplay.m +++ b/packages/core/ios/RNSentryTimeToDisplay.m @@ -2,41 +2,42 @@ #import #import -@implementation RNSentryTimeToDisplay -{ - CADisplayLink *displayLink; - RCTResponseSenderBlock resolveBlock; +@implementation RNSentryTimeToDisplay { + CADisplayLink *displayLink; + RCTResponseSenderBlock resolveBlock; } // Rename requestAnimationFrame to getTimeToDisplay - (void)getTimeToDisplay:(RCTResponseSenderBlock)callback { - // Store the resolve block to use in the callback. - resolveBlock = callback; + // Store the resolve block to use in the callback. + resolveBlock = callback; #if TARGET_OS_IOS - // Create and add a display link to get the callback after the screen is rendered. - displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; - [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + // Create and add a display link to get the callback after the screen is rendered. + displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; + [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; #else - resolveBlock(@[]); // Return nothing if not iOS. + resolveBlock(@[]); // Return nothing if not iOS. #endif } #if TARGET_OS_IOS -- (void)handleDisplayLink:(CADisplayLink *)link { - // Get the current time - NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970] * 1000.0; // Convert to milliseconds +- (void)handleDisplayLink:(CADisplayLink *)link +{ + // Get the current time + NSTimeInterval currentTime = + [[NSDate date] timeIntervalSince1970] * 1000.0; // Convert to milliseconds - // Ensure the callback is valid and pass the current time back - if (resolveBlock) { - resolveBlock(@[@(currentTime)]); // Call the callback with the current time - resolveBlock = nil; // Clear the block after it's called - } + // Ensure the callback is valid and pass the current time back + if (resolveBlock) { + resolveBlock(@[ @(currentTime) ]); // Call the callback with the current time + resolveBlock = nil; // Clear the block after it's called + } - // Invalidate the display link to stop future callbacks - [displayLink invalidate]; - displayLink = nil; + // Invalidate the display link to stop future callbacks + [displayLink invalidate]; + displayLink = nil; } #endif diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.cpp index 23bc693960..70e1fce274 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.cpp +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.cpp @@ -6,28 +6,28 @@ namespace facebook { namespace react { -std::shared_ptr MainApplicationModuleProvider( - const std::string &moduleName, - const JavaTurboModule::InitParams ¶ms) { - // Here you can provide your own module provider for TurboModules coming from - // either your application or from external libraries. The approach to follow - // is similar to the following (for a library called `samplelibrary`: - // - // auto module = samplelibrary_ModuleProvider(moduleName, params); - // if (module != nullptr) { - // return module; - // } - // return rncore_ModuleProvider(moduleName, params); + std::shared_ptr + MainApplicationModuleProvider( + const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) + { + // Here you can provide your own module provider for TurboModules coming from + // either your application or from external libraries. The approach to follow + // is similar to the following (for a library called `samplelibrary`: + // + // auto module = samplelibrary_ModuleProvider(moduleName, params); + // if (module != nullptr) { + // return module; + // } + // return rncore_ModuleProvider(moduleName, params); - // Module providers autolinked by RN CLI - auto rncli_module = rncli_ModuleProvider(moduleName, params); - if (rncli_module != nullptr) - { - return rncli_module; - } + // Module providers autolinked by RN CLI + auto rncli_module = rncli_ModuleProvider(moduleName, params); + if (rncli_module != nullptr) { + return rncli_module; + } - return rncore_ModuleProvider(moduleName, params); -} + return rncore_ModuleProvider(moduleName, params); + } } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.h b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.h index b38ccf53fd..a77063962a 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.h +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationModuleProvider.h @@ -8,9 +8,8 @@ namespace facebook { namespace react { -std::shared_ptr MainApplicationModuleProvider( - const std::string &moduleName, - const JavaTurboModule::InitParams ¶ms); + std::shared_ptr MainApplicationModuleProvider( + const std::string &moduleName, const JavaTurboModule::InitParams ¶ms); } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp index 5fd688c509..6242cd6825 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp @@ -4,42 +4,43 @@ namespace facebook { namespace react { -jni::local_ref -MainApplicationTurboModuleManagerDelegate::initHybrid( - jni::alias_ref) { - return makeCxxInstance(); -} + jni::local_ref + MainApplicationTurboModuleManagerDelegate::initHybrid(jni::alias_ref) + { + return makeCxxInstance(); + } -void MainApplicationTurboModuleManagerDelegate::registerNatives() { - registerHybrid({ - makeNativeMethod( - "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), - makeNativeMethod( - "canCreateTurboModule", - MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), - }); -} + void + MainApplicationTurboModuleManagerDelegate::registerNatives() + { + registerHybrid({ + makeNativeMethod("initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), + makeNativeMethod("canCreateTurboModule", + MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), + }); + } -std::shared_ptr -MainApplicationTurboModuleManagerDelegate::getTurboModule( - const std::string &name, - const std::shared_ptr &jsInvoker) { - // Not implemented yet: provide pure-C++ NativeModules here. - return nullptr; -} + std::shared_ptr + MainApplicationTurboModuleManagerDelegate::getTurboModule( + const std::string &name, const std::shared_ptr &jsInvoker) + { + // Not implemented yet: provide pure-C++ NativeModules here. + return nullptr; + } -std::shared_ptr -MainApplicationTurboModuleManagerDelegate::getTurboModule( - const std::string &name, - const JavaTurboModule::InitParams ¶ms) { - return MainApplicationModuleProvider(name, params); -} + std::shared_ptr + MainApplicationTurboModuleManagerDelegate::getTurboModule( + const std::string &name, const JavaTurboModule::InitParams ¶ms) + { + return MainApplicationModuleProvider(name, params); + } -bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( - const std::string &name) { - return getTurboModule(name, nullptr) != nullptr || - getTurboModule(name, {.moduleName = name}) != nullptr; -} + bool + MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(const std::string &name) + { + return getTurboModule(name, nullptr) != nullptr + || getTurboModule(name, { .moduleName = name }) != nullptr; + } } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h index 1393dc6212..36be4bb41f 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h @@ -7,32 +7,29 @@ namespace facebook { namespace react { -class MainApplicationTurboModuleManagerDelegate - : public jni::HybridClass< - MainApplicationTurboModuleManagerDelegate, - TurboModuleManagerDelegate> { - public: - // Adapt it to the package you used for your Java class. - static constexpr auto kJavaDescriptor = - "Lcom/testappsentry/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; - - static jni::local_ref initHybrid(jni::alias_ref); - - static void registerNatives(); - - std::shared_ptr getTurboModule( - const std::string &name, - const std::shared_ptr &jsInvoker) override; - std::shared_ptr getTurboModule( - const std::string &name, - const JavaTurboModule::InitParams ¶ms) override; - - /** - * Test-only method. Allows user to verify whether a TurboModule can be - * created by instances of this class. - */ - bool canCreateTurboModule(const std::string &name); -}; + class MainApplicationTurboModuleManagerDelegate + : public jni::HybridClass { + public: + // Adapt it to the package you used for your Java class. + static constexpr auto kJavaDescriptor = "Lcom/testappsentry/newarchitecture/modules/" + "MainApplicationTurboModuleManagerDelegate;"; + + static jni::local_ref initHybrid(jni::alias_ref); + + static void registerNatives(); + + std::shared_ptr getTurboModule( + const std::string &name, const std::shared_ptr &jsInvoker) override; + std::shared_ptr getTurboModule( + const std::string &name, const JavaTurboModule::InitParams ¶ms) override; + + /** + * Test-only method. Allows user to verify whether a TurboModule can be + * created by instances of this class. + */ + bool canCreateTurboModule(const std::string &name); + }; } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.cpp b/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.cpp index 54f598a486..4338b2a3a1 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.cpp +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.cpp @@ -9,57 +9,56 @@ namespace facebook { namespace react { -MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} + MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) { } -std::shared_ptr -MainComponentsRegistry::sharedProviderRegistry() { - auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); + std::shared_ptr + MainComponentsRegistry::sharedProviderRegistry() + { + auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); - // Autolinked providers registered by RN CLI - rncli_registerProviders(providerRegistry); + // Autolinked providers registered by RN CLI + rncli_registerProviders(providerRegistry); - // Custom Fabric Components go here. You can register custom - // components coming from your App or from 3rd party libraries here. - // - // providerRegistry->add(concreteComponentDescriptorProvider< - // AocViewerComponentDescriptor>()); - return providerRegistry; -} + // Custom Fabric Components go here. You can register custom + // components coming from your App or from 3rd party libraries here. + // + // providerRegistry->add(concreteComponentDescriptorProvider< + // AocViewerComponentDescriptor>()); + return providerRegistry; + } -jni::local_ref -MainComponentsRegistry::initHybrid( - jni::alias_ref, - ComponentFactory *delegate) { - auto instance = makeCxxInstance(delegate); + jni::local_ref + MainComponentsRegistry::initHybrid(jni::alias_ref, ComponentFactory *delegate) + { + auto instance = makeCxxInstance(delegate); - auto buildRegistryFunction = - [](EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer) - -> ComponentDescriptorRegistry::Shared { - auto registry = MainComponentsRegistry::sharedProviderRegistry() - ->createComponentDescriptorRegistry( - {eventDispatcher, contextContainer}); + auto buildRegistryFunction = [](EventDispatcher::Weak const &eventDispatcher, + ContextContainer::Shared const &contextContainer) + -> ComponentDescriptorRegistry::Shared { + auto registry + = MainComponentsRegistry::sharedProviderRegistry() + ->createComponentDescriptorRegistry({ eventDispatcher, contextContainer }); - auto mutableRegistry = - std::const_pointer_cast(registry); + auto mutableRegistry = std::const_pointer_cast(registry); - mutableRegistry->setFallbackComponentDescriptor( - std::make_shared( - ComponentDescriptorParameters{ - eventDispatcher, contextContainer, nullptr})); + mutableRegistry->setFallbackComponentDescriptor( + std::make_shared( + ComponentDescriptorParameters { eventDispatcher, contextContainer, nullptr })); - return registry; - }; + return registry; + }; - delegate->buildRegistryFunction = buildRegistryFunction; - return instance; -} + delegate->buildRegistryFunction = buildRegistryFunction; + return instance; + } -void MainComponentsRegistry::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), - }); -} + void + MainComponentsRegistry::registerNatives() + { + registerHybrid({ + makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), + }); + } } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.h b/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.h index 8e550c678f..e63cfe462a 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.h +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/MainComponentsRegistry.h @@ -8,25 +8,22 @@ namespace facebook { namespace react { -class MainComponentsRegistry - : public facebook::jni::HybridClass { - public: - // Adapt it to the package you used for your Java class. - constexpr static auto kJavaDescriptor = - "Lcom/testappplain/newarchitecture/components/MainComponentsRegistry;"; + class MainComponentsRegistry : public facebook::jni::HybridClass { + public: + // Adapt it to the package you used for your Java class. + constexpr static auto kJavaDescriptor + = "Lcom/testappplain/newarchitecture/components/MainComponentsRegistry;"; - static void registerNatives(); + static void registerNatives(); - MainComponentsRegistry(ComponentFactory *delegate); + MainComponentsRegistry(ComponentFactory *delegate); - private: - static std::shared_ptr - sharedProviderRegistry(); + private: + static std::shared_ptr sharedProviderRegistry(); - static jni::local_ref initHybrid( - jni::alias_ref, - ComponentFactory *delegate); -}; + static jni::local_ref initHybrid( + jni::alias_ref, ComponentFactory *delegate); + }; } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppPlain/android/app/src/main/jni/OnLoad.cpp b/performance-tests/TestAppPlain/android/app/src/main/jni/OnLoad.cpp index c569b6e865..e1e387162a 100644 --- a/performance-tests/TestAppPlain/android/app/src/main/jni/OnLoad.cpp +++ b/performance-tests/TestAppPlain/android/app/src/main/jni/OnLoad.cpp @@ -1,11 +1,12 @@ -#include #include "MainApplicationTurboModuleManagerDelegate.h" #include "MainComponentsRegistry.h" +#include -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { - return facebook::jni::initialize(vm, [] { - facebook::react::MainApplicationTurboModuleManagerDelegate:: - registerNatives(); - facebook::react::MainComponentsRegistry::registerNatives(); - }); +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *) +{ + return facebook::jni::initialize(vm, [] { + facebook::react::MainApplicationTurboModuleManagerDelegate::registerNatives(); + facebook::react::MainComponentsRegistry::registerNatives(); + }); } diff --git a/performance-tests/TestAppPlain/ios/TestAppPlain/AppDelegate.mm b/performance-tests/TestAppPlain/ios/TestAppPlain/AppDelegate.mm index 32f576bc81..426fb5164f 100644 --- a/performance-tests/TestAppPlain/ios/TestAppPlain/AppDelegate.mm +++ b/performance-tests/TestAppPlain/ios/TestAppPlain/AppDelegate.mm @@ -7,57 +7,60 @@ #import #if RCT_NEW_ARCH_ENABLED -#import -#import -#import -#import -#import -#import +# import +# import +# import +# import +# import +# import -#import +# import static NSString *const kRNConcurrentRoot = @"concurrentRoot"; -@interface AppDelegate () { - RCTTurboModuleManager *_turboModuleManager; - RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; - std::shared_ptr _reactNativeConfig; - facebook::react::ContextContainer::Shared _contextContainer; +@interface +AppDelegate () { + RCTTurboModuleManager *_turboModuleManager; + RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; + std::shared_ptr _reactNativeConfig; + facebook::react::ContextContainer::Shared _contextContainer; } @end #endif @implementation AppDelegate -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - RCTAppSetupPrepareApp(application); + RCTAppSetupPrepareApp(application); - RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; + RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; #if RCT_NEW_ARCH_ENABLED - _contextContainer = std::make_shared(); - _reactNativeConfig = std::make_shared(); - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); - _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; - bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; + _contextContainer = std::make_shared(); + _reactNativeConfig = std::make_shared(); + _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); + _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge + contextContainer:_contextContainer]; + bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif - NSDictionary *initProps = [self prepareInitialProps]; - UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"TestAppPlain", initProps); - - if (@available(iOS 13.0, *)) { - rootView.backgroundColor = [UIColor systemBackgroundColor]; - } else { - rootView.backgroundColor = [UIColor whiteColor]; - } - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - return YES; + NSDictionary *initProps = [self prepareInitialProps]; + UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"TestAppPlain", initProps); + + if (@available(iOS 13.0, *)) { + rootView.backgroundColor = [UIColor systemBackgroundColor]; + } else { + rootView.backgroundColor = [UIColor whiteColor]; + } + + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + UIViewController *rootViewController = [UIViewController new]; + rootViewController.view = rootView; + self.window.rootViewController = rootViewController; + [self.window makeKeyAndVisible]; + return YES; } /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. @@ -67,65 +70,67 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( /// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { - // Switch this bool to turn on and off the concurrent root - return true; + // Switch this bool to turn on and off the concurrent root + return true; } - (NSDictionary *)prepareInitialProps { - NSMutableDictionary *initProps = [NSMutableDictionary new]; + NSMutableDictionary *initProps = [NSMutableDictionary new]; #ifdef RCT_NEW_ARCH_ENABLED - initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); + initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); #endif - return initProps; + return initProps; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } #if RCT_NEW_ARCH_ENABLED -#pragma mark - RCTCxxBridgeDelegate +# pragma mark - RCTCxxBridgeDelegate -- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge +- (std::unique_ptr)jsExecutorFactoryForBridge: + (RCTBridge *)bridge { - _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:bridge.jsCallInvoker]; - return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); + _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge + delegate:self + jsInvoker:bridge.jsCallInvoker]; + return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); } -#pragma mark RCTTurboModuleManagerDelegate +# pragma mark RCTTurboModuleManagerDelegate - (Class)getModuleClassFromName:(const char *)name { - return RCTCoreModulesClassProvider(name); + return RCTCoreModulesClassProvider(name); } -- (std::shared_ptr)getTurboModule:(const std::string &)name - jsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker { - return nullptr; + return nullptr; } -- (std::shared_ptr)getTurboModule:(const std::string &)name - initParams: - (const facebook::react::ObjCTurboModule::InitParams &)params +- (std::shared_ptr) + getTurboModule:(const std::string &)name + initParams:(const facebook::react::ObjCTurboModule::InitParams &)params { - return nullptr; + return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { - return RCTAppSetupDefaultModuleFromClass(moduleClass); + return RCTAppSetupDefaultModuleFromClass(moduleClass); } #endif diff --git a/performance-tests/TestAppPlain/ios/TestAppPlain/main.m b/performance-tests/TestAppPlain/ios/TestAppPlain/main.m index d645c7246c..742168d2e4 100644 --- a/performance-tests/TestAppPlain/ios/TestAppPlain/main.m +++ b/performance-tests/TestAppPlain/ios/TestAppPlain/main.m @@ -2,9 +2,10 @@ #import "AppDelegate.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } } diff --git a/performance-tests/TestAppPlain/ios/TestAppPlainTests/TestAppPlainTests.m b/performance-tests/TestAppPlain/ios/TestAppPlainTests/TestAppPlainTests.m index 249dfa0cd5..7abbf13d6b 100644 --- a/performance-tests/TestAppPlain/ios/TestAppPlainTests/TestAppPlainTests.m +++ b/performance-tests/TestAppPlain/ios/TestAppPlainTests/TestAppPlainTests.m @@ -15,52 +15,56 @@ @implementation TestAppPlainTests - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test { - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; + if (test(view)) { + return YES; } - } - return NO; + for (UIView *subview in [view subviews]) { + if ([self findSubviewInView:subview matching:test]) { + return YES; + } + } + return NO; } - (void)testRendersWelcomeScreen { - UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; + UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; + NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; + BOOL foundElement = NO; - __block NSString *redboxError = nil; + __block NSString *redboxError = nil; #ifdef DEBUG - RCTSetLogFunction( - ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { + RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, + NSNumber *lineNumber, NSString *message) { if (level >= RCTLogLevelError) { - redboxError = message; + redboxError = message; } - }); + }); #endif - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes + beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - foundElement = [self findSubviewInView:vc.view - matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } + foundElement = + [self findSubviewInView:vc.view + matching:^BOOL(UIView *view) { + if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { + return YES; + } + return NO; + }]; + } #ifdef DEBUG - RCTSetLogFunction(RCTDefaultLogFunction); + RCTSetLogFunction(RCTDefaultLogFunction); #endif - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); + XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); + XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", + TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); } @end diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.cpp index 23bc693960..70e1fce274 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.cpp +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.cpp @@ -6,28 +6,28 @@ namespace facebook { namespace react { -std::shared_ptr MainApplicationModuleProvider( - const std::string &moduleName, - const JavaTurboModule::InitParams ¶ms) { - // Here you can provide your own module provider for TurboModules coming from - // either your application or from external libraries. The approach to follow - // is similar to the following (for a library called `samplelibrary`: - // - // auto module = samplelibrary_ModuleProvider(moduleName, params); - // if (module != nullptr) { - // return module; - // } - // return rncore_ModuleProvider(moduleName, params); + std::shared_ptr + MainApplicationModuleProvider( + const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) + { + // Here you can provide your own module provider for TurboModules coming from + // either your application or from external libraries. The approach to follow + // is similar to the following (for a library called `samplelibrary`: + // + // auto module = samplelibrary_ModuleProvider(moduleName, params); + // if (module != nullptr) { + // return module; + // } + // return rncore_ModuleProvider(moduleName, params); - // Module providers autolinked by RN CLI - auto rncli_module = rncli_ModuleProvider(moduleName, params); - if (rncli_module != nullptr) - { - return rncli_module; - } + // Module providers autolinked by RN CLI + auto rncli_module = rncli_ModuleProvider(moduleName, params); + if (rncli_module != nullptr) { + return rncli_module; + } - return rncore_ModuleProvider(moduleName, params); -} + return rncore_ModuleProvider(moduleName, params); + } } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.h b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.h index b38ccf53fd..a77063962a 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.h +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationModuleProvider.h @@ -8,9 +8,8 @@ namespace facebook { namespace react { -std::shared_ptr MainApplicationModuleProvider( - const std::string &moduleName, - const JavaTurboModule::InitParams ¶ms); + std::shared_ptr MainApplicationModuleProvider( + const std::string &moduleName, const JavaTurboModule::InitParams ¶ms); } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp index 5fd688c509..6242cd6825 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp @@ -4,42 +4,43 @@ namespace facebook { namespace react { -jni::local_ref -MainApplicationTurboModuleManagerDelegate::initHybrid( - jni::alias_ref) { - return makeCxxInstance(); -} + jni::local_ref + MainApplicationTurboModuleManagerDelegate::initHybrid(jni::alias_ref) + { + return makeCxxInstance(); + } -void MainApplicationTurboModuleManagerDelegate::registerNatives() { - registerHybrid({ - makeNativeMethod( - "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), - makeNativeMethod( - "canCreateTurboModule", - MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), - }); -} + void + MainApplicationTurboModuleManagerDelegate::registerNatives() + { + registerHybrid({ + makeNativeMethod("initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), + makeNativeMethod("canCreateTurboModule", + MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), + }); + } -std::shared_ptr -MainApplicationTurboModuleManagerDelegate::getTurboModule( - const std::string &name, - const std::shared_ptr &jsInvoker) { - // Not implemented yet: provide pure-C++ NativeModules here. - return nullptr; -} + std::shared_ptr + MainApplicationTurboModuleManagerDelegate::getTurboModule( + const std::string &name, const std::shared_ptr &jsInvoker) + { + // Not implemented yet: provide pure-C++ NativeModules here. + return nullptr; + } -std::shared_ptr -MainApplicationTurboModuleManagerDelegate::getTurboModule( - const std::string &name, - const JavaTurboModule::InitParams ¶ms) { - return MainApplicationModuleProvider(name, params); -} + std::shared_ptr + MainApplicationTurboModuleManagerDelegate::getTurboModule( + const std::string &name, const JavaTurboModule::InitParams ¶ms) + { + return MainApplicationModuleProvider(name, params); + } -bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( - const std::string &name) { - return getTurboModule(name, nullptr) != nullptr || - getTurboModule(name, {.moduleName = name}) != nullptr; -} + bool + MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(const std::string &name) + { + return getTurboModule(name, nullptr) != nullptr + || getTurboModule(name, { .moduleName = name }) != nullptr; + } } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h index 1393dc6212..36be4bb41f 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h @@ -7,32 +7,29 @@ namespace facebook { namespace react { -class MainApplicationTurboModuleManagerDelegate - : public jni::HybridClass< - MainApplicationTurboModuleManagerDelegate, - TurboModuleManagerDelegate> { - public: - // Adapt it to the package you used for your Java class. - static constexpr auto kJavaDescriptor = - "Lcom/testappsentry/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; - - static jni::local_ref initHybrid(jni::alias_ref); - - static void registerNatives(); - - std::shared_ptr getTurboModule( - const std::string &name, - const std::shared_ptr &jsInvoker) override; - std::shared_ptr getTurboModule( - const std::string &name, - const JavaTurboModule::InitParams ¶ms) override; - - /** - * Test-only method. Allows user to verify whether a TurboModule can be - * created by instances of this class. - */ - bool canCreateTurboModule(const std::string &name); -}; + class MainApplicationTurboModuleManagerDelegate + : public jni::HybridClass { + public: + // Adapt it to the package you used for your Java class. + static constexpr auto kJavaDescriptor = "Lcom/testappsentry/newarchitecture/modules/" + "MainApplicationTurboModuleManagerDelegate;"; + + static jni::local_ref initHybrid(jni::alias_ref); + + static void registerNatives(); + + std::shared_ptr getTurboModule( + const std::string &name, const std::shared_ptr &jsInvoker) override; + std::shared_ptr getTurboModule( + const std::string &name, const JavaTurboModule::InitParams ¶ms) override; + + /** + * Test-only method. Allows user to verify whether a TurboModule can be + * created by instances of this class. + */ + bool canCreateTurboModule(const std::string &name); + }; } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.cpp b/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.cpp index 54f598a486..4338b2a3a1 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.cpp +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.cpp @@ -9,57 +9,56 @@ namespace facebook { namespace react { -MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} + MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) { } -std::shared_ptr -MainComponentsRegistry::sharedProviderRegistry() { - auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); + std::shared_ptr + MainComponentsRegistry::sharedProviderRegistry() + { + auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); - // Autolinked providers registered by RN CLI - rncli_registerProviders(providerRegistry); + // Autolinked providers registered by RN CLI + rncli_registerProviders(providerRegistry); - // Custom Fabric Components go here. You can register custom - // components coming from your App or from 3rd party libraries here. - // - // providerRegistry->add(concreteComponentDescriptorProvider< - // AocViewerComponentDescriptor>()); - return providerRegistry; -} + // Custom Fabric Components go here. You can register custom + // components coming from your App or from 3rd party libraries here. + // + // providerRegistry->add(concreteComponentDescriptorProvider< + // AocViewerComponentDescriptor>()); + return providerRegistry; + } -jni::local_ref -MainComponentsRegistry::initHybrid( - jni::alias_ref, - ComponentFactory *delegate) { - auto instance = makeCxxInstance(delegate); + jni::local_ref + MainComponentsRegistry::initHybrid(jni::alias_ref, ComponentFactory *delegate) + { + auto instance = makeCxxInstance(delegate); - auto buildRegistryFunction = - [](EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer) - -> ComponentDescriptorRegistry::Shared { - auto registry = MainComponentsRegistry::sharedProviderRegistry() - ->createComponentDescriptorRegistry( - {eventDispatcher, contextContainer}); + auto buildRegistryFunction = [](EventDispatcher::Weak const &eventDispatcher, + ContextContainer::Shared const &contextContainer) + -> ComponentDescriptorRegistry::Shared { + auto registry + = MainComponentsRegistry::sharedProviderRegistry() + ->createComponentDescriptorRegistry({ eventDispatcher, contextContainer }); - auto mutableRegistry = - std::const_pointer_cast(registry); + auto mutableRegistry = std::const_pointer_cast(registry); - mutableRegistry->setFallbackComponentDescriptor( - std::make_shared( - ComponentDescriptorParameters{ - eventDispatcher, contextContainer, nullptr})); + mutableRegistry->setFallbackComponentDescriptor( + std::make_shared( + ComponentDescriptorParameters { eventDispatcher, contextContainer, nullptr })); - return registry; - }; + return registry; + }; - delegate->buildRegistryFunction = buildRegistryFunction; - return instance; -} + delegate->buildRegistryFunction = buildRegistryFunction; + return instance; + } -void MainComponentsRegistry::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), - }); -} + void + MainComponentsRegistry::registerNatives() + { + registerHybrid({ + makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), + }); + } } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.h b/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.h index e5fb647396..c9466dcc43 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.h +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/MainComponentsRegistry.h @@ -8,25 +8,22 @@ namespace facebook { namespace react { -class MainComponentsRegistry - : public facebook::jni::HybridClass { - public: - // Adapt it to the package you used for your Java class. - constexpr static auto kJavaDescriptor = - "Lcom/testappsentry/newarchitecture/components/MainComponentsRegistry;"; + class MainComponentsRegistry : public facebook::jni::HybridClass { + public: + // Adapt it to the package you used for your Java class. + constexpr static auto kJavaDescriptor + = "Lcom/testappsentry/newarchitecture/components/MainComponentsRegistry;"; - static void registerNatives(); + static void registerNatives(); - MainComponentsRegistry(ComponentFactory *delegate); + MainComponentsRegistry(ComponentFactory *delegate); - private: - static std::shared_ptr - sharedProviderRegistry(); + private: + static std::shared_ptr sharedProviderRegistry(); - static jni::local_ref initHybrid( - jni::alias_ref, - ComponentFactory *delegate); -}; + static jni::local_ref initHybrid( + jni::alias_ref, ComponentFactory *delegate); + }; } // namespace react } // namespace facebook diff --git a/performance-tests/TestAppSentry/android/app/src/main/jni/OnLoad.cpp b/performance-tests/TestAppSentry/android/app/src/main/jni/OnLoad.cpp index c569b6e865..e1e387162a 100644 --- a/performance-tests/TestAppSentry/android/app/src/main/jni/OnLoad.cpp +++ b/performance-tests/TestAppSentry/android/app/src/main/jni/OnLoad.cpp @@ -1,11 +1,12 @@ -#include #include "MainApplicationTurboModuleManagerDelegate.h" #include "MainComponentsRegistry.h" +#include -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { - return facebook::jni::initialize(vm, [] { - facebook::react::MainApplicationTurboModuleManagerDelegate:: - registerNatives(); - facebook::react::MainComponentsRegistry::registerNatives(); - }); +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *) +{ + return facebook::jni::initialize(vm, [] { + facebook::react::MainApplicationTurboModuleManagerDelegate::registerNatives(); + facebook::react::MainComponentsRegistry::registerNatives(); + }); } diff --git a/performance-tests/TestAppSentry/ios/TestAppSentry/AppDelegate.mm b/performance-tests/TestAppSentry/ios/TestAppSentry/AppDelegate.mm index a1ff54fe5c..729d9941e9 100644 --- a/performance-tests/TestAppSentry/ios/TestAppSentry/AppDelegate.mm +++ b/performance-tests/TestAppSentry/ios/TestAppSentry/AppDelegate.mm @@ -7,57 +7,60 @@ #import #if RCT_NEW_ARCH_ENABLED -#import -#import -#import -#import -#import -#import +# import +# import +# import +# import +# import +# import -#import +# import static NSString *const kRNConcurrentRoot = @"concurrentRoot"; -@interface AppDelegate () { - RCTTurboModuleManager *_turboModuleManager; - RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; - std::shared_ptr _reactNativeConfig; - facebook::react::ContextContainer::Shared _contextContainer; +@interface +AppDelegate () { + RCTTurboModuleManager *_turboModuleManager; + RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; + std::shared_ptr _reactNativeConfig; + facebook::react::ContextContainer::Shared _contextContainer; } @end #endif @implementation AppDelegate -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - RCTAppSetupPrepareApp(application); + RCTAppSetupPrepareApp(application); - RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; + RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; #if RCT_NEW_ARCH_ENABLED - _contextContainer = std::make_shared(); - _reactNativeConfig = std::make_shared(); - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); - _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; - bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; + _contextContainer = std::make_shared(); + _reactNativeConfig = std::make_shared(); + _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); + _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge + contextContainer:_contextContainer]; + bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif - NSDictionary *initProps = [self prepareInitialProps]; - UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"TestAppSentry", initProps); - - if (@available(iOS 13.0, *)) { - rootView.backgroundColor = [UIColor systemBackgroundColor]; - } else { - rootView.backgroundColor = [UIColor whiteColor]; - } - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - return YES; + NSDictionary *initProps = [self prepareInitialProps]; + UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"TestAppSentry", initProps); + + if (@available(iOS 13.0, *)) { + rootView.backgroundColor = [UIColor systemBackgroundColor]; + } else { + rootView.backgroundColor = [UIColor whiteColor]; + } + + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + UIViewController *rootViewController = [UIViewController new]; + rootViewController.view = rootView; + self.window.rootViewController = rootViewController; + [self.window makeKeyAndVisible]; + return YES; } /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. @@ -67,65 +70,67 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( /// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { - // Switch this bool to turn on and off the concurrent root - return true; + // Switch this bool to turn on and off the concurrent root + return true; } - (NSDictionary *)prepareInitialProps { - NSMutableDictionary *initProps = [NSMutableDictionary new]; + NSMutableDictionary *initProps = [NSMutableDictionary new]; #ifdef RCT_NEW_ARCH_ENABLED - initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); + initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); #endif - return initProps; + return initProps; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } #if RCT_NEW_ARCH_ENABLED -#pragma mark - RCTCxxBridgeDelegate +# pragma mark - RCTCxxBridgeDelegate -- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge +- (std::unique_ptr)jsExecutorFactoryForBridge: + (RCTBridge *)bridge { - _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:bridge.jsCallInvoker]; - return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); + _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge + delegate:self + jsInvoker:bridge.jsCallInvoker]; + return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); } -#pragma mark RCTTurboModuleManagerDelegate +# pragma mark RCTTurboModuleManagerDelegate - (Class)getModuleClassFromName:(const char *)name { - return RCTCoreModulesClassProvider(name); + return RCTCoreModulesClassProvider(name); } -- (std::shared_ptr)getTurboModule:(const std::string &)name - jsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker { - return nullptr; + return nullptr; } -- (std::shared_ptr)getTurboModule:(const std::string &)name - initParams: - (const facebook::react::ObjCTurboModule::InitParams &)params +- (std::shared_ptr) + getTurboModule:(const std::string &)name + initParams:(const facebook::react::ObjCTurboModule::InitParams &)params { - return nullptr; + return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { - return RCTAppSetupDefaultModuleFromClass(moduleClass); + return RCTAppSetupDefaultModuleFromClass(moduleClass); } #endif diff --git a/performance-tests/TestAppSentry/ios/TestAppSentry/main.m b/performance-tests/TestAppSentry/ios/TestAppSentry/main.m index d645c7246c..742168d2e4 100644 --- a/performance-tests/TestAppSentry/ios/TestAppSentry/main.m +++ b/performance-tests/TestAppSentry/ios/TestAppSentry/main.m @@ -2,9 +2,10 @@ #import "AppDelegate.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } } diff --git a/performance-tests/TestAppSentry/ios/TestAppSentryTests/TestAppSentryTests.m b/performance-tests/TestAppSentry/ios/TestAppSentryTests/TestAppSentryTests.m index 33ae29a52c..bce8f7d71e 100644 --- a/performance-tests/TestAppSentry/ios/TestAppSentryTests/TestAppSentryTests.m +++ b/performance-tests/TestAppSentry/ios/TestAppSentryTests/TestAppSentryTests.m @@ -15,52 +15,56 @@ @implementation TestAppSentryTests - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test { - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; + if (test(view)) { + return YES; } - } - return NO; + for (UIView *subview in [view subviews]) { + if ([self findSubviewInView:subview matching:test]) { + return YES; + } + } + return NO; } - (void)testRendersWelcomeScreen { - UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; + UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; + NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; + BOOL foundElement = NO; - __block NSString *redboxError = nil; + __block NSString *redboxError = nil; #ifdef DEBUG - RCTSetLogFunction( - ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { + RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, + NSNumber *lineNumber, NSString *message) { if (level >= RCTLogLevelError) { - redboxError = message; + redboxError = message; } - }); + }); #endif - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes + beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - foundElement = [self findSubviewInView:vc.view - matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } + foundElement = + [self findSubviewInView:vc.view + matching:^BOOL(UIView *view) { + if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { + return YES; + } + return NO; + }]; + } #ifdef DEBUG - RCTSetLogFunction(RCTDefaultLogFunction); + RCTSetLogFunction(RCTDefaultLogFunction); #endif - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); + XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); + XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", + TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); } @end diff --git a/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.h b/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.h index 63db973168..1c6ff45148 100644 --- a/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.h +++ b/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.h @@ -1,5 +1,5 @@ -#import #import +#import @interface AppDelegate : RCTAppDelegate diff --git a/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.mm b/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.mm index d33f0d7f39..3cb5dff1a5 100644 --- a/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.mm +++ b/samples/react-native-macos/macos/sentry-react-native-sample-macOS/AppDelegate.mm @@ -6,20 +6,20 @@ @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)notification { - self.moduleName = @"sentry-react-native-sample"; - // You can add your custom initial props in the dictionary below. - // They will be passed down to the ViewController used by React Native. - self.initialProps = @{}; + self.moduleName = @"sentry-react-native-sample"; + // You can add your custom initial props in the dictionary below. + // They will be passed down to the ViewController used by React Native. + self.initialProps = @{}; - return [super applicationDidFinishLaunching:notification]; + return [super applicationDidFinishLaunching:notification]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } @@ -31,9 +31,9 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge - (BOOL)concurrentRootEnabled { #ifdef RN_FABRIC_ENABLED - return true; + return true; #else - return false; + return false; #endif } diff --git a/samples/react-native-macos/macos/sentry-react-native-sample-macOS/main.m b/samples/react-native-macos/macos/sentry-react-native-sample-macOS/main.m index 1f154fcf69..71875488f7 100644 --- a/samples/react-native-macos/macos/sentry-react-native-sample-macOS/main.m +++ b/samples/react-native-macos/macos/sentry-react-native-sample-macOS/main.m @@ -1,5 +1,7 @@ #import -int main(int argc, const char *argv[]) { - return NSApplicationMain(argc, argv); +int +main(int argc, const char *argv[]) +{ + return NSApplicationMain(argc, argv); } diff --git a/samples/react-native/android/app/src/main/jni/OnLoad.cpp b/samples/react-native/android/app/src/main/jni/OnLoad.cpp index f7425ab605..6cbb3d648d 100644 --- a/samples/react-native/android/app/src/main/jni/OnLoad.cpp +++ b/samples/react-native/android/app/src/main/jni/OnLoad.cpp @@ -35,97 +35,99 @@ #include #ifdef REACT_NATIVE_APP_CODEGEN_HEADER -#include REACT_NATIVE_APP_CODEGEN_HEADER +# include REACT_NATIVE_APP_CODEGEN_HEADER #endif #ifdef REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER -#include REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER +# include REACT_NATIVE_APP_COMPONENT_DESCRIPTORS_HEADER #endif namespace facebook::react { -void registerComponents( - std::shared_ptr registry) { - // Custom Fabric Components go here. You can register custom - // components coming from your App or from 3rd party libraries here. - // - // providerRegistry->add(concreteComponentDescriptorProvider< - // MyComponentDescriptor>()); +void +registerComponents(std::shared_ptr registry) +{ + // Custom Fabric Components go here. You can register custom + // components coming from your App or from 3rd party libraries here. + // + // providerRegistry->add(concreteComponentDescriptorProvider< + // MyComponentDescriptor>()); - // We link app local components if available + // We link app local components if available #ifdef REACT_NATIVE_APP_COMPONENT_REGISTRATION - REACT_NATIVE_APP_COMPONENT_REGISTRATION(registry); + REACT_NATIVE_APP_COMPONENT_REGISTRATION(registry); #endif - // And we fallback to the components autolinked - autolinking_registerProviders(registry); + // And we fallback to the components autolinked + autolinking_registerProviders(registry); } -std::shared_ptr cxxModuleProvider( - const std::string& name, - const std::shared_ptr& jsInvoker) { - // Here you can provide your CXX Turbo Modules coming from - // either your application or from external libraries. The approach to follow - // is similar to the following (for a module called `NativeCxxModuleExample`): - // - // if (name == NativeCxxModuleExample::kModuleName) { - // return std::make_shared(jsInvoker); - // } - - // And we fallback to the CXX module providers autolinked - return autolinking_cxxModuleProvider(name, jsInvoker); +std::shared_ptr +cxxModuleProvider(const std::string &name, const std::shared_ptr &jsInvoker) +{ + // Here you can provide your CXX Turbo Modules coming from + // either your application or from external libraries. The approach to follow + // is similar to the following (for a module called `NativeCxxModuleExample`): + // + // if (name == NativeCxxModuleExample::kModuleName) { + // return std::make_shared(jsInvoker); + // } + + // And we fallback to the CXX module providers autolinked + return autolinking_cxxModuleProvider(name, jsInvoker); } -std::shared_ptr javaModuleProvider( - const std::string& name, - const JavaTurboModule::InitParams& params) { - // Here you can provide your own module provider for TurboModules coming from - // either your application or from external libraries. The approach to follow - // is similar to the following (for a library called `samplelibrary`): - // - // auto module = samplelibrary_ModuleProvider(name, params); - // if (module != nullptr) { - // return module; - // } - // return rncore_ModuleProvider(name, params); - - // We link app local modules if available +std::shared_ptr +javaModuleProvider(const std::string &name, const JavaTurboModule::InitParams ¶ms) +{ + // Here you can provide your own module provider for TurboModules coming from + // either your application or from external libraries. The approach to follow + // is similar to the following (for a library called `samplelibrary`): + // + // auto module = samplelibrary_ModuleProvider(name, params); + // if (module != nullptr) { + // return module; + // } + // return rncore_ModuleProvider(name, params); + + // We link app local modules if available #ifdef REACT_NATIVE_APP_MODULE_PROVIDER - auto module = REACT_NATIVE_APP_MODULE_PROVIDER(name, params); - if (module != nullptr) { - return module; - } + auto module = REACT_NATIVE_APP_MODULE_PROVIDER(name, params); + if (module != nullptr) { + return module; + } #endif - // We first try to look up core modules - if (auto module = rncore_ModuleProvider(name, params)) { - return module; - } + // We first try to look up core modules + if (auto module = rncore_ModuleProvider(name, params)) { + return module; + } - // And we fallback to the module providers autolinked - if (auto module = autolinking_ModuleProvider(name, params)) { - return module; - } + // And we fallback to the module providers autolinked + if (auto module = autolinking_ModuleProvider(name, params)) { + return module; + } - return nullptr; + return nullptr; } } // namespace facebook::react -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { - return facebook::jni::initialize(vm, [] { - facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider = - &facebook::react::cxxModuleProvider; - facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider = - &facebook::react::javaModuleProvider; - facebook::react::DefaultComponentsRegistry:: - registerComponentDescriptorsFromEntryPoint = - &facebook::react::registerComponents; - }); +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *) +{ + return facebook::jni::initialize(vm, [] { + facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider + = &facebook::react::cxxModuleProvider; + facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider + = &facebook::react::javaModuleProvider; + facebook::react::DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint + = &facebook::react::registerComponents; + }); } -extern "C" -JNIEXPORT void JNICALL -Java_io_sentry_reactnative_sample_SamplePackage_crash(JNIEnv *env, jobject thiz) { - char *ptr = 0; - *ptr += 1; +extern "C" JNIEXPORT void JNICALL +Java_io_sentry_reactnative_sample_SamplePackage_crash(JNIEnv *env, jobject thiz) +{ + char *ptr = 0; + *ptr += 1; } diff --git a/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm b/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm index 1fe2052e1e..0321e65bc4 100644 --- a/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm +++ b/samples/react-native/ios/sentryreactnativesample/AppDelegate.mm @@ -1,76 +1,81 @@ #import "AppDelegate.h" -#import #import +#import #import #ifdef RCT_NEW_ARCH_ENABLED -#import +# import #endif -#import #import +#import -@interface AppDelegate () {} +@interface +AppDelegate () { +} @end @implementation AppDelegate -- (void) initializeSentry +- (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; + [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; + PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode = true; #endif - }]; + }]; } -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +- (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]; + // When the native init is enabled the `autoInitializeNativeSdk` + // in JS has to be set to `false` + // [self initializeSentry]; - self.moduleName = @"sentry-react-native-sample"; - // You can add your custom initial props in the dictionary below. - // They will be passed down to the ViewController used by React - self.initialProps = @{}; + self.moduleName = @"sentry-react-native-sample"; + // You can add your custom initial props in the dictionary below. + // They will be passed down to the ViewController used by React + self.initialProps = @{}; - return [super application:application didFinishLaunchingWithOptions:launchOptions]; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { - return [self bundleURL]; + return [self bundleURL]; } - (NSURL *)bundleURL { #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } @@ -81,20 +86,21 @@ - (NSURL *)bundleURL /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { - return true; + return true; } #pragma mark RCTTurboModuleManagerDelegate -- (std::shared_ptr)getTurboModule:(const std::string &)name - jsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker { #ifdef RCT_NEW_ARCH_ENABLED - if (name == "NativeSampleModule") { - return std::make_shared(jsInvoker); - } + if (name == "NativeSampleModule") { + return std::make_shared(jsInvoker); + } #endif - return nullptr; + return nullptr; } @end diff --git a/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.h b/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.h index ceac888bef..fb83052a55 100644 --- a/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.h +++ b/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.h @@ -1,7 +1,7 @@ #import #ifdef RCT_NEW_ARCH_ENABLED -#import +# import @interface NativePlatformSampleModule : NSObject diff --git a/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.mm b/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.mm index 09c572d125..80c31d1b3a 100644 --- a/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.mm +++ b/samples/react-native/ios/sentryreactnativesample/NativePlatformSampleModule.mm @@ -7,14 +7,17 @@ @implementation NativePlatformSampleModule RCT_EXPORT_MODULE(); // Thanks to this guard, we won't compile this code when we build for the old architecture. -- (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { - return std::make_shared(params); +- (std::shared_ptr)getTurboModule: + (const facebook::react::ObjCTurboModule::InitParams &)params +{ + return std::make_shared(params); } -- (NSString *)crashOrString { - NSObject * nilObject = NULL; - NSArray * _ = @[nilObject]; - return @"NEVER RETURNED"; +- (NSString *)crashOrString +{ + NSObject *nilObject = NULL; + NSArray *_ = @[ nilObject ]; + return @"NEVER RETURNED"; } @end diff --git a/samples/react-native/ios/sentryreactnativesample/RCTAssetsModule.m b/samples/react-native/ios/sentryreactnativesample/RCTAssetsModule.m index dc9fd70635..87c570adea 100644 --- a/samples/react-native/ios/sentryreactnativesample/RCTAssetsModule.m +++ b/samples/react-native/ios/sentryreactnativesample/RCTAssetsModule.m @@ -2,27 +2,26 @@ @implementation RCTAssetsModule -RCT_EXPORT_METHOD(getExampleAssetData: (RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(getExampleAssetData + : (RCTPromiseResolveBlock)resolve rejecter + : (RCTPromiseRejectBlock)reject) { - NSDataAsset *data = [[NSDataAsset alloc] initWithName:@"ExampleBinaryData"]; - if (data == nil) { - reject(@"SampleSentryReactNative",@"Failed to load exmaple binary data asset.", nil); - } + NSDataAsset *data = [[NSDataAsset alloc] initWithName:@"ExampleBinaryData"]; + if (data == nil) { + reject(@"SampleSentryReactNative", @"Failed to load exmaple binary data asset.", nil); + } - NSMutableArray *array = [NSMutableArray arrayWithCapacity:data.data.length]; + NSMutableArray *array = [NSMutableArray arrayWithCapacity:data.data.length]; - const char *bytes = [data.data bytes]; + const char *bytes = [data.data bytes]; - for (int i = 0; i < [data.data length]; i++) - { - [array addObject:[[NSNumber alloc] initWithChar:bytes[i]]]; - } + for (int i = 0; i < [data.data length]; i++) { + [array addObject:[[NSNumber alloc] initWithChar:bytes[i]]]; + } - resolve(array); + resolve(array); } RCT_EXPORT_MODULE(AssetsModule); @end - diff --git a/samples/react-native/ios/sentryreactnativesample/main.m b/samples/react-native/ios/sentryreactnativesample/main.m index d645c7246c..742168d2e4 100644 --- a/samples/react-native/ios/sentryreactnativesample/main.m +++ b/samples/react-native/ios/sentryreactnativesample/main.m @@ -2,9 +2,10 @@ #import "AppDelegate.h" -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } } diff --git a/samples/react-native/ios/sentryreactnativesampleTests/sentryreactnativesampleTests.m b/samples/react-native/ios/sentryreactnativesampleTests/sentryreactnativesampleTests.m index 0eb5dfb8ab..68e29d1ec5 100644 --- a/samples/react-native/ios/sentryreactnativesampleTests/sentryreactnativesampleTests.m +++ b/samples/react-native/ios/sentryreactnativesampleTests/sentryreactnativesampleTests.m @@ -15,52 +15,56 @@ @implementation sentryreactnativesampleTests - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test { - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; + if (test(view)) { + return YES; } - } - return NO; + for (UIView *subview in [view subviews]) { + if ([self findSubviewInView:subview matching:test]) { + return YES; + } + } + return NO; } - (void)testRendersWelcomeScreen { - UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; + UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; + NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; + BOOL foundElement = NO; - __block NSString *redboxError = nil; + __block NSString *redboxError = nil; #ifdef DEBUG - RCTSetLogFunction( - ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { + RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, + NSNumber *lineNumber, NSString *message) { if (level >= RCTLogLevelError) { - redboxError = message; + redboxError = message; } - }); + }); #endif - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes + beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - foundElement = [self findSubviewInView:vc.view - matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } + foundElement = + [self findSubviewInView:vc.view + matching:^BOOL(UIView *view) { + if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { + return YES; + } + return NO; + }]; + } #ifdef DEBUG - RCTSetLogFunction(RCTDefaultLogFunction); + RCTSetLogFunction(RCTDefaultLogFunction); #endif - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); + XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); + XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", + TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); } @end diff --git a/samples/react-native/tm/NativeSampleModule.cpp b/samples/react-native/tm/NativeSampleModule.cpp index 529463cf16..718f42bba4 100644 --- a/samples/react-native/tm/NativeSampleModule.cpp +++ b/samples/react-native/tm/NativeSampleModule.cpp @@ -1,14 +1,16 @@ #include "NativeSampleModule.h" -namespace facebook::react -{ +namespace facebook::react { - NativeSampleModule::NativeSampleModule(std::shared_ptr jsInvoker) - : NativeSampleModuleCxxSpec(std::move(jsInvoker)) {} +NativeSampleModule::NativeSampleModule(std::shared_ptr jsInvoker) + : NativeSampleModuleCxxSpec(std::move(jsInvoker)) +{ +} - void NativeSampleModule::crash(jsi::Runtime &rt) - { +void +NativeSampleModule::crash(jsi::Runtime &rt) +{ throw std::runtime_error("Error from native cxx module"); - } +} } // namespace facebook::react diff --git a/samples/react-native/tm/NativeSampleModule.h b/samples/react-native/tm/NativeSampleModule.h index 38ef640842..c37cd715c9 100644 --- a/samples/react-native/tm/NativeSampleModule.h +++ b/samples/react-native/tm/NativeSampleModule.h @@ -1,22 +1,20 @@ #pragma once #if __has_include() // CocoaPod headers on Apple -#include +# include #elif __has_include("AppSpecsJSI.h") // CMake headers on Android -#include "AppSpecsJSI.h" +# include "AppSpecsJSI.h" #endif #include #include -namespace facebook::react -{ +namespace facebook::react { - class NativeSampleModule : public NativeSampleModuleCxxSpec - { - public: +class NativeSampleModule : public NativeSampleModuleCxxSpec { +public: NativeSampleModule(std::shared_ptr jsInvoker); void crash(jsi::Runtime &rt); - }; +}; } // namespace facebook::react diff --git a/scripts/clang-format.sh b/scripts/clang-format.sh new file mode 100755 index 0000000000..30987410e4 --- /dev/null +++ b/scripts/clang-format.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -eo pipefail + +# Check if an argument is provided +if [ $# -eq 0 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Set the mode based on the first argument +mode=$1 + +# Base command +cmd="find . -type f \( \ + -name \"*.h\" -or \ + -name \"*.hpp\" -or \ + -name \"*.c\" -or \ + -name \"*.cpp\" -or \ + -name \"*.m\" -or \ + -name \"*.mm\" \) -and \ + ! \( \ + -path \"**.build/*\" -or \ + -path \"**Build/*\" -or \ + -path \"**ios/build/**\" -or \ + -path \"**android/build/**\" -or \ + -path \"**.cxx/**\" -or \ + -path \"**build/generated/**\" -or \ + -path \"**/Carthage/Checkouts/*\" -or \ + -path \"**/libs/**\" -or \ + -path \"**/.yalc/**\" -or \ + -path \"**/node_modules/**\" -or \ + -path \"**/gems/**\" -or \ + -path \"**/Pods/**\" \) \ + | xargs npx clang-format --Werror --verbose -i -style=file" + +# Add --replace flag if mode is 'fix' +if [ "$mode" = "fix" ]; then + echo "clang-format fixing files..." +elif [ "$mode" = "lint" ]; then + echo "clang-format lint files..." + cmd+=" --dry-run" +else + echo "Invalid mode. Use 'fix' or 'lint'." + exit 1 +fi + +eval $cmd diff --git a/yarn.lock b/yarn.lock index b5b1913049..c9ce7f5709 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10230,6 +10230,21 @@ __metadata: languageName: node linkType: hard +"clang-format@npm:^1.8.0": + version: 1.8.0 + resolution: "clang-format@npm:1.8.0" + dependencies: + async: ^3.2.3 + glob: ^7.0.0 + resolve: ^1.1.6 + bin: + check-clang-format: bin/check-clang-format.js + clang-format: index.js + git-clang-format: bin/git-clang-format + checksum: 8e4198e976e8ca1dcb6f7eba09db89db44ce39c326a249b1a28ea2b3fd7dc5ece389d328bb9781424a708e63044b1432d85b9d8f65c46d3d5c13d2b6bf745a50 + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -22267,7 +22282,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@npm%3A^1.1.6#~builtin, resolve@patch:resolve@npm%3A^1.10.0#~builtin, resolve@patch:resolve@npm%3A^1.14.2#~builtin, resolve@patch:resolve@npm%3A^1.20.0#~builtin, resolve@patch:resolve@npm%3A^1.21.0#~builtin, resolve@patch:resolve@npm%3A^1.22.2#~builtin, resolve@patch:resolve@npm%3A^1.22.4#~builtin, resolve@patch:resolve@npm%3A^1.22.8#~builtin": +"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@npm%3A^1.1.6#~builtin, resolve@patch:resolve@npm%3A^1.10.0#~builtin, resolve@patch:resolve@npm%3A^1.14.2#~builtin, resolve@patch:resolve@npm%3A^1.20.0#~builtin, resolve@patch:resolve@npm%3A^1.21.0#~builtin, resolve@patch:resolve@npm%3A^1.22.2#~builtin, resolve@patch:resolve@npm%3A^1.22.4#~builtin, resolve@patch:resolve@npm%3A^1.22.8#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -22877,6 +22892,7 @@ __metadata: resolution: "sentry-react-native@workspace:." dependencies: "@sentry/cli": 2.38.1 + clang-format: ^1.8.0 downlevel-dts: ^0.11.0 google-java-format: ^1.4.0 lerna: ^8.1.8