Acknowledged

Given that a newer SDK is required to build for CIQ 5.x devices, what does this mean for existing apps on devices that were upgraded from CIQ 4 to CIQ 5 (e.g. FR955, Fenix 7, etc)? Do these apps just break?

Background:

- it has always by my understanding that if you build an app for a device with a given SDK, then that app should continue to work regardless of future firmware updates (in general). This ofc excludes situations where:

  - the new firmware update has a bug or breaking change

  - the existing app has a dormant bug which is exposed by a legit change in new firmware. e.g. newer firmware has a change where Weather.CurrentConditions.observationLocationName is null, and this caused several existing watchfaces to crash because they assume that field will never be null. But that's an application error, since that field has always been typed to be possibly null

- CIQ 5.* devices require various 7.X (or 8.X) SDKs to run properly

- Compilers have a check to ensure you don't try to build a a too-new device with a too-old device

- Due to a bug in this check, where older compilers (pre 7.2.0) seem to incorrectly believe that SDK version X can build any device with CIQ version X (or lower), it's possible for an SDK 6.X compiler to build an app for CIQ 5 devices. However, it's very possible that such an app will crash when it's run in the simulator or the device (we've already seen "bug reports" about this

- The existing crop of devices that came out with CIQ 4 (e.g. fr955, fr965, fenix7) have all been updated to CIQ 5. As far as I know, this is the first time that existing devices have received a major CIQ update since the move from CIQ 1 to CIQ 2.

- Someone in the CIQ team already clarified that CIQ 5 devices require apps to be built with newer SDKs.

So here's what I don't understand.

The two following statements seem to be mutually exclusive:

- If an app is built for a device with an existing SDK (e.g. SDK 6.4.0) it will continue (in general) to work on the device for all future firmware updates

- Devices with CIQ 5.* require a 7.X or 8.X SDK

The problem is that it was entirely possible to build an app for an fr955 (for example) with SDK 6.4.0 in the past, when fr955 was only on CIQ 4. If I installed such an app on my fr955 when it had CIQ 4, it would expect it to continue to work now that my device is on CIQ 5.

So how can it be possible that going forward, a 7.X or 8.X SDK is required to build for my fr955?

