Under Review

Connect IQ Store does not add Instinct 3 Solar 50mm product ID to manifest

When selecting “Instinct® 3 Solar 45mm / 50mm” in the Connect IQ Store and releasing the app, only the product ID “instinct3solar45mm” is added to the generated manifest.xml.

The product ID “instinct3solar50mm” is not added automatically, which causes the app to be marked as incompatible on Instinct 3 Solar 50mm devices in the Garmin Connect IQ App.

Additional issue:
If “instinct3solar50mm” is added manually to manifest.xml using the “Edit as XML” option, the Connect IQ builder reports that this product ID does not exist or is invalid.

A likely quick fix for this issue would be to update the Store-side product mapping so that the “Instinct® 3 Solar 45mm / 50mm” selection correctly maps to both underlying product IDs.

At minimum, the Store mapping for “Instinct® 3 Solar 45mm” should also include the 50mm variant, so that selecting the combined device option results in all supported product IDs being added to the generated manifest.

This would align the Store UI grouping with the actual device compatibility and prevent 50mm devices from being incorrectly marked as incompatible.

  • Additional details and clarification:

    When you export your CIQ project, an IQ file is created, which is a ZIP containing app binaries (PRGs), app data, and metadata.

    In the IQ file, there is a folder for each part number. Each folder contains all the data necessary to install the app for that part number, including the app PRG (same binary that you can sideload to a real device).

    So even though we select product IDs (sometimes referred to as "devices") like instinct3solar45mm and fr970 in a project's manifest.xml, under the covers, when you export the project the compiler really builds your app once for each part number. That's why we often see warning messages about how a certain number of *part numbers* are being skipped during hte export.

    It's the part numbers that are truly significant, not the product IDs. For each product ID to manifest.xml, when you export your project, the compiler will try to build the part numbers contained in that product's compiler.json, but individual part numbers can be filtered for various reasons:

    Part numbers filtered at export time:

    - minApiLevel in project's manifest.xml is greater than connectIqVersion.

    This was especially an issue for some older devices which have separate part numbers for APAC (Asia-Pacific) and WW (worldwide) models, as the APAC connectIqVersion in compiler.json was often significantly lower than the WW version, sometimes temporarily and sometimes permanently (this may or may not reflect the actual situation on real devices).

    So it would be pretty common for a dev to specify some minApiLevel which included WW part numbers, but happened to exclude APAC part numbers, and they wouldn't find out until users in Asia complained

    - project languages not supported: more than 0 languages are specified, and none of the specified languages is supported by a given part number

    e.g. Sometimes a dev who wants to support APAC devices will specify only Asian languages in manifest.xml, incorrectly thinking that the "default" language is always English. But just because there are default language resources doesn't mean that the compiler thinks of the resources as English, and it doesn't mean the compiler assumes that your app always supports English. So in this case, it's WW part numbers which end up getting filtered (since WW part numbers typically don't support Asian languages if there is an APAC part number for the same product)

    (The easiest way to avoid this is that if you specify languages at all, make sure you always include English, since I'm not aware of any part numbers which don't support English.)

    Part numbers filtered when a user tries to download the app from the store:

    - user's firmware is too old: even if a part number is included in the exported IQ file, if a user tries to install your app and their device's firmware is lower than what's specified in compiler.json [*], then the store will block the download and display an error message asking the user to update their firmware.

    [*] i.e. [product id]\compiler.json:partNumbers[].firmwareVersion

    It's especially clear that this is the minimum firmware version when you look inside the IQ file and note that firmwareVersion for each part number (from compiler.json) is added to the IQ manifest as minimumFirmwareVersion.

    So in this way, Garmin guarantees that an app built against a certain set of device files (including compiler.json) will have *guaranteed* minimum firmware versions for each part number, which in turn guarantees minimum CIQ API levels.

    Ofc these device files change over time (via SDK manager updates), and you can't roll back to old device files, which means that an app version you build and export today may require newer firmware than some app version you released in the past. In some ways this is a good thing, as it guarantees that you get newer bug fixes and CIQ API versions. But it also means that users who never update their firmware or who rolled back their firmware to avoid new bugs will be unable to download CIQ apps which were updated recently.

  • 2] We can map part numbers to customer-facing models by looking at the API that the CIQ web store uses to list compatible devices for a given app. Ofc to even open the webstore is pretty tricky these days, but luckily we can still google popular apps like Spotify.

    Searching up "connect iq spotify" yields: https://apps.garmin.com/apps/30c6c876-ba43-4cbb-b4c7-03583a7cb66b

    If we open on the browser's network inspector and reload the app's store page, we see that the following request relating to devices is made:

    https://apps.garmin.com/api/appsLibraryExternalServices/api/asw/deviceTypes

    Searching for those part numbers in the JSON response yields:

      {
        "id": "314",
        "partNumber": "006-B4585-00",
        "name": "Instinct® 3 – 45 mm, Solar",
        "additionalNames": [],
        "imageUrl": "https://res.garmin.com/en_GB/products/010-02934-00/v/pd-10-sm.jpg",
        "urlName": "Instinct3-45mm-s"
      },
    //...
      {
        "id": "333",
        "partNumber": "006-B4759-00",
        "name": "Instinct® 3 – 50 mm, Solar",
        "additionalNames": [
          "Instinct® 3 – 50 mm",
          "Solar",
          "Tactical"
        ],
        "imageUrl": "https://res.garmin.com/en/products/010-02935-00/v/pd-09-sm.jpg",
        "urlName": "Instinct3-50mm-s"
      },
    

    So as a matter of fact, "006-B4759-00" is in fact the 50mm variant, and you can verify that it was excluded from the build by opening the IQ file in any app that can open a ZIP file [rename the extension to .ZIP if you have to]


    --
    Note to Garmin: pretty interesting that even though the build system and store revolve around devices and part numbers, nothing I said above is really explained in any official documentation. Significantly, the procedure for viewing the actual mapping of part numbers to customer-facing models [from the web store's POV anyway] is not explained.

    Ofc as usual I had to fight with the forums for about 30-60 seconds just to get these responses accepted....

  • Details:

    The product ID instinct3solar45mm indeed maps to “Instinct 3 Solar 45mm / 50mm”.

    The reason it can be just one device is because both variants have similar-enough hardware (e.g. both have the same display resolution)

    This can be seen in a few ways:

    1] By inspecting the CIQ device files for the instinct3solar45mm device:

    1a] In VS Code, open command palette [CTRL/CMD-SHIFT-P]

    1b] Select "Monkey: Open Samples Folder"

    This will open the sapmles folder for the current SDK ...\ConnectIQ\SDKs\[current SDK]\samples

    1c] Navigate up 3 folders to ...\ConnectIQ\

    This is the parent folder for the Connect IQ SDKs and devices.

    1d] Navigate to ...\ConnectIQ\devices\instinct3solar45mm 

    1e] Open compiler.json

    1f] Note product display name:

    "displayName": "Instinct 3 Solar 45mm / 50mm"

    1g] Note that there's 2 entries in the partNumbers[] array. Each of these is basically a different software variant of a single hardware platform, although ofc there can be certain physical differences like different case size

            {
                "connectIQVersion": "5.1.0",
    //...
                 "number": "006-B4585-00"
            },
            {
                "connectIQVersion": "5.0.0",
    //...
                "number": "006-B4759-00"
            }
    Note that connectIQVersion is the *minimum* CIQ version that must be installed on the user's device in order to install your app. 
    So if you did specify minApiLevel of 5.1.0 in manifest.xml, the "006-B4759-00" part number will be excluded from the IQ file when you export the project.
    But what is "006-B4759-00"? We can guess that it's the 50mm variant but there's a way to be sure.
  • But there is no such Connect IQ product id as instinct3solar50mm, and I'm not sure why you think there is, except for the fact that your app isn't incompatible with Instinct 3 Solar 50mm in the store.

    The instinct3solar45mm device actually does have 2 variants (part numbers): Instinct 3 Solar 45mm and Instinct 3 Solar 50mm.

    My best educated guess is that you have specified a minimum API level of 5.1.0, which excludes the Instinct 3 Solar 50mm part number but not the 45mm part number.

    If that's the case, the fix is to specify a minimum API level of 5.0.0 or lower.