# Overview

Source: https://docs.interop.io/desktop/capabilities/app-management/overview/index.html

## Overview

The App Management API provides a way to manage **io.Connect Desktop** apps. It offers abstractions for:

- App - an app as a logical entity, registered in **io.Connect Desktop** with some metadata (name, description, icon, etc.) and with all the configuration needed to spawn one or more instances of it. The App Management API provides facilities for retrieving app metadata and for detecting when an app is added or removed.

> ℹ️ *For details on how to define and configure an app, see the [Developers > Configuration > Application](https://docs.interop.io/desktop/developers/configuration/application/index.md) section.*

- Instance - a running copy of an app hosted in an io.Connect Window. The App Management API provides facilities for starting and stopping app instances and tracking events related to app instances.

![](https://docs.interop.io/desktop/images/app-management/app-management.mp4)

## App Stores

**io.Connect Desktop** can obtain app definitions from a local store, from a remote REST service, or from [**io.Manager**](https://docs.interop.io/manager/overview/index.md). It's also possible to enable and configure an in-memory app store.

To specify app stores with app definitions, use the `"appStores"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**. It accepts an array of objects defining one or more app stores.

In the standard **io.Connect Desktop** deployment model, app definitions aren't stored locally on the user machine, but are served remotely. If **io.Connect Desktop** is configured to use a remote app store, it will poll it periodically and discover new app definitions. The store implementation is usually connected to an entitlement system based on which different users can have different apps or versions of the same app. In effect, **io.Connect Desktop** lets users run multiple versions of the same app simultaneously and allows for seamless forward/backward app rolling.

> ⚠️ *Note that **io.Connect Desktop** respects the FDC3 standards and can retrieve standard io.Connect, as well as FDC3-compliant app definitions. For more details on working with FDC3-compliant apps, see the [FDC3 Compliance](https://docs.interop.io/desktop/getting-started/fdc3-compliance/index.md) section, the [FDC3 App Directory](https://fdc3.finos.org/docs/app-directory/overview) documentation and the [FDC3 Application](https://fdc3.finos.org/schemas/2.0/app-directory#tag/Application) schema.*

![](https://docs.interop.io/desktop/images/app-management/app-stores.png)

### Local

To configure **io.Connect Desktop** to load app definition files from a local path, set the `"type"` property of the app store configuration object to `"path"` and specify a relative or an absolute path to the app definitions. The environment variables set by **io.Connect Desktop** can also be used as values:

```json
{
    "appStores": [
        {
            "type": "path",
            "details": {
                "path": "./config/apps"
            }
        },
        {
            "type": "path",
            "details": {
                "path": "%IO_CD_USER_DATA_DIR%/apps"
            }
        }
    ]
}
```

Each local path app store object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"appDefinitionOverrides"` | `object` | Valid [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) properties that will override the ones in all app definitions from the app store. Top-level app definition properties can be specified directly in the `"appDefinitionOverrides"` object. The properties that are found under the `"details"` top-level key for each app definition type must be specified in a top-level object with the same name as the app type - `"window"`, `"exe"`, `"node"`, `"workspaces"`, `"webGroup"`, `"clickonce"`, `"citrix"` or `"childWindow"`. *Available since **io.Connect Desktop** 9.1.* |
| `"details"` | `object` | **Required.** Specific details about the app store. |
| `"isRequired"` | `boolean` | If `true` (default), the app store will be required. If the app store can't be retrieved, **io.Connect Desktop** will throw an error and shut down. If `false`, **io.Connect Desktop** will initiate normally, without apps from that store. |
| `"type"` | `string` | **Required.** Type of the app store. Must be set to `"path"` for local path app stores. |

The `"details"` object for a local path app store has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"path"` | `string` | **Required.** Must point to the local app store. The specified path can be absolute or relative and you can use defined environment variables. |
| `"trusted"` | `boolean` | If `true`, the app store will be trusted by the platform and the [security settings](https://docs.interop.io/desktop/getting-started/security/index.md) specified in the app definitions won't be overridden by the security settings specified in the system configuration. Defaults to `false`. *Available since **io.Connect Desktop** 9.10.1 & 10.0.3.* |

### REST

App definitions can also be obtained from remote app stores via a REST service.

To configure a connection to the REST service providing the remote app store, add a new entry to the `"appStores"` top-level key in the `system.json` file and set its `"type"` property to `"rest"`:

```json
{
    "appStores": [
        {
            "type": "rest",
            "details": {
                "url": "https://my-rest-service/apps",
                "auth": "no-auth",
                "pollInterval": 30000,
                "enablePersistentCache": true,
                "cacheFolder": "%LocalAppData%/interop.io/io.Connect Desktop/UserData/%IO_CD_ENV%-%IO_CD_REGION%/configCache/"
            },
            "appDefinitionOverrides": {
                // Overrides for some top-level app definition properties.
                "ignoreSavedLayout": true,
                "allowMultiple": false,
                // Overrides for the properties under the `"details"` top-level key in apps of type `"window"`.
                "window": {
                    "autoInjectAPI": {
                        "enabled": true,
                        "autoInit": {
                            "channels": true
                        }
                    }
                }
            }
        }
    ]
}
```

Each remote app store object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"appDefinitionOverrides"` | `object` | Valid [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) properties that will override the ones in all app definitions from the app store. Top-level app definition properties can be specified directly in the `"appDefinitionOverrides"` object. The properties that are found under the `"details"` top-level key for each app definition type must be specified in a top-level object with the same name as the app type - `"window"`, `"exe"`, `"node"`, `"workspaces"`, `"webGroup"`, `"clickonce"`, `"citrix"` or `"childWindow"`. *Available since **io.Connect Desktop** 9.1.* |
| `"details"` | `object` | **Required.** Specific details about the app store. |
| `"isRequired"` | `boolean` | If `true` (default), the app store will be required. If the app store can't be retrieved, **io.Connect Desktop** will throw an error and shut down. If `false`, **io.Connect Desktop** will initiate normally, without apps from that store. |
| `"type"` | `string` | **Required.** Type of the app store. Must be set to `"rest"` for remote app stores. |

The `"details"` object for a remote app store has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"auth"` | `string` | Authentication configuration. Can be one of `"no-auth"` (default), `"negotiate"` or `"kerberos"`. |
| `"cacheFolder"` | `string` | Location the persisted configuration files. |
| `"enablePersistentCache"` | `boolean` | If `true` (default), will cache and persist the configuration files locally (e.g., in case of connection interruptions). |
| `"pollInterval"` | `number` | Interval in milliseconds at which to poll the REST service for updates. Default is `60000`. |
| `"proxy"` | `string` | HTTP proxy to use when fetching data. |
| `"readCacheAfter"` | `number` | Interval in milliseconds after which to try to read the cache. Default is `30000`. |
| `"rejectUnauthorized"` | `boolean` | If `true` (default), SSL validation will be enabled for the REST server. |
| `"requestTimeout"` | `number` | Timeout in milliseconds to wait for a response from the REST server. Default is `20000`. |
| `"startRetries"` | `number` | Number of times **io.Connect Desktop** will try to connect to the REST server. Default is `5`. |
| `"startRetryInterval"` | `number` | Interval in milliseconds at which **io.Connect Desktop** will try to connect to the REST server. Default is `10000`. |
| `"trusted"` | `boolean` | If `true`, the app store will be trusted by the platform and the [security settings](https://docs.interop.io/desktop/getting-started/security/index.md) specified in the app definitions won't be overridden by the security settings specified in the system configuration. Defaults to `false`. *Available since **io.Connect Desktop** 9.10.1 & 10.0.3.* |
| `"url"` | `string` | **Required.** The URL to the REST service providing the app definitions. |

The remote store must return app definitions in the following response shape:

```json
{
    "applications": [
        // List of app definition objects.
        {}, {}
    ]
}
```

> ℹ️ *For details on working with remote app stores compliant with FDC3 App Directory standards, see the [FDC3 Compliance](https://docs.interop.io/desktop/getting-started/fdc3-compliance/index.md#app_directory) section and the [FDC3 App Directory](https://fdc3.finos.org/docs/app-directory/overview) documentation.*

> ℹ️ *For a reference implementation of a remote app definitions store, see the [Node.js REST Config](https://github.com/InteropIO/rest-config-example-node-js) example.*

### io.Manager

You can also use [**io.Manager**](https://docs.interop.io/manager/overview/index.md) for hosting and retrieving app definitions.

To configure **io.Connect Desktop** to fetch app definitions from **io.Manager**, set the `"type"` property of the app store configuration object to `"server"`:

```json
{
    "appStores": [
        {
            "type": "server"
        }
    ]
}
```

The server app store object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"appDefinitionOverrides"` | `object` | Valid [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) properties that will override the ones in all app definitions from the app store. Top-level app definition properties can be specified directly in the `"appDefinitionOverrides"` object. The properties that are found under the `"details"` top-level key for each app definition type must be specified in a top-level object with the same name as the app type - `"window"`, `"exe"`, `"node"`, `"workspaces"`, `"webGroup"`, `"clickonce"`, `"citrix"` or `"childWindow"`. *Available since **io.Connect Desktop** 9.1.* |
| `"isRequired"` | `boolean` | If `true` (default), the app store will be required. If the app store can't be retrieved, **io.Connect Desktop** will throw an error and shut down. If `false`, **io.Connect Desktop** will initiate normally, without apps from that store. |
| `"type"` | `string` | **Required.** Type of the app store. Must be set to `"server"` for app stores retrieved from **io.Manager**. |

If you are using only **io.Manager** for retrieving app definitions, you can set the `"appStores"` key to an empty array. **io.Connect Desktop** will automatically try to connect to **io.Manager** using the provided configuration and will retrieve the app definitions from it.

> ℹ️ *For details on how to configure **io.Connect Desktop** to connect to **io.Manager**, see the [io.Manager](https://docs.interop.io/desktop/capabilities/manager/index.md) section.*

### In-Memory

Available since io.Connect Desktop 10.0

The in-memory app store of **io.Connect Desktop** allows interop-enabled apps to import app definitions dynamically. To enable it and configure it, add a new entry to the `"appStores"` top-level key and set its `"type"` property to `"in-memory"`:

```json
{
    "appStores": [
        {
            "type": "in-memory",
            "details": {
                "allowedApps": ["my-app", "my-other-app"]
            }
        }
    ]
}
```

The in-memory app store object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"appDefinitionOverrides"` | `object` | Valid [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) properties that will override the ones in all app definitions from the app store. Top-level app definition properties can be specified directly in the `"appDefinitionOverrides"` object. The properties that are found under the `"details"` top-level key for each app definition type must be specified in a top-level object with the same name as the app type - `"window"`, `"exe"`, `"node"`, `"workspaces"`, `"webGroup"`, `"clickonce"`, `"citrix"` or `"childWindow"`. |
| `"details"` | `object` | Specific details about the app store. |
| `"isRequired"` | `boolean` | If `true` (default), the app store will be required. If the app store can't be retrieved, **io.Connect Desktop** will throw an error and shut down. If `false`, **io.Connect Desktop** will initiate normally, without apps from that store. |
| `"type"` | `string` | **Required.** Type of the app store. Must be set to `"in-memory"` for the in-memory app store. |

The `"details"` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"allowedApps"` | `string[]` | List of app names, as defined in the io.Connect framework, that will be allowed to use the in-memory app store. Provide `"*"` as a value to allow all apps to use the in-memory store (e.g., `["*"]`). Defaults to `["*"]` |

## System App Stores

Besides the regular app stores that usually contain definitions for end user apps, you can define system app stores for critical apps that must be auto started with the platform. The system stores aren't monitored for changes and can be only of type `"path"` and `"rest"`. To define a system app store, use the `"systemAppStores"` top-level key in the `system.json` file, which accepts an array of objects defining one or more system app stores.

The following example demonstrates how to configure a local system app store:

```json
{
    "systemAppStores": [
        {
            "type": "path",
            "details": {
                "path": "./config/system-apps"
            }
        }
    ]
}
```

> ℹ️ *For details on how to set the priority of system apps, see the [Developers > Configuration > Application > Boot Sequence](https://docs.interop.io/desktop/developers/configuration/application/index.md#boot_sequence) section.*

## App Titles

The titles of io.Connect apps (web and native) can be specified in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md). The titles of io.Connect Windows hosting the app instances can be [modified programmatically or manually](#app_titles-modifying_titles) by the user. For web apps, you can instruct **io.Connect Desktop** to [persist the custom titles](#app_titles-persisting_custom_titles) of their instances when the user saves them in a [Layout](https://docs.interop.io/desktop/capabilities/windows/layouts/overview/index.md), and you can also define the behavior for [synchronizing the window title with the document title](#app_titles-synchronizing_titles). It's also possible to define a default [title format](#app_titles-title_format) for all io.Connect app instances.

> ℹ️ *For details on configuring and manipulating the titles of individual windows and window groups, see the [Windows > Window Management > Overview > Group & Window Titles](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md#group__window_titles) section.*

> ℹ️ *For details on how to specify a default taskbar title for tab groups and how to display the title of the selected tab in the Windows taskbar, see the [Default Windows Taskbar Title](https://docs.interop.io/desktop/developers/configuration/system/index.md#window_management-window_groups-default_windows_taskbar_title) and the [Selected Tab Title](https://docs.interop.io/desktop/developers/configuration/system/index.md#window_management-window_groups-selected_tab_title) sections in [Developers > Configuration > System > Window Management > Window Groups](https://docs.interop.io/desktop/developers/configuration/system/index.md#window_management-window_groups).*

### App Definition

The app title set in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) will be displayed as an app title in the [io.Connect launcher](https://docs.interop.io/desktop/capabilities/launcher/index.md) and will be used as a default window title for the instances of native apps, as well as for the instances of web apps that don't already have a document title. To specify an app title, use the `"title"` top-level key in the app definition:

```json
{
    "title": "My App",
    "name": "my-app",
    "type": "window",
    "details": {
        "url": "https://my-app.com"
    }
}
```

### Modifying Titles

Users can modify the titles of app instances manually by double clicking on the window title:

![Modifying Window Titles](https://docs.interop.io/desktop/images/window-management/renaming-individual-windows.mp4)

The io.Connect APIs enable you to modify window titles programmatically. The following example demonstrates customizing the window title via the io.Connect JavaScript API by using the [`setTitle()`](https://docs.interop.io/desktop/reference/javascript/windows/ioconnectwindow/index.md#IOConnectWindow-setTitle) method of the [`IOConnectWindow`](https://docs.interop.io/desktop/reference/javascript/windows/ioconnectwindow/index.md) object:

```javascript
const myWindow = io.windows.my();

await myWindow.setTitle("New Title");
```

### Persisting Custom Titles

It's possible to instruct **io.Connect Desktop** to persist the custom titles of web app instances when the user saves their app arrangement in a Layout. To specify global settings for the desired behavior, use the `"title"` property of the `"saveInLayout"` object under the `"windows"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md#window_settings-persisting_data_in_layouts) file of **io.Connect Desktop**. To specify settings per app, use the `"title"` property of the `"saveInLayout"` object under the `"details"` top-level key in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md#persisting_data_in_layouts). This property accepts either a Boolean value or a list of Layout types for which to persist the custom title. The settings in the app definition will override the global system configuration.

Providing global settings for persisting app titles:

```json
{
    "windows": {
        "saveInLayout": {
            "title": ["Global", "Workspace"]
        }
    }
}
```

Overriding the global system settings per app:

```json
{
    "details": {
        "saveInLayout": {
            "title": false
        }
    }
}
```

### Synchronizing Titles

Titles of web app instances and Workspaces App instances can be synchronized with the document title whenever the document title changes. To specify global settings for the desired behavior, use the `"syncTitleWithDocumentTitle"` property of the `"windows"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**. To specify settings per app, use the `"syncTitleWithDocumentTitle"` property of the `"details"` top-level key in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md). The settings in the app definition will override the global system configuration.

Providing global settings for synchronizing app titles:

```json
{
    "windows": {
        "syncTitleWithDocumentTitle": true
    }
}
```

Overriding the global system settings per app:

```json
{
    "details": {
        "syncTitleWithDocumentTitle": false
    }
}
```

Available since io.Connect Desktop 9.4

The `"syncTitleWithDocumentTitle"` property also accepts a `"preserveCustomTitle"` string as a value. If set to `"preserveCustomTitle"`, the window title will be synchronized with the document title until the moment the user or the API sets a custom title for the window. After that, the custom title will be preserved and the window title won't be synchronized with the document title.

```json
{
    "details": {
        "syncTitleWithDocumentTitle": "preserveCustomTitle"
    }
}
```

### Title Priority

Available since io.Connect Desktop 9.16 & 10.4

The title of an io.Connect window can be set from several sources - the user (by editing the window title manually), the io.Connect API, the HTML document of the app, and the app definition. It's possible to define explicitly the title priority - the order in which the platform will consider these sources when determining the effective window title.

To specify the priority order, use the `"titlePriority"` property of the `"details"` top-level key in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md):

```json
{
    "name": "my-app",
    "type": "window",
    "title": "My App",
    "details": {
        "url": "https://example.com/my-app",
        "titlePriority": ["custom", "user", "config", "document"]
    }
}
```

The first source in the array that has a value will be used as the window title. Sources omitted from the array will be entirely ignored. Sources with no value (`undefined` or an empty string) will be skipped. If none of the listed sources has a value, the window title will be an empty string.

The `"titlePriority"` property accepts an array with the following values:

| Value | Description |
|-------|-------------|
| `"config"` | The title specified in the app definition. |
| `"custom"` | The title specified dynamically via the io.Connect API. |
| `"document"` | The title specified in the HTML document of the app. |
| `"user"` | The title specified by the user by editing the window title manually. |

If the `"titlePriority"` property isn't specified, the default priority order is `["user", "custom", "document", "config"]`. If the `"syncTitleWithDocumentTitle"` property is set to `"preserveCustomTitle"`, the default priority order is `["custom", "user", "document", "config"]`.

> ⚠️ *Note that the `"titlePriority"` property takes precedence over the `"syncTitleWithDocumentTitle"` property. If `"titlePriority"` isn't specified, the existing title behavior will be preserved.*

### Title Format

To set a format for the titles of app instances, use the `"titleFormat"` property of the `"applications"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**. The supported macros are `{title}` and `{instanceIndex}`. The `{title}` macro will be substituted with the title set in the app definition and the `{instanceIndex}` macro will be substituted with the consecutive number of the started app instance which is incremented for each new app instance starting from `1`. If all instances are closed, the counter is reset. If some instances are closed while others are still running, the counter will continue to increment accordingly:

```json
{
    "applications": {
        "titleFormat": "{title} ({instanceIndex})"
    }
}
```

![Title format](https://docs.interop.io/desktop/images/system-configuration/title-format.png)

> ⚠️ *Note that if the window title is set programmatically via the io.Connect APIs, the specified title format will be overridden. For web apps and Workspaces Apps, the `"syncTitleWithDocumentTitle"` property will override the specified title format.*
