Having trouble with Properties

I'm trying to get properties working with my app, and everything is working fine in the simulator, but when I build for my device (fenix5xplus), it crashes as soon as I try to read a property using Application.Properties.getValue("my_prop").

Error: Unexpected Type Error
Details: 'Failed invoking <symbol>'
Time: 2022-02-10T16:34:10Z
Part-Number: 006-B3111-00
Firmware-Version: '17.30'
Language-Code: eng
ConnectIQ-Version: 4.0.9
Filename: HRBackground
Appname: HRBackground
Stack: 
  - pc: 0x10000e1b
    File: 'source-round-240x240/layouts.mc'
    Line: 27
    Function: readStateFromProperties
  - pc: 0x10001793
    File: source/FieldInfo.mc
    Line: 29
    Function: readState
  - pc: 0x10001189
    File: source/MyView.mc
    Line: 23
    Function: initialize
  - pc: 0x100001e9
    File: source/MyApp.mc
    Line: 39
    Function: getInitialView

Note - its a fatal error, not an exception (ie its not that I don't *have* such a property; the property works fine in the simulator, and I can pull up the simulator's 'Edit Application.Properties Data' editor, and see all my properties there (and change them, and see the effect on my app in the simulator).

I tried guarding the Application.Properties.getValue() call with 'if (Application has :Storage) {}', and it still failed the same way. I tried additionally guarding it with 'if (Application has :Properties && Application.Properties has :getValue) {}' and it still failed the same way.

I tried 'System.println(new Lang.Method(Application.Properties, :getValue))', and my log file shows 'Obj:243' or some such, but then invoking the method fails in a similar way to the above (but works in the simulator).

I deleted the fenix5xplus device via the sdk manager, and re-downloaded it. I deleted my bin directory, and rebuilt. No change. I'm using Sdk 4.0.9.

If I comment out the code, so that my App will run, then various CIQ 3.x features work (such as getSettingsView(), and Menu2), so its not somehow stuck on an old CIQ version.

Is there some setting I need to enable? Is there something else I need to copy to the device besides the .prg file?

  • Not that... its the call to getValue() itself thats crashing... I don't get a value back at all.

        s.drawBorders = Application.Properties.getValue("draw_borders") as Boolean;
    

    That's the exact line that crashes. If I comment that one out, it crashes on the next line, which just reads another boolean.

  • Put a try/catch around the setValue calls, and in the catch, maybe have a default. 

  • I have one, but as I said...

    Note - its a fatal error, not an exception
  • There is some strange behaviour if  run near memory limit. So if you read properties on start, when no all app data is in memory it run usually well but if you change settings when app already fully started it can be not enough memory and crash (probably no symbol getValue). I had the same problem somewhen...

  • Initially, this was being called from MyApp.initialize(), with the same issue. I thought that maybe that was too early, and moved it to my initial view's initialize() method. But no change. I don't think Im anywhere near the memory limit though.

    I think at this point, I'm going to try to make a minimal repro and if I can do that, I'll post the code here.

  • Its actually kind of embarrassing...

    I made a minimal project, and of course, it worked. But while making it, I noticed that if the project has no properties at all, then I get exactly the same crash - even in the simulator.

    ie, with *no* properties, Application.Properties.getValue('whatever') crashes the app (it doesn't throw an InvalidKeyException).

    As it happens, all my properties are defined in device-specific resource files, with special configuration in my .jungle file to pick the right one for each device. So it looked like that logic was working for the simulator, but not for the device.

    After some digging, I realized that the command lines for the simulator and device builds are almost exactly the same though, so it didn't seem likely that that could be the problem. So then I went through my .jungle file carefully, and discovered a typo... it shouldn't have found the property resource file at all. So how was the simulator working?

    At this point I realized that I'd tried deleting the device build directory, to make sure I was doing a clean build there, but hadn't bothered to do the same with the simulator build directory (since that was working as expected). When I deleted that, and rebuilt, the simulator started crashing in the same way.

    So... what had happened is that I'd got everything working in the simulator, then did some code "cleanup" during which I fat-fingered the name of the device-specific resource directory. The simulated app continued to work, because (as far as I can tell) the simulator just looks for a file named <app>-settings.json in the build directory, and uses that to determine which properties are valid. If your project contains properties, this file gets overwritten at build time; but if there are none, the file is just left in place.