Connect IQ SDK

Entry Points And The Manifest File

All Connect IQ apps require a manifest file. The manifest file is an XML file that specifies application properties like the application type and the supported products. The manifest file is created automatically by the Eclipse plug-in, but it can be created hand as well:

<iq:manifest version="1">
    <iq:application entry="CommExample" id="a3421feed289106a538cb9547ab12095"
        name="AppName" launcherIcon="LauncherIcon" type="widget" minSdkVersion="1.3.1">

            <iq:product id="vivoactive"/>

            <iq:uses-permission id="Communications"/>


Application Attributes

The application element has a number of important attributes. The id field is a 128-bit UUID identifier. Unique identifiers can be generated with the UUID Generator or with standard tools.

The entry attribute must specify the Toybox.Application.AppBase object for your application.

The name and launcherIcon attributes must specify a resource ID that is defined in the app resources. If a launcherIcon isn’t specified a default icon will be compiled into the application.

The type field specifies what kind of application you are developing. Currently Connect IQ supports four types of apps:

  1. watchface
  2. datafield
  3. widget
  4. watch-app

The app type specified in the manifest file determines where your app appears on the device and which APIs the app can use.

The minSdkVersion field specifies the minimum Connect IQ SDK version that your app is compatible with, and serves to prevent you from targeting incompatible devices. The Eclipse plug-in allows you to select a minimum SDK version when creating a new app, or editing the properties of an existing one. Currently, the following versions are selectable when configuring your app:

  1. 1.2.x
  2. 1.3.x
  3. 2.1.x

The micro version is written out to the manifest at version 1 (1.2.1 for example), but only the major and minor versions are considered when determining device support.

Every application must include an Application object, which serves as the entry point for your application:

// AppBase is the base class for an app. All apps shall inherit from this
// class. It is used to manage the lifecycle of an app. For widgets and
// watch-apps, the functions are called in the following order: onStart(),
// getInitialView() and onStop(). For watchfaces and datafields, only
// getInitialView() is called. Every AppBase object has access to an object
// store to persist data.
class AppBase
    // Before the initial WatchUi.View is retrieved, onStart() is called.
    // This is where app level settings can be initialized or retrieved from
    // the object store before the initial View is created.
    function onStart(state);

    // To retrieve the initial WatchUi.View and WatchUi.InputDelegate
    // of the application, call getInitialView(). Providing a
    // WatchUi.InputDelegate is optional for widgets and watch-apps. For
    // watchfaces and datafields, an array containing just a WatchUi.View
    // should be returned as input is not available for these app types.
    // @return [Array] An array containing
    //     [ WatchUi.View, WatchUi.InputDelegate (optional) ]
    function getInitialView();

    // When the system is going to terminate an application, onStop() is called.
    // If the application needs to save state to the object store it should be
    // done in this function.
    function onStop(state);

    // To get the data associated with the given key from the object store,
    // use getProperty().
    // @param key Key of the value to retrieve from the object store
    //     (cannot be a Symbol)
    // @return [Object] Content associated with the key, or null if the key
    //     is not in the object store
    function getProperty( key );

    // Using a key, store the given data in the object by calling setProperty().
    // @param key The key used to store and retrieve the value from the object
    //     store (cannot be a Symbol)
    // @param [String] value The value to put into the object store
    function setProperty( key, value );

    // The GOAL_TYPE enum defines the different goal types that can be triggered.
        // @since 1.3.0
        GOAL_TYPE_STEPS             = 0,
        // @since 1.3.0
        // @since 1.3.0

    // Retrieves the WatchUi.View for a goal that has triggered within a watchface.
    // If a goal is reached when a watchface is running, this function will be triggered.
    // The type of goal that was met will be provided, and the AppBase should return
    // a View that displays a goal reached message and/or animations for that goal.
    // If a View is returned from this function, the main watchface view will be
    // shutdown, and then new View will pushed. If this method is not overridden
    // in the AppBase, or if it returns null, the native goal screens will be shown.
    // @param goalType [Number] The goal type that has triggered from. From the GOAL_TYPE_??? enumeration.
    // @return [Array] An array containing [ WatchUi.View ]
    // @since 1.3.0
    function getGoalView(goalType);

    // Retrieves the System.ServiceDelegate for running background tasks for this app.
    // The method that has been triggered within the ServiceDelegate will be run. The
    // background task will be automatically terminated after 30 seconds if it does
    // not exit before this time by using Background.exit() or System.exit().
    // @return [Array] An array containing [ System.ServiceDelegate ]
    // @since 2.3.0
    function getServiceDelegate()
        return null;

    // Passes data from a background process to the application. When the background process
    // termintates, a data payload can be passed. If the main application is active when this
    // occurs, the data will be passed directly to the applications onBackgroundData() method.
    // If the main application is not active, the data will be saved until the next time the
    // application is executed, and will be passed to the application after the onStart()
    // method completes.
    // @param data [Lang.Object] The data passed from the background process.
    // @since 2.3.0
    function onBackgroundData(data)
        return null;

The Eclipse plug-in will generate an Application object when a project is created.

An Application object should override getInitialView() to provide the view object to initially push. An array must be returned with either a view and a delegate, or just a one element array with the View object:

return [ new MyView(), new MyDelegate() ];

Goal Views (CIQ 1.3)

Watchfaces can define additional entry points, which are triggered when a activity goal is reached. These can include a goal for reaching a threshold of steps, floors climbed, or minutes of exercise. Watchfaces can return a view to display a goal screen or animation for some, all, or none of these goal types. If a goal view is not provided, the device will display a default goal animation. This feature is available only in devices running the 1.3.0 or 2.1.0 SDK or later.

Background Services (CIQ 2.3)

