Acknowledged

Feature request: dynamic resource loading

Loading application resources (strings, images, etc.) in Connect IQ is done using symbols. Symbols are a compile-time construct, so any resources I want to put in my application have to be hard-coded in my source files. I would like to be able to reference resources dynamically (e.g., allow loadResource() to take strings) so that I can reference image resources within strings, e.g. loading an image from Markdown source.

  • Hey Travis,

    It's exactly like this. I created a similar construct in my app to map strings to resource symbols in order to reference them in a templating language.

    e.g. Markdown: "[Image of a duck](duck.svg)"

    The feature request is to avoid all of this overhead and instead have a way to control what resources are present in my app without referencing them at compile time, and then to load them at runtime. That would simplify the development of content-based apps like mine tremendously.

  • I'm afraid I don't understand your request. What exactly are you hoping to do?

    We load resources using resource identifiers that are fixed at compile time because the resources are compiled into the PRG and we know how to find the resource data based on the resource id at compile time. It sounds like you want to somehow inject application information into this lookup so that we find the resource dynamically based on information from the app.

    Loading resources dynamically like you seem to want should probably just be a layer built on top of accessing the resource in the PRG data given a resource id.. something like this:

    var DYNAMIC_RESOURCE_MAPPING = {
    } as Dictionary<String, Symbol>;
    
    function addDynamicResource(aResourceName as String, aResourceId as Symbol) as Void {
        DYNAMIC_RESOURCE_MAPPING[aResourceName] = aResourceId;
    }
    
    function removeDynamicResource(aResourceName as String) as Void {
        DYNAMIC_RESOURCE_MAPPING.remove(aResourceName);
    }
    
    function clearDynamicResources() as Void {
        DYNAMIC_RESOURCE_MAPPING = {} as Dictionary<String, Symbol>;
    }
    
    function loadDynamicResource(aResourceName as String) as WatchUi.Resource or Null {
        var aResourceId = DYNAMIC_RESOURCE_MAPPING[aResourceName];
        if (aResourceId == null) {
            return null;
        }
        
        return WatchUi.loadResource(aResourceId);
    }
    
    (:test)
    function testLoadDynamicResource(logger as Logger) as Void {
        Test.assertEqual(loadDynamicResource("launcherIcon), null);
        
        addDynamicResource("launcherIcon", Rez.Drawables.LauncherIcon);
    
        var icon = loadDynamicResource("launcherIcon");
        Test.assert(icon instanceof WatchUi.BitmapResource || icon instanceof Graphics.BitmapReference);
    
        removeDynamicResource("launcherIcon");
    
        Test.assertEqual(loadDynamicResource("launcherIcon"), null);
        
        return true;
    }