-
-
Notifications
You must be signed in to change notification settings - Fork 354
feat(expo): Add RNSentrySDK APIs support to @sentry/react-native/expo plugin #4633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: capture-app-start-errors
Are you sure you want to change the base?
Changes from 8 commits
313e844
2e97acc
6eedaae
9ae5475
566550e
770c9f4
f8b37b5
d25db30
adc81a5
8c2cd73
a2b5575
5f4f7c5
0431cc3
62d39cc
235f3ef
369cce7
a53c7f4
5e4a98f
dce74b2
0ffd26c
744993c
5447be9
0b3423f
5c615fd
c356288
8e32556
a20984c
d1db4fa
7c25c2c
1918baf
b2a89f2
3885d70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| import type { ExpoConfig } from '@expo/config-types'; | ||
| /* eslint-disable @typescript-eslint/no-unsafe-member-access */ | ||
| import type { ConfigPlugin, XcodeProject } from 'expo/config-plugins'; | ||
| import { withDangerousMod, withXcodeProject } from 'expo/config-plugins'; | ||
| import { withAppDelegate, withDangerousMod, withXcodeProject } from 'expo/config-plugins'; | ||
| import * as path from 'path'; | ||
|
|
||
| import { warnOnce, writeSentryPropertiesTo } from './utils'; | ||
|
|
@@ -12,8 +13,11 @@ const SENTRY_REACT_NATIVE_XCODE_PATH = | |
| const SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH = | ||
| "`${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`"; | ||
|
|
||
| export const withSentryIOS: ConfigPlugin<string> = (config, sentryProperties: string) => { | ||
| const cfg = withXcodeProject(config, config => { | ||
| export const withSentryIOS: ConfigPlugin<{ sentryProperties: string; useNativeInit: boolean | undefined }> = ( | ||
| config, | ||
| { sentryProperties, useNativeInit = false }, | ||
| ) => { | ||
| const xcodeProjectCfg = withXcodeProject(config, config => { | ||
| const xcodeProject: XcodeProject = config.modResults; | ||
|
|
||
| const sentryBuildPhase = xcodeProject.pbxItemByComment( | ||
|
|
@@ -36,7 +40,9 @@ export const withSentryIOS: ConfigPlugin<string> = (config, sentryProperties: st | |
| return config; | ||
| }); | ||
|
|
||
| return withDangerousMod(cfg, [ | ||
| const appDelegateCfc = useNativeInit ? modifyAppDelegate(xcodeProjectCfg) : xcodeProjectCfg; | ||
|
|
||
| return withDangerousMod(appDelegateCfc, [ | ||
| 'ios', | ||
| config => { | ||
| writeSentryPropertiesTo(path.resolve(config.modRequest.projectRoot, 'ios'), sentryProperties); | ||
|
|
@@ -79,3 +85,58 @@ export function addSentryWithBundledScriptsToBundleShellScript(script: string): | |
| (match: string) => `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_PATH} ${match}`, | ||
| ); | ||
| } | ||
|
|
||
| export function modifyAppDelegate(config: ExpoConfig): ExpoConfig { | ||
| return withAppDelegate(config, async config => { | ||
| if (!config.modResults || !config.modResults.path) { | ||
| warnOnce('Skipping AppDelegate modification because the file does not exist.'); | ||
krystofwoldrich marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return config; | ||
| } | ||
|
|
||
| const fileName = config.modResults.path.split('/').pop(); | ||
|
|
||
| if (config.modResults.language === 'swift') { | ||
| if (config.modResults.contents.includes('RNSentrySDK.start()')) { | ||
| warnOnce(`Your '${fileName}' already contains 'RNSentrySDK.start()'.`); | ||
| return config; | ||
| } | ||
| if (!config.modResults.contents.includes('import RNSentry')) { | ||
krystofwoldrich marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Insert import statement after UIKit import | ||
| config.modResults.contents = config.modResults.contents.replace(/(import UIKit\n)/, `$1import RNSentry\n`); | ||
| } | ||
| // Add RNSentrySDK.start() at the beginning of application method | ||
| const originalContents = config.modResults.contents; | ||
| config.modResults.contents = config.modResults.contents.replace( | ||
| /(func application\([^)]*\) -> Bool \{)/s, | ||
| `$1\n RNSentrySDK.start()`, | ||
krystofwoldrich marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ); | ||
| if (config.modResults.contents === originalContents) { | ||
| warnOnce(`Failed to insert 'RNSentrySDK.start()'.`); | ||
| } | ||
| } else { | ||
| // Objective-C | ||
krystofwoldrich marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (config.modResults.contents.includes('[RNSentrySDK start]')) { | ||
| warnOnce(`Your '${fileName}' already contains '[RNSentrySDK start]'.`); | ||
| return config; | ||
| } | ||
| if (!config.modResults.contents.includes('#import <RNSentry/RNSentry.h>')) { | ||
| // Add import after AppDelegate.h | ||
| config.modResults.contents = config.modResults.contents.replace( | ||
| /(#import "AppDelegate.h"\n)/, | ||
| `$1#import <RNSentry/RNSentry.h>\n`, | ||
| ); | ||
| } | ||
| // Add [RNSentrySDK start] at the beginning of application:didFinishLaunchingWithOptions method | ||
| const originalContents = config.modResults.contents; | ||
| config.modResults.contents = config.modResults.contents.replace( | ||
| /(- \(BOOL\)application:[\s\S]*?didFinishLaunchingWithOptions:[\s\S]*?\{\n)(\s*)/s, | ||
| `$1$2[RNSentrySDK start];\n$2`, | ||
|
Comment on lines
+123
to
+125
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The regex pattern /(- \(BOOL\)application:\(UIApplication \*\)\w+\s+didFinishLaunchingWithOptions:\(NSDictionary \*\)\w+\s*\{\n)(\s*)/sDid we get this right? 👍 / 👎 to inform future reviews. |
||
| ); | ||
| if (config.modResults.contents === originalContents) { | ||
| warnOnce(`Failed to insert '[RNSentrySDK start]'.`); | ||
| } | ||
| } | ||
|
|
||
| return config; | ||
| }); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit. It would be nice to include an example code snippet and a small summary of what will the flag do.