# In-App Automation

Integrate options for In-App Automation (IAA) customization.

In-App Automation (IAA) powers banner, modal, and fullscreen in-app messages.

## Customization 

Various options are available for customizing the container view for In-App Automation content via the native SDKs.

Scenes are fully customizable in the dashboard and cannot be customized via the SDK.


## Styles

Plists can be used to modify any of the default message styles that the SDK provides. Each message type can be customized with a different plist:

- **Banner**: `UAInAppMessageBannerStyle.plist`
- **HTML**: `UAInAppMessageHTMLStyle.plist`
- **FullScreen**: `UAInAppMessageFullScreenStyle.plist`
- **Modal**: `UAInAppMessageModalStyle.plist`

These plists support the following values:

- **Banner**
   - `additionalPadding`: _Padding_. Adds padding around the view.
   - `headerStyle`: _Text Style_. Customizes the message's header.
   - `bodyStyle`: _Text Style_. Customizes the message's body.
   - `mediaStyle`: _Media Style_. Customizes the message's media.
   - `buttonStyle`: _Buttons Style_. Customizes the message's buttons.
   - `maxWidth`: _Points_. Max width.
   - `tapOpacity`: _Tap Opacity_. Customizes the message's opacity it's tapped and a tap action is present.
   - `shadowStyle`: _Shadow Style_. Customizes the message's shadow.

- **FullScreen**
   - `headerStyle`: _Text Style_. Customizes the banner's header.
   - `bodyStyle`: _Text Style_. Customizes the banner's body.
   - `mediaStyle`: _Media Style_. Customizes the banner's media.
   - `buttonStyle`: _Buttons Style_. Customizes the banner's buttons.
   - `dismissIconResource`: String. Resource name for a custom dismiss icon.

- **Modal**
   - `additionalPadding`: _Padding_. Adds padding around the view.
   - `headerStyle`: _Text Style_. Customizes the banner's header.
   - `bodyStyle`: _Text Style_. Customizes the banner's body.
   - `mediaStyle`: _Media Style_. Customizes the banner's media.
   - `buttonStyle`: _Buttons Style_. Customizes the banner's buttons.
   - `dismissIconResource`: String. Resource name for a custom dismiss icon.
   - `maxWidth`: _Points_. Max width.
   - `maxHeight`: _Points_. Max height.
   - `extendFullScreenLargeDevice`: _Boolean_. True to allow the option 'Display fullscreen on small screen device' to extend to large devices as well.

- **HTML**
   - `additionalPadding`: _Padding_. Adds padding around the view.
   - `dismissIconResource`: String. Resource name for a custom dismiss icon.
   - `maxWidth`: _Points_. Max width.
   - `maxHeight`: _Points_. Max height.
   - `extendFullScreenLargeDevice`: _Boolean_. True to allow the option 'Display fullscreen on small screen device' to extend to large devices as well.

- **Padding**
   - `top`: _Points_. Top padding.
   - `bottom`: _Points_. Bottom padding.
   - `leading`: _Points_. Leading padding.
   - `trailing`: _Points_. Trailing padding.

- **Buttons Style**
   - `additionalPadding`: _Padding_. Adds padding around the button area.
   - `buttonHeight`: _Points_. Button height.
   - `stackedButtonSpacing`: _Points_. Button spacing in the stacked layout.
   - `separatedButtonSpacing`: _Points_. Button spacing in the separated layout.
   - `borderWidth`: _Points_. Button's border width.
   - `buttonTextStyle`: _Text Style_. Text style for each button.

- **Text Style**
   - `additionalPadding`: _Padding_. Adds padding around the view.
   - `letterSpacing`: _Points_. Spacing between the letters.
   - `lineSpacing`: _Points_. Spacing between lines.

- **Media Style**
   - `additionalPadding`: _Padding_. Adds padding around the view.

- **Shadow Style**
   - `colorHex`: _Color_. Shadow color.
   - `radius`: _Points_. Shadow radius.
   - `xOffset`: _Points_. Shadow x-axis offset.
   - `yOffset`: _Points_. Shadow y-axis offset.

## Fonts

You can use custom fonts in your in-app messages by adding them to your app bundle and configuring them in the Airship dashboard.

### Custom Fonts

