Stupid complications questions

Hello,

Before I head down the path of complications, please verify:

1) It's not that drastic to convert/publish my Glance as an app 

2) I can open my own app using a long press on an area of my compatible watch face

It looks a bit daunting from my amateur programmer seat.

Thanks

  • This is currently working...

        if (hasComps) {
                stepId = new Id(Complications.COMPLICATION_TYPE_STEPS);
                batId = new Id(Complications.COMPLICATION_TYPE_BATTERY);
                calId = new Id(Complications.COMPLICATION_TYPE_CALENDAR_EVENTS);
    
                stepComp = Complications.getComplication(stepId);
                if (stepComp != null) {
                    Complications.subscribeToUpdates(stepId);
                }
                batComp = Complications.getComplication(batId);
                if (batComp != null) {
                    Complications.subscribeToUpdates(batId);  
                }
                calComp = Complications.getComplication(calId);
                if (calComp != null) {      
                Complications.subscribeToUpdates(calId);  
                }
    
                Complications.registerComplicationChangeCallback(stepId);
                Complications.registerComplicationChangeCallback(batId);
                Complications.registerComplicationChangeCallback(calId);    

    Battery example...

                var batLoad;
                if (hasComps) {
                    batLoad = Complications.getComplication(batId).value;
                } else {
                    batLoad = ((System.getSystemStats().battery) + 0.5).toNumber();
                }
                batString = Lang.format("$1$", [batLoad])+"%";
    

  • So you aren't using 

    Complications.registerComplicationChangeCallback()
    With that, you get notified when a value changes instead of getting the value all the time.  I have a couple of publishers that only update every 15 minutes so much more battery friendly than getting the value every time onUpdate() is called (for example)
  • So, It was set up to only call the functions when an onUpdate happened.  Can i set the ComplicationChangeCallback to the onUpdate function?

  • Look at when I do the register in the sample WF I posted. You only do it once.

  • I'm not too sure I;m picking up what you're putting down.

    I put that code in intialize() so that it would only set-up once.  

    I tried changing my 3 registrations to 

    Complications.registerComplicationChangeCallback(onUpdate);
     
    using multiple ways of putting onUpdate in.  It went as well as expected.
  • Again, look at the sample I posted and run it, maybe adding println calls for things you don't understand.

  • I put that code in intialize() so that it would only set-up once.  

    I tried changing my 3 registrations to 

    Complications.registerComplicationChangeCallback(onUpdate);
     
    using multiple ways of putting onUpdate in.  It went as well as expected.

    View.onUpdate(), like other CIQ system callbacks named on*(), isn't meant to be called directly by your app code. It's a function that the app provides for the system to call (hence the term "callback"). Notice how onUpdate() takes a dc as an argument. The dc is provided by the system when it calls onUpdate, and it's one reason that calling onUpdate() directly or using it as a complication change callback doesn't make sense.

    In order to ask the system to call onUpdate(), use WatchUi.requestUpdate().

    e.g.

    // app class:
    
    function onComplicationChanged(id as Complication.id) as Void {
      // [insert code that deals with complication id]
      // depending on how your view code works, perhaps there's nothing to be done here
      // e.g. if your view onUpdate() code always queries all complications of interest
      // then you don't really care which complication was updated, just that *a* complication was updated
      // ...
    
      WatchUi.requestUpdate(); // request update for current view
    }
    
    function initialize() {
      // ... subscribe to complication updates ...
    
      Complications.registerComplicationChangeCallBack(method(:onComplicationChanged));
    }

  • If you look at the sample I posted, there's no reason to call requestUpdate() in my onComplicationChanged.  You just need to save the value for the next regular call to onUpdate().  Native comps can change every second, and when a watch face is in low power mode, you don't want onUpdate() called that often.  Calling requestUpdate() the way you show could impact battery life....60 onUpdate calls when you only need 1.

  • If you look at the sample I posted, there's no reason to call requestUpdate() in my onComplicationChanged.  You just need to save the value for the next regular call to onUpdate().  Native comps can change every second, and when a watch face is in low power mode, you don't want onUpdate() called that often.  Calling requestUpdate() the way you show could impact battery life....60 onUpdate calls when you only need 1.

    I didn't look at your sample, nor did I claim to offer the best solution.

    I simply addressed the issue with the code that I quoted. They're trying to call onUpdate() directly (regardless of whether that's the best solution or not), and I tried to show how you would get the system to call onUpdate(), assuming that's what you want to happen.

    Besides, will the system actually call onUpdate() "too often" in low-power mode, just because the app calls requestUpdate() too often? It's a genuine question. I don't develop watchfaces, but my best guess would be that the system would ignore requestUpdate() if it's called too frequently. Similarly to how requestUpdate() is ignored for glances on devices which don't support live updates.

    Otherwise, seems like it would be too easy for a broken/rogue watchface app to break the strict limits that CIQ places on the power budget for watchfaces.

    After all, the function is called requestUpdate().

  • The way I've always understood it, is requestUpdate() queues a call to onUpdate() if one isn't already queued.  So if you do it 10 times in a row, only one is queued.  But you are still doing something that doesn't need to be done 10 times, and in reality, not needed even once in this case. 

    I'll use requestUpdate() in a WF from things like onSettingchanged() or onBackgroundData(), but that's it

    If I change the color of something when the WF is in low power mode, waiting for the next regular call to onUpdate() could be a minute later, so I make the requestUpdate() call in onSettingchanged so the change is visible right away