Typechecker does not accept ScanResult for Applicaton.Storage - any workaround for this?

If i code

 Storage.setValue("MyBLE_ScanResult", scanResult as ScanResult);    

the type checker complains that ScanResult is not an Application.PropertyValueType. 
That's true, but the API says that from v3.2.0 on it is possible to save a ScanResult with Application.Storage.

Of course, i can switch off type checking, then it works.
But that's not straight forward.

Should i file a bug for this? Or is there a workaround?

  • what device is this on? What is the minApiLevel in the manifest?

  • minAPI Level 3.2.0

    build for Edge1030, 1030plus, 1040. all the same.

  • Then I would open a bug report about the compiler, type checker

  • with SDK 8.1.0 this works. But with 8.1.1 it fails again. Strange.

  • Yeah if you search ConnectIQ/Sdks/**/bin/api.mir for "type PropertyValueType", every SDK [*] except 8.1.0 has this definition:

    type PropertyValueType as $.Toybox.Application.PropertyKeyType or $.Toybox.Lang.Array<$.Toybox.Application.PropertyValueType> or $.Toybox.Lang.Dictionary<$.Toybox.Application.PropertyKeyType,$.Toybox.Application.PropertyValueType> or $.Toybox.WatchUi.BitmapResource or Null;

    [*] at least every SDK which I have installed and which has type info in the first place (the oldest I have which fits the bill is 4.0.6)

    8.1.0 has this definition:

    type PropertyValueType as $.Toybox.Application.PropertyKeyType or $.Toybox.Lang.Array<$.Toybox.Application.PropertyValueType> or $.Toybox.Lang.Dictionary<$.Toybox.Application.PropertyKeyType,$.Toybox.Application.PropertyValueType> or $.Toybox.WatchUi.BitmapResource or $.Toybox.BluetoothLowEnergy.ScanResult or $.Toybox.Complications.Id or $.Toybox.Application.WatchFaceConfig.Id or Null;

    The changelog for 8.1.0 says this:

    Bug Fixes

    ...

    • Update typing for Storage.setValue() to include all allowed value types.

    The changelog for 8.1.1 says nothing about undoing that change, so I'm guessing the change was inadvertently undone. EDIT: then again, it's possible that it was undone on purpose, as PropertyValueType is used for both Properties.setValue() and Storage.setValue(), but the above change should only apply to Storage.setValue() afaik [*]. It seems that the correct fix would be to introduce a new type that's only applicable to Storage, such as StorageValueType.

    If the change was truly undone on purpose, it's a shame the changelog doesn't say a word about that.

    [*] ofc I'm just basing this on the fact that the API docs for Properties.setValue() doesn't have a list of extra things can be stored in properties beyond the normal "primitive" Monkey C types and standard containers. Then again, PropertyValueType still includes BitmapResource even though the docs for Properties.setValue() don't say anything about that, either. (Contrast with the docs for Storage.setValue() which mention that BitmapResource can be set since CIQ 3.0.0). Does the lack of an explicit mention of  BitmapResource for the Properties.setValue() docs mean anything? Are we supposed to just look at the docs for PropertyValueType type and take it at face value? The docs for PropertyValueType don't mention anything about BitmapResource only being valid since CIQ 3.0.0. What about the fact that the Storage.setValue() docs also talk about AnimationResource being valid, but that wasn't reflected in the change above.

    Honestly the docs and type info are a huge mess here, and the core topics docs don't have any information on any of the "new" types for storage/properties (including BitmapResource).

    This does highlight the apparent fact that it's seemingly not possible for the SDK to actually provide different types for a function argument (or other symbol) based on device or API level (this has come up before in other discussions). Meaning if you pass a ScanResult to a pre-3.2.0 device, the compiler can't and won't flag that as an error, assuming that the type information is eventually corrected for PropertyValueType.

  • developer.garmin.com/.../Properties.html

    developer.garmin.com/.../Application.html

    developer.garmin.com/.../Storage.html

    I think that Garmin should update the docs for Property.setValue and PropertyValueType to make it explicit which types are available for Property.setValue, and what CIQ versions they are available in -- just like the docs for Storage.setValue.

    As a bonus, I think the core topics doc could be updated, too:

    https://developer.garmin.com/connect-iq/core-topics/persisting-data/

  • The problem here is that a ScanResult can be saved to Storage, but not Properties, and PropertyValueType is used for both.  The doc used to be clearer about this, but can't find it right now.

    So if PropertyValueType didn't allow ScanResult, it caused a warming/error if you tried to do it with Storage, which is not an error, and it looks like in 8.1.0 where It would work for Storage (correct) but also for Properties (an error) so they checged it back

    Looks to me they need a second definition (StorageValueType) for Storage as the valid types are different between Storage and Properties.

    I reported this back when saving the ScanResult to Storage was first added with Typechecking so a few years back.  At that point, I just turned off type checking in apps where I wanted to save the ScanResult as it's a really nice feature and can really speed up the connection process with BLE, but I'm not sure many apps use it.

    So right now, either turn off type checking or don't save the ScanResult to Storage and maybe it will be fixed in a coming SDK update.

  • you can turn off type checking just in the relevant function:

    (:typecheck(false))
    function foo()...
  • Thanks for this useful hint. I did not know that. Now i can capsule my code with this to avoid compiler error.