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.
- Pair the watch and register a watch app with the SDK.
- Call sendMessage with a large message (about 58 packets).
- Lose the Bluetooth link 2 to 5 s after the call.
- 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.