Questions about getGoalView() and onGoalReached() for Watch Faces

Hello,

I'm working on a watch face and I want to do something when a goal event is reached. The goal events can be step goal, floors climbed goal and active minute goal.

First of all, I'm using getGoalView() to create a custom view. As far as I understand this will only fire when the watch face is running but not while another app is running, correct?

I'm doing it like in the Analog sample:

function getGoalView(goal as GoalType) as [View]? {
        return [new $.WatchFaceGoalView(goal)];
    }

Then I have my WatchFaceGoalView where I have my custom goal view. This works.

However, I have tested this in the simulator and I've noticed, that the memory keeps increasing each time a goal event is triggered. My guess is that's because getGoalView() keeps returning a new WatchFaceGoalView and the old one is not destroyed? I have also noticed the memory increase in the Analog sample. For watches that have not a lot memory this can lead to an out of memory crash quite fast. Is there something I could do differently here?

The second question is related to the Background services, also regarding goal events. I understand that you can register for the goal events. Which I would do for the 3 different goal types I want. Then I can overwrite onGoalReached() to do what I want. However I have to pass one goal type here. How would I go about it if I want to check for 3 different goal types?

Thanks for any kind of help or hints, I appreciate it!

Top Replies

All Replies

  • Just an idea:
    Add setGoal(goal) to WatchFaceGoalView, create the view in the initializer of the app, and set the goal in getGoalView, and return the already existing variable.

  • Just an idea:
    Add setGoal(goal) to WatchFaceGoalView, create the view in the initializer of the app, and set the goal in getGoalView, and return the already existing variable.

    Yeah, I think the behavior described in the OP is a bug/design issue in CIQ (I would expect the goal view to be freed from memory after it's no longer being displayed), but given that it's happening, the best way to deal with it is to just keep one instance of the goal view around all the time, and modify its behavior based on the goal type that's triggered.

    Given that your watch face needs to have enough memory headroom to be able to create one instance of the goal view at any point in time any way, it shouldn't be a problem to just keep one instance of the goal view around all the time. (Unless ofc memory is very tight, and there's other aspects of the app which depend on being able to max out memory at other points in time...) Either way, I can't think of a better solution.

    However I have to pass one goal type here. How would I go about it if I want to check for 3 different goal types?

    Have you tried calling registerForGoalEvent() multiple times with each of the types you're interested in? Does it work with multiple types, or does each subsequent call cancel the previous one?

  • Thank you, yeah, it seems like a bug or oversight in CIQ. But as you said, there needs to be enough memory for the goal view anyway, so this is the solution I will be going with.

    Regarding the registerForGoalEvent() and onGoalReached(), this works as well. I was calling the register events at the wrong place- brain fart on my end!