Complication vs direct data access

When I only display data, what are the upsides/downsides of using the complications api vs directly accessing data like Activity.getActivityInfo().currentHeartRate?

Complications

  • I need to subsribe
  • I need to write a handler function
  • I need to save the last provided data in my watchface

Direct Access

  • I simply use the provided data

So in the case of only needing the data (no label), why should I use the complications api for system complications?

It seems that it does not provide any benefits but increases memory, size and time consumption of my watchface.

  • This is a great question and I agree with the points you made. Obviously one unmistakable benefit of the complications API, even for something like heart rate where there’s a simpler alternative to get the data, is that you can now support long-press to open the related system glance. But ofc even if you do that, you don’t need to use the complications API to get the data itself.

    Just to play devil’s advocate, here’s a couple of arguments for using the complications API to retrieve data:

    - Some data, such as training status or the various race predictor values, may not be available by other means

    - For a given data field on your watch face, if you are going to give the user the ability to select from all possible complication types (possibly including third party complications), then it may be simpler and cleaner to use the complications API for everything. Ofc this argument breaks down if there’s stuff you want to display that isn’t available via the complications API

    - Even for something like heart rate, it may be considered conceptually simpler (although not simpler in terms of amount of code) to use the complications API given that Activity.getActivityInfo().currentHeartRate is kind of a hacky, undocumented way of retrieving “live” HR for a watchface. i.e. if it’s null, then you have to fall back to sensor history. And it’s completely unavailable on watches like Fenix 5X. None of that stuff is documented afaik, unless you count the forums.

  • A little bit off topic, but I did not investigate this yet:

    How do I create a setting that allows the user to select from all available complications and some custom entries? Is this even possible? It seems this can only be done with on device settings and not by using the xml based properties/settings approach.

  • How do I create a setting that allows the user to select from all available complications and some custom entries
    It seems this can only be done with on device settings

    Yep I agree. Outside of the device, it's not possible to have dynamic settings, and even if it was possible, there'd be no way to enumerate 3rd party complications installed on the watch.

    Some CIQ watchfaces allow the user to enter the display name of a 3rd party complication in a text field, to support "off device" settings. Obviously the display name is not a unique ID, but there isn't really a better alternative afaik.

  • One really nice thing about complications, is the "onPress" functionality on touch devices.  Press the HR on the screen, and you see the HR widget and all the extra data it provides.  You actually only need minimal code for the complication.

    Here is a thread with an example of using them for Heart rate on devices with complications, and direct access for things that don't

    https://forums.garmin.com/developer/connect-iq/f/discussion/349473/simple-example-wf-that-shows-a-bunch-of-things

    When complications were first introduced, I wrote a simple app, where with on devices settings, any system complication can be selected by number as a way to see the data provided by any system complication.

    When it comes to CIQ publishers, you do need to know the name in the watchface.  Here's an example of a simple publisher and watch face that uses the published data.

    https://forums.garmin.com/developer/connect-iq/f/discussion/353286/sample-of-ciq-complication-publisher-and-consumer-of-those-complications

    In the real world, having on-device settings can be really handy for CIQ published data.  I have two different weather widgets (OWM and Weather Underground). and with my watch face, with on-device settings, it can detect if either or both widgets are installed, with the default being the Garmin weather data.  Smarts that using app-settings on the phone can't provide.

    Here's the watch face that does that, and that uses system complications (if available) for other things."Garmin" is the default weather source, but you see OWM or WU if you've installed one of my widgets.

    https://apps.garmin.com/apps/c051f37a-8fad-4907-b124-0112fe010c91

    The "onPress" ability is what brought about complications and why using them is very useful.  In the above WF, pressing on steps opens that widget, pressing on the notification icon opens that widget and allows see all of your notifications, pressing on weather, the correct weather widget is opened, etc.

  • One really nice thing about complications, is the "onPress" functionality on touch devices

    This one is nice but using the complications subscription api is not necessary to use this functionality.

    When it comes to CIQ publishers, you do need to know the name in the watchface.

    There is no way to query a list of installed publishers?

    I have two different weather widgets (OWM and Weather Underground)

    That's something really cool - I've been asked a few times already if I could support non garmin weather but I always said, that adding background data and internet permissions back to my watchface just for this single feature is not worth it. I could use your widgets directly instead - is that something your widgets are there for and would that be ok?

  • This one is nice but using the complications subscription api is not necessary to use this functionality.

    But you do need the complication ID for this..  And not just the number.

    That's something really cool - I've been asked a few times already if I could support non garmin weather but I always said, that adding background data and internet permissions back to my watchface just for this single feature is not worth it. I could use your widgets directly instead - is that something your widgets are there for and would that be ok?

    No problem at all.  In the case of my OWM widget I publish 3 complications that anyone can use:

    (temperature is always in C or F based on the watch setting for "temperature units")

    JmOwmTemp - just the temperature
    JmOwmTempTime - the temperature and the time the data was obtained

    JmOwmTempHumid - the temperature and current humidity
    (replace Owm in the above with "Wu" for the Weather Underground widget)
    In both I publish a 4th complication, but it's restricted and can only be used by my own apps.  That's what I use in the watch face I posted a link for.  It has a whole bunch of additional data, like rain, wind data, etc.)
    And by default, both only publish every 15 minutes.  Right after a successful makeWebRequest in the widgets background service.
  • When there's a choice between direct access and retrieving via complications I'm usually more concerned about which value is more up to date, device support and performance to a lesser degree.

    I think SensorHistory can lag by about a minute, I'm not sure about ActivityMonitor.

    You don't have to subscribe and use callbacks, although I'm not sure if doing it this way could have unintended consequences.

    function getTimeToRecovery() {
            if (ActivityMonitor.getInfo() has :timeToRecovery) {
                return ActivityMonitor.getInfo().timeToRecovery;
            }
    
            if (Toybox has :Complications) {
                var comp = Complications.getComplication(new Complications.Id(Complications.COMPLICATION_TYPE_RECOVERY_TIME));
                if (comp.value != null) {
                    return (comp.value / 60).toNumber();
                }
            }
    
            return "--";
        }
  • hi,

    interesting, Have you tried on real device? Does it display a data? Does it update?

  • Yes, it's working on a FR165 and VA5. Creating a new instance of a complication is probably less efficient / performant than instantiating it once and subscribing to updates though.

  • it's not just when the value changes, but when you can see it/display it.  With a watch face in low power (most of the time) you are stuck at once a minute.

    If you subscribe to a complication, it depends on the specific complication as far as when it updates.  Some update very often, some only when the value changes, and some are on a timer.  My weather widgets for example, only update once every 15 minutes by default