What am I missing? Has something also changed with the device files that's relevant here?

  • > it means that backward compatibility is ensured

    I used to believe this, but if I was still 100% sure about this, I wouldn't have opened this bug report.

    If CIQ 6.* SDKs cannot build for CIQ 5 devices, but CIQ 6.* can build for CIQ 4 devices, then it doesn't seem possible that to say that CIQ 5 is backwards compatible with old SDKs/apps, since existing CIQ 4 devices have received an update for CIQ 5.

    Even in the SDKs with the broken compatibility check, there is a file compilerInfo.xml which lists targetSdkVersions (should really be called targetApiVersions, but ofc there was a time when API version and SDK version were more or less synonymous / in -sync.)

    We can see from compilerInfo.xml that:

    - SDK 6.4.2 supports APIs 1.2.0 - 4.2.0

    - The SDK 7.0.* betas and 7.1.0 RC were the first to support 5.0.0

    - SDK 7.1.1 was the first production SDK to support 5.0.0.

    - SDK 7.3.0 was the first to support 5.0.1.

    - 7.4.1 (unreleased) seems to incorrectly have support for 5.1.0

    - 7.4.3 no longer has support for 5.1.0

    - 8.0.0 beta is the first SDK to actually support 5.1.0

    Note that the corresponding compiler/device check was broken until 7.2.0. In SDKs prior to 7.2.0, the compiler apparently just incorrectly assumed that SDK version = API version, so that if you had SDK version X, it should automatically be able to build devices with API X or lower. This is why SDK 6.4.0 can incorrectly build for API 5.* and SDK 7.1.1 can incorrectly build for API 5.0.1.

    Anyway, going back to my original argument:

    - my fr955 now has CIQ API 5.1.0 (I'm in the beta program)

    - previously it had API 5.0.0 (and this is how it's configured now in fr955/compiler.json)

    - even earlier (when I bought it about 2 years ago), it had API 4.x.

    When my fr955 had API 4.x, SDKs such as 6.* would happily build for it

    Now that my fr955 has API 5.0.0 in compiler.json:

    - SDKs 6.* should *not* be able to build for it (based on the above information),  but they will, because of the bug mentioned above. But the CIQ team has already clarified that CIQ 5.* devices require one of the latest SDKs (not SDK 6.*) for sure

    - When CIQ 5.1.0 comes out of beta and is widely released, I assume the connectIqVersion value in the device file (fr955/compiler.json) will eventually be updated to 5.1.0.

    - At this point, SDKs 7.2 - 7.4.3 (excluded the broken 7.4.1) should refuse to build for my fr955

    - SDK 6.* still should *not* be able to build for fr955, but they will, because of the bug

    My point is that if old SDKs either won't build or shouldn't build for a device with newer firmware (CIQ 5.0.0/5.0.1/5.1.0), how is it possible that an old app which was built targetting old firmware (CIQ 4.*) for the same device can continue to run properly? If there's backwards compatibility in the sense that new firmware should be able to run old apps, then old SDKs should be able to build for new firmware (with a newer CIQ API version). But according to the version check information in compilerinfo.xml, old SDKs should not be able to build for new firmware (with a newer CIQ API version).

    The only way out of this dilemma that I can think of is if something else also changed in the device configuration files along with the connectIqVersion in compiler.json. i.e. Whatever that something else is, it used to be compatible with CIQ 4.* but now it isn't.

  • The problem is that firmwareVersion from compiler.json limits devices (when user tries download app) and it shouldn't because only min API level should it.

    Since there is usually no problem with apps installed before the firmware update (i.e. built with the old SDK) it means that backward compatibility is ensured. So the only reason for using the firmwareVersion to limit devices is forcing users to update firmware (which is completely unnecessary for developer and only limits the users who can use the developer's application).

    Of course I can fix compiler.json and put 0 in firmwareVersion and it should run without problem. Unless the compiler choose something (e.g. headers of functions) depending on firmwareVersion - but this would mean that there are many subsystems on device (virtual machines, SDK) because there may be old applications installed before firmware update.

  • Tl;DR I'm still having trouble squaring the circle with the following facts:

    - all CIQ 4 devices have gotten an update to CIQ 5

    - Garmin says that you must use a newer SDK to build for CIQ 5.* devices. (And in fact we have seen crashes if an old SDK - like SDK 6.4.0 - is used to build for a new CIQ 5.* device, either in the sim or a real device. It's also worth noting that if the compiler checks were working properly in the 6.* SDKs, then those SDKs wouldn't be able to buidl for CIQ 5.* devices in the first place.)

    I don't see how this can mean anything other than: it's possible for old apps installed on CIQ 4 devices to crash when those devices are updated to CIQ 5.

    And to me that seems to go against everything we've seen in the past as far as back compat is concerned.

    So why haven't we seen en masse reports of crashes for apps on CIQ 4/5 devices?

    I'm probably missing something here though. Like maybe something to do with devices updates.

  • Regarding deprecation:

    - I have the impression that *in general*, deprecation was usually something applied "in the future" to new (not yet existing) devices, with new (not yet existing) major CIQ versions.

    Ofc there are exceptions, like Weather.currentConditions.observationLocationName, which has been deprecated in a recent SDK update. I know that the field isn't actually removed on the devices (yet), but it's set to null. I kinda wonder what the value would be for actually removing the field, except to definitively break any app that still uses it, even with the correct null check. Does Garmin really wanna do that? Isn't it bad enough that badly-written apps broke bc they don't have a null check (which is def a bug, since the field was always typed to be possible null)

    - for example, Application.loadProperties/saveProperties were scheduled for deprecation "after System 4" (which is CIQ 3.2/CIQ 4). To me this is ok because the only devices which require those functions were CIQ 2 devices, and CIQ 2 devices would never get CIQ 3

    - Yes, even this situation has an obvious problem for devs. If someone chose to use loadProperties/saveProperties in System 4 (or CIQ 3.0.x to CIQ 3.1.x), they could reasonably expect their code to stop working if Garmin kept their promise and removed those functions after System 4.

    - If that happened, Garmin could reasonably turn around and say "I told you so".

    - *However*, at least a couple of years ago (long after the original deprecation announcement, Garmin had still held back on removing loadProperties/saveProperties because devs were still using it. A CIQ team member (Travis) expressed frustration in a comment on a bug report that devs were still using these functions, bc the team wants to get rid of them. I don't know if they've finally done so.

    So ironically, the deprecation argument actually provides evidence that Garmin doesn't want apps to automatically break with firmware updates.

    > Ideally Garmin should never deprecate anything "too fast", meaning that they should announce that something is going to be deprecated in a way that any developer not aware before the announcement could release an app available on all devices and not having to check each and every method with runtime has check.

    If Garmin has to be cautious about deprecating things (as you said and as with my argument above), isn't deprecation sort of the exception that proves the general rule that new firmware should be backwards compatible with old apps?

    Exhibit B: auto-migration. If it was the case that old apps are supposed to "automatically break" with new firmware (or new devices), then Garmin would have never implemented auto-migration. The existence of auto-migration implies that in fact, in some cases, old apps should be able to run on new devices, with 0 code changes.

    Then again, idk if any of my apps have been auto-migrated in the past few years. Certainly I can't imagine a CIQ 4 app being auto-migrated to a CIQ 5 devices (or can I?)

    Anyway, I think the huge difference in the current era, which I have alluded to a couple of times, is that all the CIQ 4 devices got CIQ 5. A new major version seems to imply breaking changes in a way that a new minor version does not.

    Contrast with the past, when no CIQ 3 device was ever upgraded to CIQ 4, and no CIQ 2 device ever got CIQ 3. Yes, many CIQ 1.x devices got CIQ 2.x, but at the time the ecosystem was so new we probably didn't care so much. And I don't think that apps built with a CIQ 1.* SDK ever broke because a device was updated to CIQ 2, so there is that, as well.

    Anyway, I have an 8 year old running pace calculator on my iPhone with a recent iOS. Yes, Apple breaks backwards compatibility all the time (e.g. removing support for 32-bit apps), but even they have a *general* strategy of not "automatically" breaking apps with a firmware/OS update.

  • Regarding your last question :"are new firmware versions backwards compatible with old CIQ apps or not?"

    I think in general no, and that is because some things can be deprecated in the future firmware. Ideally Garmin should never deprecate anything "too fast", meaning that they should announce that something is going to be deprecated in a way that any developer not aware before the announcement could release an app available on all devices and not having to check each and every method with runtime has check.

    However is it required from every developer that every time they upload a new version to change their code (and use runtime has checks where they use has checks) according to the newest SDK's deprecation announcements?

    In the past someone could write an app and use the now deprecated properties. At some point in time they might "just fix a bug from ERA", (and not even adding the latest devices) and not even using the then latest SDK, so totally unaware that the way they save properties is deprecated (though still working on all devices they support at the time)

    But is it possible that some devices (that their app supports) have been upgraded to a firmware that stopped supporting properties and now only work with storage?

    I haven't checked the past timeline, and hopefully Garmin does think about these cases, but maybe sometimes they miss something.

    After all there have been firmware bugs that required devs to release a quick workaround so the users don't have to wait 3 month (at least) for Garmin to fix the firmware, if they ever fix it...