Skip to content

Conversation

@philprime
Copy link
Member

@philprime philprime commented Nov 4, 2025

📜 Description

This PR addresses issue #3901 by automatically disabling App Hang (ANR) tracking for Widgets, Live Activities, (Siri) Intent Extensions, Action Extensions and Share Extensions. These components run in separate processes or sandboxes with different execution characteristics, which can cause false positive app hang reports.

  • Added SentryExtensionDetector to detect the current extension context by reading Info.plist
  • Added SentryExtensionType enum for extension point identifiers (WidgetKit, Intents, Action, Share extensions)
  • Modified SentryANRTrackingIntegration to check for extensions before installing ANR tracking
  • Extended SentryInfoPlistWrapper to support reading dictionary values from Info.plist

💚 How did you test it?

Testing:

  • Added comprehensive unit tests for SentryExtensionDetector covering all extension types and error cases
  • Added integration tests for SentryANRTrackingIntegration verifying correct behavior in extension contexts
  • Added tests for SentryExtensionType enum

Sample Applications:

To properly test the edge cases I created additional sample apps and extensions. Some of them required newer iOS versions than iOS 15 which is still used by iOS-Swift.

Testing - General

I implemented samples with UI to visualize internal state using available UI, e.g. using a Siri Message Preview or a widget. As the App Hang tracker is disabled by default when a debugger is attached, you have two options to verify behaviour:

  • Perform the test without a debugger attached
  • Comment out the following lines of code, so that the App Hang Tracker is also installed with a debugger attached:

if ((integrationOptions & kIntegrationOptionDebuggerNotAttached) &&
[SentryDependencyContainer.sharedInstance.crashWrapper isBeingTraced]) {
[self logWithReason:@"because the debugger is attached"];
return NO;
}

The easiest way to verify that the changes in this PR actually change anything is removing/commenting disabled extension types in the SentryExtensionDetector:

private static var disabledAppHangTypes: [SentryExtensionType] {
return [
.widget,
.intent,
.action,
.share
]
}

Testing - Share Extension

Before:

  1. Remove the .share from the disabled app hang types in the SentryExtensionDetector
  2. Run the Xcode scheme iOS-Swift on an iOS 18.6 simulator or iOS device
  3. Stop the app
  4. Open Safari on the device and navigate to any page, e.g. https://docs.sentry.io
  5. Tap the share symbol in the toolbar
  6. Tap on iOS-Swift in the list of applications
  7. The share dialog will appear with Sentry Enabled? ✅ but ANR Disabled? ❌, indicating that we are in the falsey state and still have ANR tracking enabled.
share-before.mov

After:

  1. Ensure the .share is in the list of disabled app hang types in the SentryExtensionDetector
  2. Perform steps 2 to 6 similar explained above
  3. The share dialog will appear with Sentry Enabled? ✅ but ANR Disabled? ✅ , indicating that we are in the truthy state and have ANR tracking disabled.
share-after.mov

Testing - Action Extension

  1. Remove the .action from the disabled app hang types in the SentryExtensionDetector
  2. Run the Xcode scheme iOS-Swift on an iOS 18.6 simulator or iOS device
  3. Stop the app
  4. Open Safari on the device and navigate to any page, e.g. https://docs.sentry.io
  5. Tap the share symbol in the toolbar
  6. Scroll to the bottom and tap on the action iOS-Swift-ActionExtension
  7. The share dialog will appear with ✅ Sentry is enabled but ❌ ANR Tracking installed, indicating that we are in the falsey state and still have ANR tracking enabled.
action-before.mov

After:

  1. Ensure the .action is in the list of disabled app hang types in the SentryExtensionDetector
  2. Perform steps 2 to 6 similar explained above
  3. The action view will appear with ✅ Sentry is enabled and ✅ ANR Tracking not installed , indicating that we are in the truthy state and have ANR tracking disabled.
action-after.mov

Testing - Intent Extension

Important

I was unsuccessful in using the extension in the simulator, but it worked on device. Therefore I recommend using a real device, but it might also work in the simulator

