Skip to main content

Mobile Generic Event Listener

· 8 min read
Kenneth Walker
Software Developer

VertiGIS Studio Mobile 5.22 includes an exciting new capability for working with commands, operations, and events. This capability allows app authors to execute custom, configured actions in response to events raised in Mobile. To opt in to this behavior, app authors register an event listener (subscriber) for any given Mobile event. When this event is raised in Mobile, the corresponding configured command or operation is invoked.

note

To use these new features, you will need a 5.22+ version of VertiGIS Studio Mobile.

The new events capability can be exercised in a few ways:

Want a complete list of events?

Check out the Events for the complete list of eligible events that can be listened to.

Register a Listener

To get started, you'll want to introduce a new item $type into your app.json configuration: the event-listener. Today, you'll need to manually configure this app item and any respective listeners. Support for configuring listeners through Designer will be coming soon.

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
// ... to be populated with listeners ...
]
}

Wire up a new Listener

With the new event-listener app item, you register a listener to a given event and respond with a configured action. Below, we're taking advantage of the map.viewpoint-changed event. In particular, it's configured with the highlights.clear command. When you pan the map, the map.viewpoint-changed event is raised, and in turn, our highlights.clear command is executed. No more highlights when we pan!

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "map.viewpoint-changed",
"action": "highlights.clear"
}
// ... more listeners ...
]
}

Of course, multiple listeners may be registered. They can listen to both distinct or duplicate events:

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "map.viewpoint-changed",
"action": "highlights.clear"
},
{
"event": "map.viewpoint-changed",
"action": "highlights.clear-focus"
},
{
"event": "layers.visibility-changed",
"action": "log-viewer.display"
}
// ... more listeners ...
]
}
Warning

The event listener capability is only available after the map has begun initializing. Listeners for events that fire before the map.initializing event will not trigger any actions.

Command Chaining

We can pair event listening with Command Chains to react with multiple actions chained together. In the example below, we'll react to a map pan by both clearing highlights and closing the panel. Notice that we can mix the use of simple syntax with the dictionary syntax that can optionally provide arguments.

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "map.viewpoint-changed",
"action": [
"highlights.clear",
{
"name": "panel.close-host-panel",
"arguments": {}
}
]
}
// ... more listeners ...
]
}

Specify A Sender

Use the sender property to configure the listener such that it only reacts to those events that originate from the specified sender. A sender could correspond to a given component or service. Specifying the sender is optional.

Take the example below where two map-extensions are configured. Since sender is specified as "map-config-1", viewpoint changed events raised from this map will result in highlights being cleared. Viewpoint changed events raised from "map-config-2" are effectively ignored.

{
"$type": "map-extension",
"id": "map-config-1",
"webMap": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1"
// ...
},
{
"$type": "map-extension",
"id": "map-config-2",
"webMap": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2"
// ...
},

// ...

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "map.viewpoint-changed",
"sender": "item://map-extension/map-config-1",
"action": ["highlights.clear"]
},
// ... more listeners ...
]
}
note

If the sender is omitted, any instance of the raised event will trigger the configured action.

Workflows and Context

Using this new capability, you can also configure a Studio Workflow as an action to invoke in response to an event being raised.

Want to learn more about Studio Workflow?

Check out the overview to learn more about Studio Workflow.

Below, we'll configure a workflow.run action and listen to a layers.visibility-changed event. Notice that we can specify arguments for our action, which in this case, will be the id of a $type: "workflow" item in app.json configuration.

In this example, toggling an entry in the layer list will invoke the configured workflow.

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "layers.visibility-changed",
"action": {
"name": "workflow.run",
"arguments": {
"id": "visibility-workflow" // this id corresponds to the id of the workflow item that we want to invoke
}
}
},
// ... more listeners ...
]
},

// ...

{
// The corresponding Workflow that we want to invoke in response to an event.
"$type": "workflow",
"id": "visibility-workflow",
"title": "My Visibility Workflow",
"target": "auto",
"portalItem": "https://www.arcgis.com/sharing/rest/content/items/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"commandArgumentInput": "context"
},

A Workflow with Context

Running a Workflow is a powerful way to react to events raised during an app session. Pairing a Workflow with the context capability gives us an opportunity to use an input from the event in the Workflow activity.

Notice below that the Workflow item specifies a commandArgumentInput value of context:

{
"$type": "workflow",
"commandArgumentInput": "context"
// ...
},

Using the layers.visibility-changed event, we configure a Workflow as an action, being mindful of the commandArgumentInput.

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "layers.visibility-changed",
"action": {
"name": "workflow.run",
"arguments": {
"id": "visibility-workflow" // this id corresponds to the id of the workflow item that we want to invoke
}
}
},
// ... more listeners ...
]
},

// ...

{
// The corresponding Workflow that we want to invoke in response to an event.
"$type": "workflow",
"id": "visibility-workflow",
"title": "My Visibility Workflow",
"target": "auto",
"portalItem": "https://www.arcgis.com/sharing/rest/content/items/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"commandArgumentInput": "context"
},

By specifying the context, we're able to retrieve an input value within a Workflow using the Get Workflow Inputs activity.

In our Workflow, we would want to run Get Workflow Inputs as our first activity to retrieve the input. Once we have the input as an object in our Workflow, we can access the context to start working with the input.

In the case of the layers.visibility-changed event, we're able to retrieve and work with the LayerContent as an input to our Workflow. Below is an example of how to access the LayerContent from the context and get at the id, which could then be used in any subsequent activity, for example an alert or a query:

=$getWorkflowInputs1.inputs.context.LayerContent.id.toString()
Important

The value provided to commandArgumentInput and the accessor used within the Get Workflow Inputs activity object must match to correctly access an input (i.e. both context in this example).

Raise Custom Events

While Mobile exposes a number of events that may be listened to, there are times where it would be beneficial to respond to events that aren't raised out of the box. Fortunately, there are also capabilities that allow app authors to raise custom events.

Raise Event through Action

Using the new viewer.publish-event command, a custom event can be raised. This action can be configured anywhere in the app that supports actions, like buttons, hooks, command chains, etc. Below is an example of a configured button action:

"action": {
"name": "viewer.publish-event",
"arguments": {
"name": "custom.raised-event",
"arguments": {}
}
}

Raise Event through Workflow

But what if we want to raise a custom event during execution of a Workflow? Using the Publish Event activity, it's possible to raise a custom event from anywhere in your Workflow logic. Simply provide the same custom event name to the Event Name input in the Publish Event activity. Arguments may also be provided. For the above example, that would be:

custom.raised-event
note

Although not recommended, it's also possible to use the viewer.publish-event command and the Publish Event activity to manually publish well-known Mobile events, i.e. map.viewpoint-changed.

Subscribe to Custom Event

Of course, publishing these events is only one side of the capabilities. Using the same mechanism introduced above, these custom raised events can be listened to, and configured with an action to invoke.

{
"$type": "event-listener",
"id": "custom-event-listener",
"listeners": [
{
"event": "custom.raised-event",
"action": "..."
}
]
}

Custom events could in turn raise more events with the viewer.publish-event, which could in turn be listened to. Together, the publishing and listening capabilities offer flexibility to respond to custom events with configured actions.

In Closing

We're excited to showcase these new capabilities for commands, operations, and events. We hope app authors can take advantage of them to create more responsive and exciting applications. Happy building!