iOS · SwiftUI · SDK 0.0.24

# Alerts

Display in-app warning and error banners for service problems or other issues affecting your users.

Complete the [iOS quickstart](https://docs.mobilejoe.dev/ios/quickstart.md) first. These examples use your configured app and `MobileJoeUI`.

## Deliver an alert

1. Select your app in the [dashboard](https://app.mobilejoe.dev/) and open **Alerts**.
2. Create an alert with a title, optional message, **Warning** or **Error** kind, and occurrence date. Save it.
3. Open its audience settings. Choose **All users** , or **Filtered** with iOS app-version or OS-version values, then save.
4. Choose **Deliver → Deliver now**. The alert becomes live for matching app users. Archive it when the issue is resolved.

Filters match exact version strings. App versions use the app's version number, not its build number. OS versions include the patch component, such as `18.5.0`. When both iOS filters contain values, both must match. A filtered audience without any iOS values does not match iOS devices.

## Place the banners

Add `AlertsView()` where users should see alerts. This example places them above the screen's list:

```swift
import SwiftUI
import MobileJoeUI

struct HomeView: View {
  var body: some View {
    NavigationStack {
      List {
        Text("Your app content")
      }
      .navigationTitle("Home")
      .safeAreaInset(edge: .top, spacing: 0) {
        AlertsView()
          .padding(.horizontal)
      }
    }
  }
}
```

The view displays a banner for each returned alert and no banners when the list is empty. Kind determines its colors. Tapping a banner opens a detail sheet with the title, optional message, and occurrence date. Closing that sheet leaves the banner visible; there is no persistent per-user dismissal.

## Refresh and testing

`AlertsView` loads on appearance and when the app becomes active. Successful requests are spaced at least 15 minutes apart, so dashboard edits and archival take effect after the next eligible refresh. There is no automatic polling timer.

During integration, add `debugMode: true` to the configuration call shown in the quickstart to bypass this interval. Alerts marked for debug mode in the dashboard can then arrive before delivery and regardless of audience filters, except when archived. Debug mode still uses the live API. Test with debug mode disabled to verify production targeting.

## Use your own UI

Import `MobileJoe` and keep an observable `Alerts()` model in `@State`. Call `try await alerts.load()` on the main actor after configuration and read `alerts.all`. This uses the same refresh interval. Handle errors in your interface; the standard view does not display a loading error.

Pass a model to `AlertsView(alerts:)`, render individual banners with `AlertView(alert:)`, or build your own interface from each alert's `title`, `message`, `kind`, and `occurredAt`.

## Verify

Run the app, confirm your delivered alert appears, and open its details. Archive it, then trigger an eligible refresh and confirm it disappears. If missing, check the app's SDK key, live status, exact audience version values, and refresh interval. Also check that configuration completed successfully.
