Search code examples
garminmonkeycgarmin-connect-iq

Garmin Connect IQ Array out of Bounds error without Stack


Im currently trying to build a Watch App using a ViewLoop. However i get a, to me unexplainable, Array out of Bounds Error.

The App generates Views from an Array of Objects and adds these to a ViewLoop. I added println's to try and debug the error.

import Toybox.Application;
import Toybox.Lang;
import Toybox.WatchUi;

class AareGuruGarminApp extends Application.AppBase {
    var objects;

    function initialize() {
        AppBase.initialize();
        objects = [
            new Object("Object 1", "Value 1"),
            new Object("Object 2", "Value 2"),
            new Object("Object 3", "Value 3")
        ];
    }

    function onStart(state as Dictionary?) as Void {
    }

    function onStop(state as Dictionary?) as Void {
    }

    function getInitialView() as [Views] or [Views, InputDelegates] {
        System.println("Trying to generate ViewLoop");
        var viewLoop = new WatchUi.ViewLoop(new AareGuruGarminViewLoopFactory(objects), {});
        System.println("Successfully generated ViewLoop");
        System.println("Returning ViewLoop");
        return [viewLoop];
    }

}

function getApp() as AareGuruGarminApp {
    return Application.getApp() as AareGuruGarminApp;
}

class Object {
    var title;
    var description;

    function initialize(newObjectTitle as String, newObjectDescription as String) {
        title = newObjectTitle;
        description = newObjectDescription;
    }
}
import Toybox.Graphics;
import Toybox.WatchUi;

class AareGuruGarminView extends WatchUi.View {
    var object;

    function initialize(objectToDisplay as Object) {
        System.println("Initializing view for " + objectToDisplay.title);

        View.initialize();
        object = objectToDisplay;

        System.println("Initialized view for " + object.title);
    }

    function onLayout(dc as Dc) as Void {
        System.println("'onLayout' called");
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
        dc.drawText(
            dc.getWidth() / 2,                      
            dc.getHeight() / 2,                     
            Graphics.FONT_LARGE,                    
            object.title,                          
            Graphics.TEXT_JUSTIFY_CENTER            
        );
        dc.drawText(
            dc.getWidth() / 2,                      
            dc.getHeight() / 4,                     
            Graphics.FONT_LARGE,                    
            object.description,                          
            Graphics.TEXT_JUSTIFY_CENTER            
        );
    }

    function onShow() as Void {
        System.println("'onShow' called");
    }

    function onUpdate(dc as Dc) as Void {
        System.println("'onUpdate' called");
        View.onUpdate(dc);
    }

    function onHide() as Void {
        System.println("'onHide' called");
    }
}
import Toybox.WatchUi;

class AareGuruGarminViewLoopFactory extends WatchUi.ViewLoopFactory {
    var objectsForViews;
    function initialize(objects as [Object]) {
        objectsForViews = objects;
        System.println("Initialized ViewLoopFactory with " + objectsForViews.size() + " objects");
    }

    function getView(i) {
        System.println("Generating view for index " + i);
        var view;
        if (i >= objectsForViews.size()) {
            view = new AareGuruGarminView(new Object("empty", "empty"));
        }
        view = new AareGuruGarminView(objectsForViews[i]);

        System.println("Generated view for index " + i);

        return [view];
}


    function getSize() {
        System.println("'getSize' called");
        System.println("Size is " + objectsForViews.size());
        return objectsForViews.size();
    }
}

When i run this, i get the following output:

Trying to generate ViewLoop

Initialized ViewLoopFactory with 3 objects

'getSize' called

Size is 3

Successfully generated ViewLoop

Returning ViewLoop

Generating view for index 0

Initializing view for Object 1

Initialized view for Object 1

Generated view for index 0

Error: Array Out Of Bounds Error

Details: Failed to start CIQ Application

Stack:

Encountered app crash.


Solution

  • The problem lies within your custom factory class. You overwrote getView() but your getView() method doesn't return a delegate (you need to return a BehaviourDelegate or a subclass of it) but ViewLoop expects one.

    For further questions I suggest you to use the official developer forum. There tend to be more active monkey-c developers than here.

    You can also check out the "PrimatesApp" example shipped with the SDK. If you use VSCode, press F1 and type "monkey c: open samples folder". You can find the samples there.