How to Limit Instances of Datafield on a Layout?

Hi,

when I have two displays of a datafield in a complex layout layout, I get one call to onCompute per second and one to each onUpdate - all as expected

but I want to limit the user to one! … for a small datafield I can say “too small” but my problem use case is the split screen on watch or Edge with 2 valid sized fields

because I do a web request based on the dc size and obscurity in onCompute every X minutes

i could initialise the web request in onUpdate and not onCompute but I’d not know which request of multiple came back for which dc layout

so overall I was hoping there was some setting I had missed to limit the datafield to one user layout

 - thanks for ideas - Crisp

  • I don't have an answer to your question about how to distinguish between two identical data fields on a screen - but that's not necessary (at least in my experience with Edge devices):

    Two identical data fields on a screen behave in exactly the same way (so there is no point in having two on one screen).

    Example: If you tap one to change a display (if the data field offers this option), both data fields respond to this tap in the same way.

    Both data fields behave in exactly the same way. In fact, only one data field is used - it is simply displayed twice.

  • While I think it's impossible to differentiate between 2 fields of the same size and obscurity flag, the behavior you describe is not necessarily a feature of the CIQ platform. I think * it is probably just as much determined by the way your DataField is programmed.

    *) I don't have experience with user interaction (aka touch) with datafields.

    BTW I wasted some time in the past trying to crack this thing (with not much success) and you can try out this DF Detector DataField: https://apps.garmin.com/apps/1535a238-cbac-463b-bde2-373403502a6f also on GitHub: https://github.com/flocsy/DFDetector

  • I think * it is probably just as much determined by the way your DataField is programmed.

    When the program does any stuff coded in onCompute it has effect on all datafields (of the same datafield) on the same screen - even the sizes are different.

    When you do stuff in onUpdate for different datafield sizes, you can get different displays of the datafield at the same time on one screen.

    But 2 identical datafields (same width, same heigth) always react as one in the same way. (What‘s logical, because you cannot distinguish in onUpdate.)

    PS: I have your datafield for field-distinguishing. But as you stated - it does not help - especially with Edge devices.

  • Thanks both -- the DF Detector was really useful in identifying potential problems with watches returning similar or same obscurity flags and sizes, ... and I was OK with the duplication on Edge where two large fields are still rectangular.  My edge-case is where a semi-circular field upper on a watch I would like to process differently to a lower semi-circular layout.

    I could detect two onUpdate() being called with at the same moment and tell one not to update member variables (obscurity) for the onConpute to handle but it was unreliable.  I'll have to give some credit to user common sense (ahahahaahha)

  • assuming you have control of the api server end, just cache the response for x minutes based on a common url pattern that both fields would have.   that way the user can run it in as many fields as they want, but each one will get the same response from your server, one will just get the cached value from the previous call.

  • I could detect two onUpdate() being called with at the same moment and tell one not to update member variables (obscurity) for the onConpute to handle but it was unreliable.  I'll have to give some credit to user common sense (ahahahaahha)

    My hot take is that if the user is allowed to do something like add the same CIQ data field multiple times, then they can't be blamed for doing so, especially if the action is not a bug or quirk in the system.

    Iow, if your data field is added multiple times by a user, and it behaves in some way that the user doesn't expect, respectfully speaking, it's not their fault if the data field acts in some way that looks wrong to them. I wouldn't characterize any reaction from the user in this case as a failure of common sense.

    In general, if some app works unexpectedly in some edge case that's rare, yet "legal", that's not the user's fault. If they don't understand why it's working unexpectedly, it's not a failure of common sense.

    Respectfully, I think it's up to us as app devs to either:

    - somehow prevent said edge cases (not possible here)

    or

    - address the edge cases as best as we can

    As others have implied and as the CIQ team has explicitly noted, this is exactly why we are not supposed to calculations in onUpdate - that's what compute() is for.

    Seems like you're trying to jam a square peg into a round hole and implying that the user is wrong if they notice that it's not quite working.

    I don't think you explained exactly how or why your web request is supposed to be different for each instance of the data field, but it sounds kind of fragile.

    i could initialise the web request in onUpdate and not onCompute but I’d not know which request of multiple came back for which dc layout

    Do you have control over the server? Can you add context to the request which will be returned in the response?

    Why is it better if you make the request in onCompute vs onUpdate?

    Sorry that I'm obviously missing a bunch of things here.

  • It's easy: you send the dc size and obscurity flag to the server? Send them back in the response, and cache the response in a map indexed by the DC size and obscurity flag (I just make a number of them: 10000 * width + 10 * height + obscurityFlag), then each field in it's onUpdate can use the relevant values from the cache

  • I'll add that there are at least 2 ways of having the same DataField added more than once:

    1. You can add them on 2 different pages. Similar to how you might have 2 pages where you have mostly different fields, but there might be some that you always want to see without changing pages, so you have it on both pages. Of course the dimensions can be the same or different. In this case you will only get 1 onUpdate calls per compute.

    2. You could add the same DataField multiple times to the same page. In this case you'll get onUpdate called multiple times. Dimensions can also be same or different. In theory, especially if CIQ would support it, this could also be useful. Some datafields calculate (and probably save to fit file) many values, but can only display some, because of small DC dimensions. In this case it would make sense to be able to have 2 fields, each displaying something else.

    Unfortunately this is not really supported by CIQ, that is one of the reasons why some developers publish multiple identical versions of their datafields (though I think the main reason is to be able to have different config in different activities, but of course the user could add 2 of those to the same activity if they want)

  • Thanks for the input and comments -- I've been out cycling and thinking about the feedback before updating.

    The rhetoric from flowstate was most thought provoking and I ran a lot of thought experiments about how to help resolve user expectations -- but ultimately either my knowledge or the system is making that very hard!  And I hadn't even really considered one of flocsy's scenarios about having multiple pages with the app running ... and how onLayout and onCompute work there.

    For those reading the parent app forum there is the background to my localised rain radar, but that explains why there are potentially multipls makeImageRequest's for different layouts -- in order to optimise the content in both size and server-side text placement (I can't use the same corner regardless of obscurity flags).

    From the discussion here, my thought-code was that I could create a dictionary or key-value pairs of layouts<->images and somehow manage the requests and timers.  However, I thought I should build such a data structure onLayout.  I would expect that when changing to a 2-layout field view that onLayout is called twice, but not on Edge!  Maybe because both layouts would be the same.

    But on a Forerunner in the simulator when changing from a full-screen datafield to 2-field layout the onLayout is called twice per second, EVERY second, not just when the layout changes.

    So if I have a upper- and lower-half 2-field layout on a watch, and I want to update the bottom half due to a timer or user interaction then I can, within onCompute send a makeImageRequest and set some variable so that when the callback method is fired I know where to store the image, and then within onUpdate I can check the image sizes... but it doesn't work if they are identical halves of a rectangular Edge screen.

    Just like other platforms and applications, some registration for "full-screen-only" datafields sounds like it would be helpful (to me).

    And some way to get a GUID for a datafield layout rather then the guddle of building an almost-unique key from the size and obscurity that doesn't quite work?

  • I think you overthink it. I did it too and tried to find a solution, but after wasting much time and reading the forum for a while I can confidently say that it's a waste of time with the currently available tools the SDK gives us.

    I think that one unexpected, unintended side effect of how the simulator displays the running DataField simultaneously in every possible position of the layout is that some developers overthink how they want their datafields to work. Including me.

    But I'd challenge you: let's say the user adds your DataField to the top half of an edge. How would the rain map look like?

    And if they added it to the bottom half? How would it be different?

    Why would the user want to add it to both the top and bottom half at the same time? Why wouldn't they instead change the layout to full screen?

    Regarding enforcing full screen: many datafields do that, it's not complicated: instead of using the dc's dimensions they use the device's screen dimensions. They always draw accordingly. So if the user adds it to a field that is smaller, they only see the top-left portion. Then they quickly understand that it is meant to be only used full screen.

    Having a system enforced solution would just give hard time to everyone: user installs your DataField, then wants to add it on the main screen, below time and distance. What would they experience? If I was Garmin, probably I would filter out the datafields that enforce a not suitable size. So the user wouldn't see your DataField. But they wouldn't know why. So they would get frustrated, give your DataField a 1 star review and uninstall it. Other users would contact you and you'll start explaining them, then after 10 or 100 you'll add a section about it to the FAQ hoping that it'll solve all the problems of all the users. But the reports keep coming. 95% of the users don't read even the first 5 sentences of the app description, let alone click on a link to a FAQ... Garmin support would get a huge amount of unhappy users' complaints as well...