Fonts added to the app bundle are available for use with in-app messaging. To add
fonts, please read the [The UIKit Custom Fonts Guide](https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app).
![iOS Custom Font](https://www.airship.com/docs/images/ios/ios-custom-font_hu_abb515eea5dfec6b.webp)

*iOS Custom Font*

After adding fonts to your app, create a Font Stack in the Airship dashboard by following the steps in [Setting brand guidelines](https://www.airship.com/docs/guides/messaging/features/brand-guidelines/). Then you can select the stack when [setting in-app message defaults](https://www.airship.com/docs/guides/messaging/in-app-experiences/configuration/defaults/) and creating in-app messages.

### Dynamic fonts With HTML in-app messages

Most In-App message styles support automatically scaling fonts through the use of Dynamic Type.
However, automatically scaling fonts in HTML In-App messages requires
you to use the following Apple system fonts when specifying the CSS font property:
- `-apple-system-body`
- `-apple-system-headline`
- `-apple-system-subheadline`
- `-apple-system-caption1`
- `-apple-system-caption2`
- `-apple-system-footnote`
- `-apple-system-short-body`
- `-apple-system-short-headline`
- `-apple-system-short-subheadline`
- `-apple-system-short-caption1`
- `-apple-system-short-footnote`
- `-apple-system-tall-body`

For example, to have the HTML body default to the Apple system font body style:

```html
body {
    font: -apple-system-body; // available on Apple devices only
}
```


For more information about dynamic type, please see this [WWDC video](https://developer.apple.com/videos/play/wwdc2017/245/).

## Customizing HTML In-App Messages

> **Note:** In order for the Airship JavaScript interface to be loaded into the webview, the URL must be specified in the URL Allowlist. See [Advanced Integration](https://www.airship.com/docs/developer/sdk-integration/apple/installation/advanced-integration/#url-allowlist) for configuration details.


HTML in-app messages provide a way to display custom content inside a native web view. These types of in-app messages display with a dismiss button built in, but can also be customized to provide their own buttons capable of dismissing the view. Dismissing a view requires calling the dismiss function on the UAirship JavaScript interface with a button resolution object passed in as a parameter. The button resolution object is a JSON object containing information about the interaction type and the button performing the dismissal. It should match the following format:

```javascript
{
    "type" : "button_click",
    "button_info" : {
        "id" : "button identifier",
        "label" : {"text": "foo"}
    }
}
```


The button resolution requires each of the key fields shown above. These include:

- `type` — The type key with the value of resolution type `button_click`
- `button_info` — The button info object containing required id and label fields
    - `id` — The button identifier
    - `label` — Label object containing the required text key
        - `text` — The text key with a string value representing the label text

Providing a basic dismiss button in HTML:

```html
<button onclick="UAirship.dismiss({
    'type' : 'button_click',
    'button_info' : {
        'id' : 'button identifier',
        'label' : {'text' : 'foo'}
    }
}
);">Dismiss with resolution</button>
```


## Custom adapters

Providing an adapter allows defining the behavior of the custom type or overriding
any of the default message types. The adapter will be created by the in-app messaging
manager when a message's schedule is triggered. Once created, the adapter can define when
the message is ready to display and the display behavior.

After the message is displayed, the caller of the display method must be notified
that the message is finished displaying by returning a `CustomDisplayResolution` when
finished. This will allow for subsequent in-app messages to be displayed.

**Example custom banner adapter**


```swift
final class CustomBannerAdapter: CustomDisplayAdapter {

    private let message: InAppMessage
    private let assets: AirshipCachedAssetsProtocol

    init(message: InAppMessage, assets: any AirshipCachedAssetsProtocol) {
        self.message = message
        self.assets = assets
    }

    @MainActor
    var isReady: Bool {
        get {
            /// Called before display
            return true
        }
    }

    @MainActor
    func waitForReady() async {
        // If `isReady` is false this will be called  to wait for the
        // adapter to be ready
    }
    
    @MainActor
    func display(scene: UIWindowScene) async -> CustomDisplayResolution {
        return await withCheckedContinuation { continuation  in
            ///  After displaying call the continuation  with the result
            continuation.resume(returning: .userDismissed)
        }
    }
}
```


**Register a factory block to return the adapter**

```swift
/// Set the factory block after takeOff
InAppAutomation.shared.inAppMessaging.setAdapterFactoryBlock(forType: .banner) { message, assets in
    return CustomBannerAdapter(message: message, assets: assets)
}
```