Before:

  1. Remove the .intent from the disabled app hang types in the SentryExtensionDetector
  2. Run the Xcode scheme iOS-Swift on an iOS device
  3. Stop the app
  4. Trigger Siri and ask it to "Send a message via iOS-Swift".
  5. The sample will pick a fake recipient "John Snow" and show a preview message with Sentry Enabled? ✅ but ANR Disabled? ❌
  6. Tap on "Send" to view the sent message UI
  7. The sample will show a sent message UI with Sentry Enabled? ✅ but ANR Disabled? ❌ too

NOTE: iOS sometimes seems to cache the preview but the message after "sending it" should be correct.

intent-before.MP4

After:

  1. Ensure the .intent is in the list of disabled app hang types in the SentryExtensionDetector
  2. Perform steps 2 to 4 as explained above
    ...
  3. The sample will pick a fake recipient "John Snow" and show a preview message with Sentry Enabled? ✅ but ANR Disabled? ✅
  4. Tap on "Send" to view the sent message UI
  5. The sample will show a sent message UI with Sentry Enabled? ✅ but ANR Disabled? ✅ too
intent-after.MP4

Testing - Widget

For this test we are disabling debugger detection and keep the debugger attached, because it causes a widget refresh on every run.

Before:

  1. Remove the .widget from the disabled app hang types in the SentryExtensionDetector
  2. Disable the debugger detection by commenting out the following code:

if ((integrationOptions & kIntegrationOptionDebuggerNotAttached) &&
[SentryDependencyContainer.sharedInstance.crashWrapper isBeingTraced]) {
[self logWithReason:@"because the debugger is attached"];
return NO;
}

  1. Run the Xcode scheme iOS-SwiftUI-Widgets-WidgetsExtension on an iOS simulator
  2. It will install the app and create a widget on the home screen.
  3. The widget will display SDK Enabled? ✅ but ANR Disabled? ❌ with the current timestamp (which is important because widgets can be outdated)
widget-before.mov

After:

  1. Ensure the .widget is in the list of disabled app hang types in the SentryExtensionDetector
  2. Perform steps 2 to 4 from the before test
  3. The widget will display SDK Enabled? ✅ and ANR Disabled? ✅ with the current timestamp (which is important because widgets can be outdated)
widget-after.mov

Testing - Widget Control

Before:

  1. Remove the .widget from the disabled app hang types in the SentryExtensionDetector
  2. Disable the debugger detection by commenting out the following code:

if ((integrationOptions & kIntegrationOptionDebuggerNotAttached) &&
[SentryDependencyContainer.sharedInstance.crashWrapper isBeingTraced]) {
[self logWithReason:@"because the debugger is attached"];
return NO;
}

  1. Run the Xcode scheme iOS-SwiftUI-Widgets-WidgetControl on an iOS simulator
  2. It will install the app and create a control in the widget control center.
  3. If the symbol of the control is a X, it indicates ANR tracking is enabled.
widget-control-before.mov

After:

  1. Ensure the .widget is in the list of disabled app hang types in the SentryExtensionDetector
  2. Disable the debugger detection by commenting out the following code:

if ((integrationOptions & kIntegrationOptionDebuggerNotAttached) &&
[SentryDependencyContainer.sharedInstance.crashWrapper isBeingTraced]) {
[self logWithReason:@"because the debugger is attached"];
return NO;
}

  1. Run the Xcode scheme iOS-SwiftUI-Widgets-WidgetControl on an iOS simulator
  2. It will install the app and create a control in the widget control center.
  3. If the symbol of the control is a ✔️, it indicates ANR tracking is enabled.
widget-control-after.mov

Testing - Live Activities

Live Activities are displayed differently on different devices, so I recommend you use an iPhone 16 Pro with an dynamic island to see it there too.

IMPORTANT:

During testing I experience multiple times that Live Activities were not started properly, with the push notification token never showing up. Further investigation showed that the live activity is actually a separate process which is called WidgetRenderer_Activities in combination with chronod. During compile-time some of the extensions seemed to perform only partial rebuilds, causing theses processes to not being able to unarchive the live activities.

Furthermore, live activities can be considered special kinds of widgets, therefore they are in the same kind of app extension.

Before:

  1. Remove the .widget from the disabled app hang types in the SentryExtensionDetector
  2. Disable the debugger detection by commenting out the following code:

