Under Review
over 1 year ago

Feature-request: split the strings.xml for in-device and settings related strings

In most of the apps I've seen most of the strings are used for settings, still those strings are included in the memory footprint of the app. It would be very useful to split strings.xml to device-strings.xml and settings-strings.xml.

Parents
  • I just noticed that starting in sdk-4.2.x, the documentation for String resources (see Strings section of https://developer.garmin.com/connect-iq/core-topics/resources/) says

    See resource scopes. String can have the additional setting scope which removes it from the runtime. This is useful when a string is only used within your setting definitions

    But I tried it, and I just get compilation errors. For eg fr235 (where this would *really* help to save some memory), I get 

    WARNING: fr235: settings.xml:66: String resource 'option_4' specifies a resource scope, but resource scopes are not supported by device 'fr235'.

    followed by

    ERROR: fr235: settings.xml:66: String resource 'option_4' specifies an invalid resource scope 'setting'.

    With newer devices, I just get the error. So it looks like there was/is a plan to support this, but its not made it into the compiler yet...

Comment
  • I just noticed that starting in sdk-4.2.x, the documentation for String resources (see Strings section of https://developer.garmin.com/connect-iq/core-topics/resources/) says

    See resource scopes. String can have the additional setting scope which removes it from the runtime. This is useful when a string is only used within your setting definitions

    But I tried it, and I just get compilation errors. For eg fr235 (where this would *really* help to save some memory), I get 

    WARNING: fr235: settings.xml:66: String resource 'option_4' specifies a resource scope, but resource scopes are not supported by device 'fr235'.

    followed by

    ERROR: fr235: settings.xml:66: String resource 'option_4' specifies an invalid resource scope 'setting'.

    With newer devices, I just get the error. So it looks like there was/is a plan to support this, but its not made it into the compiler yet...

Children
  • good trick, probably I'll save less, because usually use

    var s = Rez.Strings;

    WatchUi.loadResource(s.myString).

  • App can't crash because you can't build it  (Undefined symbol ':StringSymbol' detected).

    In my case, it can, because of the way I access the strings. I have

    (:typecheck(false))
    function loadString(string_id as Symbol) as String {
        return WatchUi.loadResource(Rez.Strings[string_id] as Symbol) as String;
    }
    

    And then I call loadString(:my_string), rather than WatchUi.loadResource(Rez.String.myString).

    Each call to loadString generates much less code than the corresponding call to WatchUi.loadResource would have done (saves 5 bytes for the call itself, and 14 for the argument) - but yes, I guess it does have the downside that it subverts the compiler's undefined symbol checking.

    But I'm curious how it works since it's from 4.2.x:

    No device needs to know about the new "scope", because anything with that scope is left out of the .prg file. Settings still work because all the information about the settings is (and always has been) encapsulated in the MyApp-settings.json file (which is sent to the store in the .iq file).

  • App can't crash because you can't build it  (Undefined symbol ':StringSymbol' detected).

    I've made some test and it is possible to save some memory (but only for ID in rez.strings and strings, peak when changing properties is also a bit less).

    But I'm curious how it works since it's from 4.2.x:

    - adding scope settings

    - building app

    - running app on device with 4.2.x, device knows new scope

    - running app on device with 3.2.x, device doesn't know new scope so

    -- ignores scope so all is in memory optimisation?

    -- compiler prepares different version for older firmware? 

  • As far as I can tell, it works for everything (I've tested it with fr235, fenix5xplus and fr955 so far).

    But note that if you mark a string as scope="settings", but use it anyway, your app will likely crash.

    eg with my app, devices that support "on device" settings via getSettingsView use all the settings strings to construct on device menus etc. So I can only take advantage of settings scope on devices that don't support getSettingsView - which is devices prior to 3.2.0. So it depends on exactly what you meant. There's nothing to stop you using settings scope with 3.2.0 devices, as long as your 3.2.0 app doesn't try to use those strings (but for me, it just so happens that it does).

  • Can I use settings scope for every device e.g. with CIQ 3.2 in firmware?