Acknowledged
CIQQA-4834

iOS Mobile SDK 1.8.0: sendMessage completion never called after a link drop during a transfer; later sends stuck until app restart

Environment

  • Connect IQ Mobile SDK for iOS 1.8.0 (latest release, f0d29ff), Swift package
  • iPhone 17 Pro Max, iOS 26.7.1
  • Garmin epix 2, firmware 27.18
  • Companion iOS app in Swift. It sends data to 1 watch face and 1 data field.

Description

The Bluetooth link to the watch drops during a transfer. After that, the sendMessage completion block is never called. All later sendMessage calls to that device also get no completion. Only a restart of the iOS app process clears it. A watch restart does not.

The app calls getAppStatus before each send, and the later sends passed that check. So the link was back while the sends stayed stuck.

Evidence

App log, 27 to 31 Oct 2026: 4191 sends, 43 disconnects. 40 disconnects came with no send running and caused no problem. 3 came during a send:

  • Disconnect 4 to 5 s after sendMessage: no completion, 31 later sends also got none, 29 minutes until the app process ended.
  • Disconnect 2 s after sendMessage: no completion, 12 minutes until the app process ended.
  • Disconnect 11 s after sendMessage: later sends completed within 9 s.

Steps to reproduce

The problem is intermittent, and I cannot reproduce it easily on demand.

  1. Pair the watch and register a watch app with the SDK.
  2. Call sendMessage with a large message (about 58 packets).
  3. Lose the Bluetooth link 2 to 5 s after the call.
  4. Let the link return, then call sendMessage again.

4 deliberate tries did not reproduce it: 2 with Bluetooth off in the watch controls, 2 with the watch in a metal pot. In all 4, the completion came back with a failure and later sends worked. So a clean link loss alone is not enough.

Expected

The completion block is always called, with a failure such as IQSendMessageResult_Failure_Timeout, and the next send runs.

Actual

No completion, no error and no later send complete. The watch shows old data, and the app has no way to detect the cause or recover. ConnectIQ.h has no public cancel or reset call.

Code sample

ConnectIQ.sharedInstance().getAppStatus(app) { status in
    guard status?.isInstalled == true else { return }
    ConnectIQ.sharedInstance().sendMessage(message, to: app,
        progress: { _, _ in },
        completion: { result in
            // Not called after the drop described above.
        })
}

Request

Please make sure every send ends with a completion when the link stalls or drops. A public call to cancel pending sends would also help.