Correct way to detect lack of FIT download support

What would be the best way to determine at runtime if a device does not support downloading FIT via makeWebRequest()

(I know I can read the SDK and "know" which devices implement the support, but I like to have generic code which handles (at least a subset of) unexpected errors, even if it is to show a more helpful message to the user.

I can trap the SymbolNotAllowedException, but I can't find any way to interrogate it to determine if it is the specific :responseType exception, apart from running equals() on its getErrorMessage() (which is really not nice code) eg:

// Note: the ( after "if" changed to a [ below to avoid an issue in the forum which would break the post
try {
Communications.makeWebRequest(url, params, options, method(:handleDownloadResponse));
} catch (e instanceof Lang.SymbolNotAllowedException) {
// XXX It would be nice if there was a better way to test for this specific error
if [ e.getErrorMessage().equals("Invalid value for :responseType for this device.")) {
handleError(Ui.loadResource(Rez.Strings.errorFitNotSupported));
} else {
handleError(Ui.loadResource(Rez.Strings.errorUnexpectedDownloadError));
}
}
// end


So.. whats a correct way to do this?

Thanks :)

David
  • For a runtime check, I typically use a "has" check and not even make the call if it won't work, but in this case, I can't think of what could be used with "has".

    If this is a critical call for your app, why not just support targets that you know support the call?

    If the app can function without it, you could use resource overrides to determine if the call can be made on a specific target.
  • It is quite literally the only purpose for the app :) - it downloads workouts for AI tailored running plans ( https://github.com/TrainAsONE/trainasone-connectiq/ )

    I set the target products to the set of devices which CIQ2 and advanced workouts, which includes the Vivoactive 3 (which triggered this exception and led to https://forums.garmin.com/forum/developers/connect-iq/connect-iq-bug-reports/1252481-vivoactive-3-unable-to-download-fit-workout ) so can certainly remove the Vivoactive 3 from that set, but I was just curious if there was a natural way to have this run-time check in ConnectIQ

    Thanks
  • One thing to consider is that some devices support .FIT files and some support .GPX. If I recall an edge device supports GPX and not .FIT, and some devices support .FIT and not .GPX
  • Absolutely - I noted in my other post about the Vivoactive 3 download issue that I'd tried GPX with the same result as well but forgot to mention it here.

    It looks like I'm out of luck on a generic solution here. One of the joys of targetting an embedded device!

    Still, I'd rather be able to write 2.x code which also runs on 735s & 935s than have a richer runtime which only runs on a Fenix 5! (Insert obligatory comment about writing 6502 code a *very* long time ago which had to fit within 256 bytes :)
  • I don't see a way to detect at runtime... It would be nice if you could use the has operator on something (like HTTP_RESPONSE_CONTENT_TYPE_FIT) to see if the functionality is supported or not. I'm fairly certain that fitness devices (Edge, Forerunner) are supposed to have FIT support, and outdoor devices (Rino, Oregon) should have GPX support. I think the Fenix5 line is the exception; they are technically outdoor devices, but have FIT support.

    So if you only target Fenix5, Forerunner, or Edge devices, then you probably don't need to do anything and can just assume FIT support is available. If you need to support both then you could use your trick or you could use build exclusions. I'm not sure that is a great solution, but it is a possibility.

    Another thing to note is that some devices apparently don't have support for structured workouts (the vivoactive line I believe). I think you can detect support for this at runtime by looking for PersistedContent has :getWorkouts, but it seems like a runtime check for this is unnecessary... If the device can't support structured workouts, you probably won't bother porting to that device.

    Edit: confirmed FIT/GPX support comment is correct here

    Travis
  • Amusingly this afternoon I was implementing PersistedContent in the app and reached the same conclusion :)

    It looks like "has :PersistedContent" is the right runtime check - that check fails on the Vivoactive 3, and passes on devices which can download workouts.

    Obviously "has :PersistedContent" fails on CIQ 1.x devices such as the ForeRunner 235, but they fail the makeWebRequest() call with a fatal error. It looks like the Vivoactive 3 is the special case here.

    Thanks