Implement compile-time detection of (version-)incompatible features

Hello CIQ team,

Following a detailed response from jim_m_58 (https://forums.garmin.com/forum/deve...66#post1281066) about the link between CIQ device version and SDK version, may I suggest a compile-time detection of incompatible features is implemented ?

The API clearly states when a new feature becomes available or an old feature will disappear.
On the other hand, when building a project, we have to specify the CIQ version we target (-s parameter to monkeyc). (What for ?)
As jim_m_58 explained, using a feature not yet available on an actual device makes the app crash (IQ!).
Wouldn't it much more elegant to detect such incompatibilities at compile time (since we *do* specify the target CIQ version at that time) ?
Manually keeping track of version introduction/deprecation time for all the API entry points we use not being the most efficient and least error-prone of method :-/
EDIT: that would help beta-testers of beta SDKs: we can try out the new features and clearly be warned about them when attempting to compile the app version/branch to be published on the CIQ Store (which we obviously do not want to crash on users devices)

Cédric
  • There actually is much of this using the sim. If you try to use a 2.x feature on a 1.x target, it will crash and you'll see where and why. You could of course just set a minimum SDK for your app to 2.x and not worry about 1.x devices (they won't be available in the store), but that's not ideal. This also won't help in the case of sideloads, as the check is down when downloading from the store. That's where there are a couple options. Build file excludes (Jungles in 2.4.x) or "has".

    With build file excludes, you can have different code based on the target, and it's resolved at compile time. Using "has" is a runtime thing.

    Take the case of getHeartRateHistory. That's only available on devices with an OHRM. Let's say you want to use it to display HR is a watchface, and that watchface is for both OHRM and non-OHRM devices. You could use build file excludes so that it's not even in the .prg for devices without OHRM. Or you can use "has" - only call getHeartRateHistory on devices where it's available. (this is what I do in watch faces). If "has" indicates that you can use it, do so. If not, don't. The call is in the .prg,but just won't be executed on devices that don't support it. Based on the target in the sim, it will work on devices it's available, and not be used on the others.

    To do a compile time check, the compiler would have to understand the code paths that can be taken for a target to flag that "getHeartRateHistory" is being used on a device that doesn't support it, so instead bugs are caught at run time, when the code path is actually taken. I'll admit, "has" is at the top of my bag of tricks for multi device/multi VM support. Again using a WF, I have some that support 1.x and 2.x device, with and without OHRM, where background processes may be supported, and "seconds all the time" may be supported.

    And I can copy the same .prg to any target I support and it runs fine, and uses the features available on that target.

    With 2.4.x using Application.Store. First of all, I'm not rushing to use it, as the getProperty/setProperty method for the Object Store is fine with all my current apps, and the calls aren't going away until CIQ 4.0.0 (a long ways off). This again can be managed with "has", or is a good candidate for using different code for different devices (build file exclude/jungles).

    You could have
    function readObjStore(whatever) {
    //use getProperty call
    return stuff;
    }

    for non 2.4.x devices
    and
    function readObjStore(whatever) {
    //use Application.Storage call
    return stuff;
    }

    for 2.4.x devices. Using annotations, you build with the correct version of the function for the specific target. To be honest, for something that's small (code wise), I'd use "has", but use excludes for larger chunks of code. Also, build excudes don't handle APAC/ROW VM version differences on the same device target.

    There is also using "monkeyVersion" to see what VM you're on, but I don't use that.

    Is this the ideal in all cases? Maybe not. But it's workable, once you find what "tricks" work best for you and for specific things in your apps. And some is "developer choice". I know people that try to avoid using "has", and go for build excudes/Jungles whenever they run into stuff like this.