---
title: "View Hierarchy"
description: "Learn more about debugging the view hierarchy when an error occurs. Sentry pairs the view hierarchy representation with the original event, giving you additional insight into issues."
url: https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy/
---

# View Hierarchy | Sentry for iOS

Sentry makes it possible to render a JSON representation of the view hierarchy of an error and includes it as an [attachment](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/attachments.md).

This feature only applies to SDKs with a user interface, such as the ones for mobile and desktop applications. In some environments like native iOS, rendering the view hierarchy requires the UI thread and in the event of a crash, that might not be available. Another example where the view hierarchy might not be available is when the event happens before the screen starts to load. So inherently, this feature is a best effort solution.

App hang events will not have view hierarchy because the main thread is blocked and Sentry can't interact with UI elements in a background thread.

Deobfuscation for view hierarchies is fully supported for native SDKs and React Native, but is currently not supported for Flutter.

View hierarchy support for SwiftUI is highly limited, due to the SwiftUI rendering engine not backing every view with a UIKit view anymore.

For example, `Text` views may be rendered directly into a graphics render surface rather than creating a corresponding `UILabel`. This is an operating system limitation, not a limitation of the Sentry SDK. As a result, the captured view hierarchy may not fully represent the SwiftUI view tree.

## [Enabling View Hierarchy Attachments](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy.md#enabling-view-hierarchy-attachments)

View hierarchy debugging is an opt-in feature. You can enable it as shown below:

```swift
import Sentry

SentrySDK.start { options in
  options.attachViewHierarchy = true
}
```

*Other available variations of the above snippet: Objective-C, Objective-C (SentryObjC)*

### [Customize View Hierarchy Capturing](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy.md#customize-view-hierarchy-capturing)

Requires Cocoa SDK version `8.33.0` or higher.

The `beforeCaptureViewHierarchy` also allows you to customize the behavior based on event data, so you can decide when to capture a view hierarchy and when not to. The callback doesn't work for crash events.

```swift
import Sentry

SentrySDK.start { options in
    options.dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>"
    options.beforeCaptureViewHierarchy = { _ in
        // Return false to not capture a view hierarchy for the event.
        return false
    }
}
```

*Other available variations of the above snippet: Objective-C, Objective-C (SentryObjC)*

## [Privacy In View Hierarchy Attachments](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy.md#privacy-in-view-hierarchy-attachments)

Sentry doesn't collect any user information (such as UILabel and UITextView text) with the view hierarchy attachment, which only contains structure and properties.

If you're using the view's `accessibilityIdentifier` property with personal information, make sure to disable `accessibilityIdentifier` reporting like in the example below:

```swift
import Sentry
SentrySDK.start { options in
  options.attachViewHierarchy = true
  options.reportAccessibilityIdentifier = false
}
```

*Other available variations of the above snippet: Objective-C, Objective-C (SentryObjC)*

## [View Hierarchy JSON Format](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy.md#view-hierarchy-json-format)

The SDK stores the hierarchy in a `view-hierarchy.json` attachment. The attachment uses the `application/json` content type and the `event.view_hierarchy` attachment type so Sentry can render it as an interactive hierarchy.

The following example contains one window, its view controller's root view, and a child view:

```json
{
  "rendering_system": "UIKIT",
  "windows": [
    {
      "type": "UIWindow",
      "identifier": "main-window",
      "width": 390,
      "height": 844,
      "x": 0,
      "y": 0,
      "alpha": 1,
      "visible": true,
      "children": [
        {
          "type": "UIView",
          "view_controller": "CheckoutViewController",
          "width": 390,
          "height": 844,
          "x": 0,
          "y": 0,
          "alpha": 1,
          "visible": true,
          "children": [
            {
              "type": "UIButton",
              "identifier": "submit-order",
              "width": 200,
              "height": 44,
              "x": 95,
              "y": 720,
              "alpha": 1,
              "visible": true,
              "children": []
            }
          ]
        }
      ]
    }
  ]
}
```

The root object contains these fields:

| Field              | Type   | Description                                                                                    |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------- |
| `rendering_system` | string | Rendering system that produced the hierarchy. The Apple SDK uses `UIKIT`.                      |
| `windows`          | array  | Top-level window nodes. Each window uses the same recursive node structure as its descendants. |

Each window or child node, except truncation markers, contains these fields:

| Field             | Type    | Required | Description                                                                                                                                 |
| ----------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`            | string  | Yes      | Runtime class name of the view, such as `UIWindow`, `UIView`, or `UIButton`.                                                                |
| `width`           | number  | Yes      | Width of the view's frame in points.                                                                                                        |
| `height`          | number  | Yes      | Height of the view's frame in points.                                                                                                       |
| `x`               | number  | Yes      | Horizontal origin of the view's frame in its containing coordinate space, in points.                                                        |
| `y`               | number  | Yes      | Vertical origin of the view's frame in its containing coordinate space, in points.                                                          |
| `alpha`           | number  | Yes      | Opacity of the view, from `0` for transparent to `1` for opaque.                                                                            |
| `visible`         | boolean | Yes      | Whether the view's `isHidden` property is `false`. This does not account for the visibility or alpha of ancestor views.                     |
| `children`        | array   | Yes      | Child views in UIKit subview order. An empty array indicates that the node has no child views.                                              |
| `identifier`      | string  | No       | The view's `accessibilityIdentifier`. The SDK omits this field when the identifier is empty or `reportAccessibilityIdentifier` is disabled. |
| `view_controller` | string  | No       | Runtime class name of the view controller when this node is the controller's root view.                                                     |

To keep captures bounded, the Apple SDK records up to 90 levels of nested views. When a view at that limit has child views, the SDK replaces those child views with a truncation marker:

```json
{
  "type": "SentryTruncatedViewHierarchy"
}
```

Truncation markers contain only the `type` field. The other required fields in the table above do not apply to these markers.

## [Viewing View Hierarchy Attachments](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy.md#viewing-view-hierarchy-attachments)

View hierarchies appear in the "Attachments" tab, where you can view all attachments, as well as associated events. Click the event ID to open the [Issue Details](https://docs.sentry.io/product/issues/issue-details.md) page of that specific event.

On the **Issue Details** page, you can interact with the view hierarchy attachment in a section called "View Hierarchy". This section represents the state of your application at the time of an error event. There are three displays: a tree view, wireframe, and detailed view for a selected node. Select a node in the tree or wireframe to inspect its [JSON fields](https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy.md#view-hierarchy-json-format). Use these displays to debug layout issues, find unnecessarily rendered content, or understand the relationship between views.
