# UIKit

<figure><img src="https://1411608689-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCbCMt5C3rawmE9oIus7f%2Fuploads%2Fy3uoRm3imfeYJfxzubZY%2Fimage.png?alt=media&#x26;token=210c4029-66db-4d5a-9c7c-8dd0d0da8a07" alt=""><figcaption></figcaption></figure>

Maestro provides native, transparent support for iOS applications built with UIKit. Operating at the visual interaction layer rather than the implementation layer, Maestro interacts with rendered UI components regardless of underlying class hierarchies such as `UIButton`, `UITableView`, and `UILabel`.

### Technical advantages

* **Zero Instrumentation**: Maestro does not require test libraries, delegates, or ViewController exposure. You test the built `.app` binary, nothing else.
* **Implementation Agnostic**: Because Maestro validates user-facing features rather than internal code, you can refactor UIKit components to SwiftUI without breaking your tests, provided the visual output remains consistent.
* **Black-Box Model**: Maestro adopts an [arm's length](https://docs.maestro.dev/get-started/how-maestro-works) approach, simulating authentic user interactions with the rendered UI without needing access to internal source code.

### Element interaction strategies

Maestro interacts with UIKit components by simulating authentic user interactions through the accessibility layer.

#### **Interacting with views by text**

Primary interaction in UIKit is often done via visible UI text. Any view with text content (like a `UIButton` title) can be targeted directly.

```swift
// In your UIKit Swift code
let button = UIButton()
button.setTitle("Submit Order", for: .normal)
```

You can tap this button in your Flow using the visible text:

```yml
- tapOn: "Submit Order"
```

#### **Using accessibility labels and IDs**

For non-textual elements like icons, or for disambiguating duplicate elements, leverage iOS accessibility metadata. Maestro translates these properties into specific selectors:

* `accessibilityLabel`: Maestro translates this to the `text` selector.
* `accessibilityIdentifier`: Maestro translates this to the `id` selector. This is the gold standard for reliable tests.

```swift
// In your UIKit Swift code
let button = UIButton()
button.accessibilityIdentifier = "login_button_id"
```

The corresponding tap command in your Flow would use the `id`:

```yaml
- tapOn:
    id: "login_button_id"
```

### Handling lists and complex components

Maestro abstracts away the complexity of coordinate calculations and cell enumeration in `UITableView` and `UICollectionView`.

#### **Intelligent scrolling**

Instead of manual index or offset calculations, use `scrollUntilVisible`. Maestro combines visibility detection with continuous swiping to find elements that are currently off-screen.

```yaml
- scrollUntilVisible:
    element:
        text: "List Item 50"
    direction: DOWN
```

### Known limitations

* **Simulators**: Full support for local execution on iOS Simulators.
* **Physical Devices**: Executing tests on physical iOS devices is not supported yet.

### Next steps

If you don't know how to create tests with Maestro, access the [QuickStart](https://docs.maestro.dev/get-started/quickstart) guide to get up and running in minutes.

To learn how to create tests, refer to the [Flows](https://app.gitbook.com/s/mS3lsb9jRwfRHqddeRXG/) documentation. If you want to explore Maestro solutions, consult the appropriate documentation:

* [Maestro Studio](https://app.gitbook.com/s/eQi66gxHTt2vx4HjhM9V/)
* [Maestro CLI](https://app.gitbook.com/s/kq23kwiAeAnHkGJYMGDk/)
* [Maestro Cloud](https://app.gitbook.com/s/ky7LkNoLfvcORtXOzzBs/readme)