if ((integrationOptions & kIntegrationOptionDebuggerNotAttached) &&
[SentryDependencyContainer.sharedInstance.crashWrapper isBeingTraced]) {
[self logWithReason:@"because the debugger is attached"];
return NO;
}

  1. Run the Xcode scheme iOS-SwiftUI-Widgets on an iOS simulator
  2. Tap on the button "Start Live Activity"
  3. It will start an indefinite local live activity and display the push notification token locally with "✅ Live Activity is running"
  4. Lock the screen (CMD + L)
  5. In the lockscreen it should display a live activity with "SDK Enabled? ✅" and "ANR Disabled? ❌) indicating that the ANR tracker is still installed
  6. Unlock the simulator and go to the home screen (CMD + SHIFT + H, repeat 3x)
  7. It will display a ✅ left to the dynamic island indicating the SDK is enabled, but ❌ on the right side indicating that the ANR tracker is still installed
live-activity-before.mov

After:

  1. Ensure the .widget is in the list of disabled app hang types in the SentryExtensionDetector
  2. Perform steps 2 to 6 from the before test
  3. In the lockscreen it should display a live activity with "SDK Enabled? ✅" and "ANR Disabled? ✅ ) indicating that the ANR tracker is not installed anymore
  4. Unlock the simulator and go to the home screen (CMD + SHIFT + H, repeat 3x)
  5. It will display a ✅ left to the dynamic island indicating the SDK is enabled, but ✅ on the right side indicating that the ANR tracker is not installed
live-activity-after.mov

@philprime philprime self-assigned this Nov 4, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 11d7087

@codecov
Copy link

codecov bot commented Nov 4, 2025

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1218.48 ms 1246.26 ms 27.78 ms
Size 23.75 KiB 1.00 MiB 1001.61 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
d1c4916 1216.66 ms 1244.73 ms 28.08 ms
d1c0538 1227.49 ms 1246.96 ms 19.47 ms
cc02c0d 1234.69 ms 1247.15 ms 12.46 ms
23b6a91 1227.73 ms 1262.93 ms 35.20 ms
ea2e54c 1207.78 ms 1218.13 ms 10.35 ms
6c0b61e 1194.21 ms 1218.74 ms 24.53 ms
83d27f6 1233.56 ms 1259.24 ms 25.68 ms
1a34ddc 1217.79 ms 1242.17 ms 24.38 ms
d05d866 1211.78 ms 1230.96 ms 19.18 ms
bc0a04c 1226.83 ms 1255.04 ms 28.21 ms

App size

Revision Plain With Sentry Diff
d1c4916 23.75 KiB 981.31 KiB 957.56 KiB
d1c0538 23.75 KiB 928.87 KiB 905.12 KiB
cc02c0d 23.75 KiB 912.37 KiB 888.62 KiB
23b6a91 23.75 KiB 1004.80 KiB 981.06 KiB
ea2e54c 23.75 KiB 919.70 KiB 895.95 KiB
6c0b61e 23.75 KiB 1.02 MiB 1019.10 KiB
83d27f6 23.75 KiB 928.88 KiB 905.13 KiB
1a34ddc 23.75 KiB 919.90 KiB 896.15 KiB
d05d866 23.75 KiB 878.60 KiB 854.85 KiB
bc0a04c 23.75 KiB 933.32 KiB 909.57 KiB

Previous results on branch: philprime/disable-live-activity-widgets

Startup times

Revision Plain With Sentry Diff
10db8d4 1225.04 ms 1254.57 ms 29.53 ms
1171923 1232.80 ms 1251.69 ms 18.90 ms

App size

Revision Plain With Sentry Diff
10db8d4 23.75 KiB 1.00 MiB 1003.65 KiB
1171923 23.75 KiB 1.00 MiB 1001.57 KiB

@philprime philprime force-pushed the philprime/disable-live-activity-widgets branch from 095f7a8 to f8693fb Compare November 6, 2025 14:11
@philprime philprime changed the title feat(anr): Disable ANR tracking for widgets, live activities, and extensions feat(anr): Disable ANR tracking for widgets, live activities, action, intent and share extensions Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants