iOS n'avait jamais demandé l'autorisation Bluetooth, et le scan attendait un état qui n'arrivait pas
« aucun appareil Bluetooth détecté » après 30 s de scan. La cause n'était pas la
montre : Réglages → coach ne contenait même pas de ligne Bluetooth. L'alerte
d'autorisation n'avait jamais été présentée.
La raison est dans le SDK. `CBDeviceListenerImpl.search()` commence par
`monitorBleState().filter { $0 == .poweredOn }` — tant que cet état n'arrive
pas, le flux n'émet rien et le scan ne démarre jamais. Or l'état ne peut venir
que d'un CBCentralManager, et c'est sa création qui déclenche la demande
d'autorisation. Aucun manager n'existant, on attendait un signal que rien ne
pouvait produire, puis on concluait « aucun appareil » au timeout. Avoir la clé
NSBluetoothAlwaysUsageDescription dans Info.plist ne suffit pas : elle fournit
le texte de l'alerte, elle ne la provoque pas.
`SondeBluetooth` crée donc le manager, attend son premier état non-`.unknown`
(l'état transitoire du démarrage, sur lequel il ne faut pas conclure), et
traduit ce qu'il dit : autorisation refusée, Bluetooth éteint, matériel absent.
Le cas d'erreur est distinct de watchNotFound — on n'a même pas pu chercher, et
parler de la montre envoyait chercher au mauvais endroit. Deux tests verrouillent
cette distinction.
Au premier lancement après ce correctif, iOS présentera l'alerte : il faut
l'accepter. Ensuite seulement on saura si la Vantage accepte une connexion
tierce, qui reste la question de fond.
75 tests au vert sur tests-linux.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -156,3 +156,27 @@ final class PolarPftpErrorTests: XCTestCase {
|
||||
XCTAssertEqual(messages.count, 3)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - « La radio ne marche pas » ≠ « la montre est introuvable »
|
||||
//
|
||||
// Le 2026-08-31, le scan a tourné 30 s et rendu « aucun appareil » — alors que
|
||||
// la vraie cause était en amont : iOS n'avait jamais demandé l'autorisation
|
||||
// Bluetooth, et la ligne n'apparaissait même pas dans les réglages de l'app.
|
||||
// Un message parlant de la montre envoyait chercher au mauvais endroit.
|
||||
|
||||
extension PolarPftpErrorTests {
|
||||
|
||||
func testRadioInutilisableNeParlePasDeLaMontre() {
|
||||
let e = PolarPftpError.bluetoothUnusable(
|
||||
"coach n'a pas l'autorisation d'utiliser le Bluetooth.")
|
||||
XCTAssertFalse(e.description.contains("montre"))
|
||||
XCTAssertTrue(e.description.contains("autorisation"))
|
||||
}
|
||||
|
||||
func testRadioInutilisableEstDistinctDeMontreIntrouvable() {
|
||||
let radio = PolarPftpError.bluetoothUnusable("Bluetooth désactivé").description
|
||||
let montre = PolarPftpError.watchNotFound(30, vues: 0,
|
||||
sansPsFtp: 0, muettes: 0).description
|
||||
XCTAssertNotEqual(radio, montre)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user