iOS CIQ SDK Setup

This took me forever to figure out, so I figured that I'd share.

In order to successfully add the CIQ iOS SDK to your project (to create a companion app), you need to do the following:

  • Drag ConnectIQ.framework in to the "Embedded Binaries" list in <Target App> -> General
  • In <Target App> -> Info -> URL Types add a new URL scheme where
    • "Identifier" is your bundle name (e.g. com.whatever.appname)
    • "URL Schemes" is whatever you choose (passed to ConnectIQ on initialization)
    • "Role" is "None"
  • In Info.plist add the following (grants permission to your app to open the Garmin Connect app URL)

<key>LSApplicationQueriesSchemes</key>
<array>
<string>gcm-ciq</string>
</array>

  • In Info.plist, if there is no definition for CFBundleDisplayName (which is the default for Xcode Single App View projects), add the following definition

<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>

Without this, the URL that the ConnectIQ iOS Framework generates is missing a parameter, and it won't open a return URL to your app (failing silently).

Then check out these example apps on github to see how to use the SDK:

https://github.com/dougw/Garmin-ExampleApp-Swift.git

https://github.com/clawoo/gexporter-ios.git

Hope this saves someone else some time, as far as I can tell most of these steps aren't documented anywhere. :(

  • Hi All,

    Please I would need some help. I’m trying to work with the Garmin companion APP sample code. And I’m stuck on same point.  Can anyone help with some insights? I’m getting the following error:

    2019-09-12 07:48:01.787828+0200 ExampleApp[430:30383] Can't end BackgroundTask: no background task exists with identifier 6 (0x6), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.

    Seem the methods to handle Background task have changed. The code open Conect IQ App and gets back to device list without device, obviously device is connected.

    In the other hand I’m getting the same error with the sample code in Swift posted in the tread we have been talking in the forum. And also the function to handle OpenURL is returning “nil”

    2019-09-12 07:40:09.920315+0200 Garmin-ExampleApp-Swift[426:29594] Can't end BackgroundTask: no background task exists with identifier 1 (0x1), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.

    Received URL: garmin-exampleapp-swift://device-select-resp?ciqApp=Connect&ciqBundle=com.garmin.connect.mobile&ciqScheme&ciqSdkVersion=10000&d0ID=69211CC2-6C50-31C9-1982-F5FD6BE553E2&d0Model=fenix%205X%20Plus&d0Name=fenix%205X%20Plus

    handleOpenURL: Source application value was nil, expecting com.garmin.connect.mobile; disregarind open request, likely not for us.

    SAMPLE CODE:

    https://github.com/dougw/Garmin-ExampleApp-Swift.git


    func handleOpenURL(_ url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    
            guard let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String else {
    
                print("handleOpenURL: Source application value was nil, expecting \(IQGCMBundle); disregarind open request, likely not for us.")
    
                return false
    
            }
    
            
    
            if (url.scheme! == ReturnURLScheme) && (sourceApplication == IQGCMBundle) {
    
                
    
                let devices = ConnectIQ.sharedInstance().parseDeviceSelectionResponse(from: url)
    
                dump(devices)
    
                if let devices = devices, devices.count > 0 {
    
                    print("Forgetting \(Int(self.devices.count)) known devices.")
    
                    self.devices.removeAll()
    
                    for (index, device) in devices.enumerated() {
    
                        guard let device = device as? IQDevice else { continue }
    
                        print("Received device (\(index+1) of \(devices.count): [\(device.uuid), \(device.modelName), \(device.friendlyName)]")
    
                        self.devices.append(device)
    
                        print("status>>> \(ConnectIQ.sharedInstance().getDeviceStatus(device).rawValue)")
    
                    }
    
                    self.saveDevicesToFileSystem()
    
                    self.delegate?.devicesChanged()
    
                    return true
    
                }
    
            }
    
            return false

    There is any way to have support or to try an actual version of sample code companion APP although in beta or test state?

    Thanks

  • Yeah, it's mostly there, my big stumbling point was CFBundleDisplayName (as there is no error output, Connect on iOS just doesn't do anything). Figured I'd post a full set of instructions though so it was all in one place.

  • I'm trying to develop an iOS companion app for my Garmin IQ app and have run into the "Source application value was nil" issue as posted by FGM. I have followed all instructions in the top post as well as the Garmin iOS SDK docs. I've used the code from https://github.com/dougw/Garmin-ExampleApp-Swift.git

    According to Apple's docs for UIApplication.OpenURLOptionsKey.sourceApplication, this value is only passed if the originating app is from the same group/team:

    The value of this key is an NSString object containing the bundle ID of the app that made the request. If the request originated from another app belonging to your team, UIKit sets the value of this key to the ID of that app. If the team identifier of the originating app is different than the team identifier of the current app, the value of the key is nil.

    This seems like a deal-breaker, or am I missing something? Does anyone have a working iOS Companion app on iOS 13+ ?

    Thanks!

  • Update: it seems like skipping the sourceApplication check and relying only on the url.scheme matching works fine at first look. Wondering what issues might be triggered later on, but for now it'll do.

  • Any updates about this issue? Followed the steps described in the thread, but still receive this issue:

    handleOpenURL: Source application value was nil, expecting com.garmin.connect.mobile; disregarind open request, likely not for us.

    ,  ?