GC mobile iOS: setting returned as null if non-numeric entered for numeric

TL;DR: For bad settings, GCM sends null to the app, but shows the default value to the user, and this isn't okay.

I know this will be a controversial bug report, but please hear me out.

If a setting is defined as "numeric" and the user enters something non-numeric in GCM iOS, like an empty string, "abcd" or "2adsf", that property will apparently be returned as to the app as null.

This is problematic for reasons to go beyond the obvious, IMO. Obviously it's trivial for the app to check if the returned property was null. But what value is it actually supposed to use (internally) now?
1) It could use 0 or null, assuming those are valid values
2) It could use the real default, but how does it know what the real default is?

The problem with 1) is that when you return to the app settings page in GCM, it shows that setting as the default value. So now the setting in GCM and the setting in the app are different, which is not expected behaviour. Devs will have to tell users to send settings a second time if the first time didn't "take". I bet this has happened already.

The problem with 2) is you have to duplicate all your non-zero numeric defaults in both the properties.xml and the app code....

I think if GCM is going to show you the default value for a bad setting when you return to the settings page, it should also have sent the default value to the app in the first place.

This is just my opinion, but I think apps should be able to assume that GCM enforces all the settings constraints defined in the XML, such as the type, range and default value, otherwise what was the point of defining them there? A perfectly behaved app would have to have two copies of all its numerical defaults, but I bet nobody does that....

Hopefully I didn't miss something here.
  • Former Member
    Former Member
    Hey. I'll take a look at this for you. Based on what you're saying, I think I agree. I'll check to see if this is a bug or a just a design that could be better.

    Thanks,
    -Coleman
  • Thanks Coleman.ConnectIQ

    TL;DR Please do not allow users to even submit invalid settings, because then you'll have to silently reject/change them as you do today. As a user I want to know whether all my changes were accepted or not, and today there's no (direct) way to know.

    Devs are telling users not to use GCM for settings, and that's not okay.

    ---

    Just as a follow-up, I have noticed some devs telling users:
    - Not to use Garmin Connect Mobile to change app settings, but to use Garmin Express instead. The rationale is that "sometimes Garmin Connect doesn't work" when it sends your settings. Which is true based on what I reported above. And there's also the issue where GC iOS just exits the settings page when it auto-syncs over bluetooth.
    - That if the user enters a non-numeric value in a numeric setting, and the app crashes, it's basically the user's fault for entering bad settings.

    I'm sorry, but I think this kind of thing doesn't put the Connect IQ platform in a positive light. I would never want to tell the user that it's their fault the app crashed, but it seems that's the situation we have now.

    I'm not saying this to throw shade, but only to point out that it would benefit devs, users and Garmin if the settings constraints were enforced on all platforms. This would certainly save some code space, for older CIQ1 watches especially, to avoid all the checking / type conversion / defaults that would need to go into an app that behaved perfectly. Apps could actually save code "for free", if they could assume that users had the latest version of Garmin Connect or Garmin
    Express when changing settings (*).

    On a side note, I don't think GC should just automatically and silently reject bad settings the way it does today, with no notice to the user. Whether that bad setting would've been replaced with null (nope) or the real default (please!), the user should be notified and given a chance to do something about it. I realize this somewhat conflicts with the idea of replacing a bad value with anything at all, so maybe bad values should just be highlighted and the user given a chance to fix them.

    I also realize this kind of thing is harder on mobile, but I think the key is that the user should not be able to exit settings without confirming to save/discard changes. One of example of this on mobile is Account settings on iOS. You have to tap Edit to change them, and once you do that, Back goes away, and you've only got Cancel and Done. I think GC app settings should be exactly like this.

    There should be no way to...
    ...Go Back and just accidentally lose settings. (Or to have auto-sync automatically kick you out of the settings).
    This is extremely frustrating for apps that have a ton of settings.

    ...Enter bad settings and have them automatically changed to anything.
    Please force the user to fix bad settings before letting them save settings. Or, they can Cancel all their changes.

    Yes, this is going back to the bad old days of complex desktop and web apps, but for important settings with constraints, I think that's what has to be done.

    Alternatively, find a way to implement a numerical picker where there's no way to enter an invalid value. Easy for integers, not sure about floats. (I don't know if ranges are supported for floats....) For floats, you have a text field with input masking, but then you also have to handle a blank value, which runs into the same problem.

    A nice solution would probably be a combo of forcing the user to accept/cancel changes, as well as implementing a numerical spinner for integers, and a masked input field for floats. Just IMO.

    As an end user, I want to know for sure whether the settings I entered were accepted or rejected. I don't want to have to guess that it worked or go back into the settings to check (which wouldn't even help today), or submit a second time to be sure.

    ---

    (*) For example, for numeric (integer or float) settings, the get property code becomes a one-liner:
    // this should be fine as long as the myNumericSetting var has the same type as the property
    myNumericSetting = App.getProperty("myNumericSetting");


    Today, it's more like:
    var x = App.getProperty("myNumericSetting");
    if (x != null) // guard against null sent due to invalid settings
    {
    myNumericSetting = x.toFloat(); // fix for android GC bug where float setting sent as string
    }
    else
    {
    myNumericSetting = ??????; // in a perfect world we would set the default value here
    }


    Of course devs can write wrappers for this stuff, but I don't think it should be necessary.