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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions docs/platforms/apple/common/session-replay/customredact.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,58 @@ var body: some View {
}
```

## Ignore View Types from Subtree Traversal

Some view hierarchies contain layers that crash when accessed during traversal. For example, `CameraUI.ChromeSwiftUIView` on iOS 26+ contains `CameraUI.ModeLoupeLayer` instances that cause fatal errors when their `sublayers` property is accessed, resulting in crashes during session replay or screenshot capture.

To prevent these crashes, you can configure the SDK to skip traversing the subtree of specific view types while still redacting the view itself if needed.

### Default Behavior

On iOS 26+, `CameraUI.ChromeSwiftUIView` is automatically included in the ignore set by default to prevent crashes. On other platforms or iOS versions, the ignore set is empty by default.

### Adding View Types to Ignore List

You can add custom view types to the ignore set using the `excludeViewTypeFromSubtreeTraversal` method:

```swift
options.sessionReplay.excludeViewTypeFromSubtreeTraversal("MyProblematicView")
```

The view type identifier should match the result of `type(of: view).description()`, which typically follows the format `"ModuleName.ClassName"`.

### Removing View Types from Ignore List

If you need to remove a view type from the ignore set (not recommended for default values), you can use:

```swift
options.sessionReplay.includeViewTypeInSubtreeTraversal("CameraUI.ChromeSwiftUIView")
```

<Alert level="warning">

Removing default values like `CameraUI.ChromeSwiftUIView` from the ignore set may cause crashes on iOS 26+. Only do this if you understand the risks and have tested thoroughly.

</Alert>

### Dictionary Initialization

You can also configure ignored view types when initializing `SentryReplayOptions` from a dictionary:

```swift
let replayOptions = SentryReplayOptions(dictionary: [
"viewTypesIgnoredFromSubtreeTraversal": ["MyCustomView", "AnotherProblematicView"]
])
```

### How It Works

When a view type is ignored from subtree traversal:

- The view itself is still redacted (unless it's explicitly marked to be ignored, like `UISwitch`)
- The SDK skips traversing the view's subtree, preventing crashes from accessing problematic sublayers
- This prevents crashes while maintaining privacy protection for the view itself

## Debugging Session Replay masking

To see how elements are being masked, enable the masking preview from anywhere in your app. It will display an overlay on top of the masked elements. This works on the simulator and on device, as well as within Xcode Preview.
Expand Down
28 changes: 28 additions & 0 deletions docs/platforms/apple/common/session-replay/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,34 @@ final class SceneDelegate: NSObject, UIWindowSceneDelegate {

</Expandable>

<Expandable title="App crashes during Session Replay or screenshot capture" permalink>

If your app crashes during Session Replay recording or screenshot capture, it may be due to problematic view hierarchies that contain layers that crash when accessed during traversal.

### Common Causes

Some view types contain layers that cause fatal errors when their `sublayers` property is accessed. For example, `CameraUI.ChromeSwiftUIView` on iOS 26+ contains `CameraUI.ModeLoupeLayer` instances that crash during view hierarchy traversal.

### Solution: Ignore View Types from Subtree Traversal

You can prevent these crashes by configuring the SDK to skip traversing the subtree of problematic view types. The view itself will still be redacted, but the SDK won't attempt to traverse its children, preventing crashes.

To add a problematic view type to the ignore set:

```swift
options.sessionReplay.excludeViewTypeFromSubtreeTraversal("MyProblematicView")
```

The view type identifier should match the result of `type(of: view).description()`. You can find the exact type name by inspecting the view hierarchy or checking crash logs.

### Default Protection

On iOS 26+, `CameraUI.ChromeSwiftUIView` is automatically included in the ignore set by default to prevent crashes. If you're experiencing crashes with other view types, add them to the ignore set using the method above.

For more information, see the [Ignore View Types from Subtree Traversal](/platforms/apple/guides/ios/session-replay/customredact/#ignore-view-types-from-subtree-traversal) section in the custom masking documentation.

</Expandable>

<Expandable title="Masking limitations with AsyncDisplayKit/Texture" permalink>

[AsyncDisplayKit](https://github.com/facebookarchive/AsyncDisplayKit) (now archived) and its successor [Texture](https://github.com/texturegroup/texture/) use a custom rendering pipeline that relies on layers rather than standard UIKit components. This architecture prevents Session Replay's default masking options (`maskAllImages` and `maskAllText`) from working correctly.
Expand Down
Loading