Persistent Storage / App.Setproperty - where is data stored?

hi -

I'm making changes to my GymTimer app and I would like to add a persistent userDefined rest time. (Currently the default is 60s) . While the rest time can be user defined via a menu option - this user defined option does not carry forward for the next time the app is ran.

I understand that I can use app.setproperty() and app.getproperty() to do the persistent storage, but I'm a little unsure of how it's used.
The Setproperty/getproperty seems to be a key/value pair which is fine. I believe I can use it.
What I would like to know is how does the code store this data.

Is it stored under GARMIN\APPS\DATA?
As a FIT file?

I searched github and the ObjectStore example but can't connect the dots (yet)
  • Yup, under apps\data in a "*.str" file. It's in it's own format. The name is the 8.3 version of your app name.

    when you use app.setProerty(), you only set one property, but they aren't actually save to the .str until you call app.saveProperties()

    so if you do something like:

    var value = app.getProperty(key);
    if(value==null) {
    value="DEFAULT";
    app.setProperty(key, value);
    saveOS=true;
    }
    if(saveOS) {
    app.saveProperties();
    }


    you look for a key, and if it doesn't exist, it gets the value "DEFAULT", sets the key value to that, and save the Object Store if something was set.
  • i need to do a saveProperties()?

    I am not currently doing that.
    It took me a while to learn how to get and set the property.

    but i didn't use saveProperties

    i wrote its own UserDefined Class to store that 1 single "UserDefinedRestTime" property. (LOL)

    getRestTime() {
    ...
    var DefinedRestTime = app.getProperty(UD_REST_TIME);
    ...
    }

    storeRestTime() {
    app.setProperty(UD_REST_TIME, UserRestTime);
    ...
    }



    when I start the app (initialise) i use getRestTime() when I exit and saveSession, i call up storeRestTime.

    It works (or at least, I don't see bugs (yet!!))

    the API Page http://developer.garmin.com/downloads/connect-iq/monkey-c/doc/Toybox/Application/AppBase.html#saveProperties-instance_method

    has literally nothing on the LoadProperties and SaveProperties.

    8.3 version of the app name?? huh?
    What I do see in the garmin\apps\data folder is a bunch of names which I do not recognise. it's gibberish names.
  • Without saveProperties, they are not saved to apps/data. The documentaion (1.1.1) doesn't say a word about it, but I found it in one of the samples and how to use it.

    the names you see are from the app store. the .prg files from there have matching names

    if you sideload a .prg (say abcdef.prg), the OS will be abcdef.str. But learned the other day that if you sideload abcdefabc.prg the .str will be turned into an 8.3 name (like abcdef~1.str)
  • Former Member
    Former Member over 9 years ago
    The saveProperties function is not documented because we did not intend it to be a public function.


    At this time, saveProperties is only needed if you set properties in the onStop method. Due to a bug in the VM, the object store was being saved prior to onStop, causing changes made there to be lost. We have fixed this bug in the VM, and it will not be needed once the next SDK is released.
  • Brian, on a va, I do get/set properties in initialize(), and without the saveProperties call, the OS never gets created. Maybe this is similar to the situation you described. I'm on fw 2.90
  • Former Member
    Former Member over 9 years ago
    saveProperties is called by the VM when the app shuts down, so I'm not sure what you are seeing. If your app crashes, then properties won't be saved. The ObjectStore sample in the SDK does not call saveProperties, and I know it works on VivoActive.
  • I think the object store sample is not indicating the right way to store/get the data.
    It doesn't do user input. It's like defining the values yourself in the app and the key/value pair it within the app.

    Wish it had a better example. At least my learning would be faster.

    Just ranting. ��
  • Could it have to do with the fact I'm playing with the OS in initialize()? I only use the OS to read a configuration, but create one with defaults if a given key or keys) don't exist. Let me try it again and just verify this.....

    update: if I comment out the saveProperties, the .str is not created either in the simulator or on the VA itself. It probably has something to do with doing this in initialize().
  • Former Member
    Former Member over 9 years ago
    That is not something I would expect to affect anything. If you have some simple sample code that demonstrates the issue, I would like to investigate. Odds are it is fixed since the system was reworked, but I'd like to catch it if it isn't.
  • Actually, could it be that I'm doing this in a watchface, so onExit is never called, so the OS isn't created? I'm doing this in preparation for "user Config", because I'm guessing the OS will have to exist to be configured. Maybe I'm wrong on thinking this is needed, but I'm trying to plan for it!

    Here is my OS "editor" widget where I can create a custom OS based for various color configs. With the "saveProperties()" commented out, no .str is created in the simulator. But on the va itself it is, because the widget actually exits?

    using Toybox.Graphics as Gfx;
    using Toybox.System as Sys;
    using Toybox.WatchUi as Ui;
    using Toybox.Application as App;

    enum {
    OS_SCHEME,
    OS_CLOCK,
    OS_BACKG,
    OS_FOREG,
    OS_WARN,
    OS_ICON,
    OS_STEPS,
    OS_CLOCKALWAYS,
    OS_STEPSALWAYS,
    OS_STDBARCOLORS,
    OS_ALLSAME,
    OS_SHOWLOGO
    }

    var data= [
    [OS_SCHEME,"DEFAULT"],
    [OS_CLOCK,"GREEN"],
    [OS_BACKG,"BLACK"],
    [OS_FOREG,"WHITE"],
    [OS_WARN,"LTGRAY"],
    [OS_ICON,"WHITE"],
    [OS_STEPS,"WHITE"],
    [OS_CLOCKALWAYS,false],
    [OS_STEPSALWAYS,true],
    [OS_STDBARCOLORS,false],
    [OS_ALLSAME,false],
    [OS_SHOWLOGO,false]
    ];

    class OSEditView extends Ui.View {

    var keysDone=0;

    function initialize() {
    var app = App.getApp();

    app.clearProperties();

    for(var i=0;i <data.size();i++) {
    app.setProperty(data[0], data[1]);
    Sys.println("key "+data[0].toString()+" "+data[1]);
    keysDone++;
    }
    //app.saveProperties();
    Sys.println("Saved OS!");
    Ui.requestUpdate();
    }

    //! Update the view
    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_BLACK,Gfx.COLOR_BLACK);
    dc.clear();

    dc.setColor(Gfx.COLOR_WHITE,Gfx.COLOR_TRANSPARENT);
    dc.drawText(dc.getWidth()/2, dc.getHeight()/2-20, Gfx.FONT_MEDIUM, "Object Store\n"+keysDone.toString()+" keys saved\nAll Done!", Gfx.TEXT_JUSTIFY_CENTER+Gfx.TEXT_JUSTIFY_VCENTER);
    }
    }
    [/code]