Applications can register for background services. Services can be registered to run when various events occur. These events include when the user reaches goal targets, when sleep and wake times occur, when a steps threshold is reached, or at a scheduled time. Modules available to background processes differ from those of their parent application.

When background services are started, the getServiceDelegate() is run from the Application object. This method returns a System.ServiceDelegate and the method corresponding to the event that triggered is invoked. Once a background service has finished any necessary tasks, it should exit using the Background.exit() method. This method takes a argument containing data to be sent to the main process. Use null to provide no data.

Services may be terminated at any time free memory for foreground applications. Services will also be terminated automatically if the do not exit properly within 30 seconds of opening.

In the Connect IQ simulator, an option has been added under the Simulation menu, which allows manually triggering background services. When manually triggering a service, the background service for the most recently run application will be loaded, and the corresponding call in the ServiceDelegate will be triggered regardless of whether the application has registered for that event.

This feature is available only in devices running the 2.3.0 SDK or later.


Garmin makes a wide variety of products for many use cases, and Monkey C makes it easy to write for all our Connect IQ compatible devices. Monkey C asks the developer which Connect IQ devices they choose to support because it is impossible to know whether a future product may be incompatible with your app. As new Connect IQ compatible products appear on the market, the simulator will be updated to support them so developers can decide whether to support them.

The SDK currently supports two imaginary products designed for general prototyping—a round-watch and a square-watch—along with all currently supported production devices (e.g. Forerunner 920XT, fēnix 3, etc.). The round watch is button only, and the square watch is a touch screen product with fewer buttons.

Products supported by an app are listed in the products block of the manifest file:

    <iq:product id="round-watch"/>


Certain modules expose personal information about the user or expose communication to the internet. To use these modules, permission must be requested from the user at installation time. To request permission, the module name must be added to the permissions list of the manifest file. The following modules require permission:

More modules may be added to this list as modules are added to the API. To request permission, use the following syntax in the manifest file:

    <iq:uses-permission id="Sensor"/>

Intents (2.2)

Intents allow a Connect IQ watch-app or widget to launch another Connect IQ watch-app, Connect IQ widget, or native application (e.g. built in activities like Run, Bike, etc.) by calling System.exitTo():

//! Exit the current app and launch a new app. This is an asynchronous request.
//! If the user chooses to launch the Intent then the app will be shut down. Otherwise
//! the app will continue to run. This can only be called by watch-apps and widgets.
//! @param [Intent] content The Intent to trigger
//! @raise [UnexpectedAppTypeException] If the app requested is not a watch-app or widget
//! @raise [AppNotInstalledException] If the application requested is not installed
//! @raise [PreviousOperationNotCompleteException] If exitTo is called a second time before completing
//! @since 2.2.0
native function exitTo(content);

Calling System.exitTo() will cause a confirmation view to be displayed asking the user whether to exit to the intended app. If the user chooses ‘No’ then the app that called System.exit() will continue to run. If the user chooses ‘Yes’ then the app will exit and the new app will launch. While the confirmation view is shown, originating app will continue to run.

Exiting to Connect IQ Apps

In order to exit to another Connect IQ app, a System.Intent must be created, which contains a target app identifier and any arguments you wish to pass to the target app. The target app identifier must be specified using one of two supported URI schemes:

Arguments are passsed to the target app as a dictionary, which may be empty or null, and are received by the target app’s onStart() method as a Dictionary object.

using Toybox.System as Sys;
var intent = new Sys.Intent("manifest-id://01234567-89AB-CDEF-0123-456789ABCDEF", {"lat"=>38.856419, "lon"=>-94.801369});

Assuming the target app is installed on the device, this example launches the app with manifest ID “01234567–89AB-CDEF–0123–456789ABCDEF” and passes it the “lat” and “lon” arguments.

Exiting to Native Apps

Intents to launch native apps deal exclusively with PersistedContent objects, such as Waypoints, Routes, and Tracks. Connect IQ handles most of the Intent functionality for native apps behind the scenes, automatically embedding the appropriate native app identifier in the PersistedContent object, which is accesible via the toIntent() method. See the Persisted Content section for more information.

Intent Exceptions

Connect IQ includes three exception types related to Intents:

App Trials (2.3)

The app trials feature allows developers who have gone through the appropriate approval process (see for details) to enable a special “trial” mode for their app. Enabling trial mode is accomplished by adding a new tag to the manifest under the application tag as follows:

<iq:application entry="CommExample" id="a3421feed289106a538cb9547ab12095"
        name="AppName" launcherIcon="LauncherIcon" type="widget" minSdkVersion="1.3.1">
    <iq:trialMode enable="true">

The unlock URL provides an endpoint for the app store to redirect the user to in order go through whatever you want your app “unlock” process to be. See details of requirements for how your endpoint needs to be set up at


The app trials feature is not supported for watchfaces.

Trial Mode Functionality

Developers can query the new isTrial() method in AppBase to determine if trial mode is active for their app, which can be used to trigger special trial-mode functionality. App trials can also be time-based. The method getTrialDaysRemaining() in AppBase should be overriden if you wish to support a time-based trial. getTrialDaysRemaining() must return a Number that represents how many days are remaining in the trial(or null if time-based trials are to be disabled), and if 0 is returned, the app will be prevented from running as the trial will be considered “expired”. By default, when an app is in trial mode, the system will push special trial notifications to the use either to inform them of how many days remain in their trial(if you’ve overridden getTrialDaysRemaining() to return a non-null value), or more generally that trial mode is active. If you do not wish for these notifications to be displayed to the user, you can override AppBase.allowTrialMessages() to return false.

Eclipse Plugin Support

The Eclipse plugin has been updated to support enabling app trial mode and setting the unlock URL via both the project properties page and the manifest editor. See the screenshots below for examples: