Arrêt du chantier BLE : l'approche « piloter le listener à la main » est la mauvaise

Cinq causes trouvées et corrigées aujourd'hui, chacune par une mesure — et le
publisher reste muet. Le manager du SDK existe pourtant : l'avertissement
CoreBluetooth sur le restore identifier ne peut apparaître que s'il a été
instancié.

Ce que ça enseigne compte plus que la sixième hypothèse : instancier
CBDeviceListenerImpl soi-même revient à réimplémenter ce que PolarBleApiImpl
fait, sans en voir le détail. On avance d'un cran par essai, et chaque essai
coûte à Sylvain un cycle Xcode complet. Continuer à pousser des correctifs sur
des mécanismes internes que je ne peux pas exécuter, c'est exactement
l'extrapolation que ce projet s'interdit.

Le runbook porte donc les cinq causes déjà écartées — pour que personne ne les
revérifie — et la piste qui me paraît juste : passer par
PolarBleApiDefaultImpl.polarImplementation, le chemin supporté, avec son point
bloquant énoncé (le listener y est privé ; reste à voir si une API publique
donne accès à la session ou au client PsFTP, faute de quoi la voie est fermée
elle aussi).

Rien du travail serveur n'est perdu : le câble fonctionne intégralement, et
c'est lui qui a écrit la séance du jour sur la montre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Bettinelli
2026-08-31 13:25:52 +00:00
parent 01607ed75c
commit 0f96122cca

View File

@@ -166,6 +166,44 @@ abonné à `search()`. L'ordre est critique : si `bleStateSubject` est un
`PassthroughSubject`, un état émis avant l'abonnement serait perdu et on `PassthroughSubject`, un état émis avant l'abonnement serait perdu et on
retomberait sur le même silence. retomberait sur le même silence.
## 🔴 ÉTAT AU SOIR DU 31/08 : bloqué, et pourquoi il faut changer d'approche
Malgré le réveil du manager, le filtre Polar et l'abonnement unique, le
publisher de `search()` **reste muet** : `bleStateSubject` n'émet jamais
`.poweredOn`. Le manager du SDK existe pourtant — l'avertissement CoreBluetooth
`SDKCBCentralManager … has no restore identifier` ne peut apparaître que s'il a
été instancié.
**Ce qui a été corrigé et vérifié en chemin** (ne pas refaire) :
| Cause | Preuve |
|---|---|
| Autorisation Bluetooth jamais demandée | pas de ligne « Bluetooth » dans Réglages → coach |
| Manager `lazy` jamais réveillé | publisher muet ; `blePowered()` le crée |
| Aucun filtre de scan | 43 appareils, sessions ouvertes jusque sur l'Apple Watch |
| Attentes sans limite de temps | envoi figé sans message |
| Fenêtres de scan successives | `bleStateSubject` ne publie que sur changement |
**⚠️ Ce que ça enseigne** : instancier `CBDeviceListenerImpl` soi-même revient à
réimplémenter ce que `PolarBleApiImpl` fait, sans en voir le détail. On avance
d'un cran à chaque essai, et chaque essai coûte un cycle Xcode.
### Piste pour la reprise : passer par l'API publique
Plutôt que de piloter le listener à la main, utiliser
`PolarBleApiDefaultImpl.polarImplementation(…)` — le chemin que Polar supporte —
pour la découverte et la connexion (`searchForDevice()`, `connectToDevice(_:)`),
puis n'atteindre `BlePsFtpClient` qu'une fois la session établie par le SDK.
⚠️ À vérifier d'abord, et c'est le point bloquant de cette piste :
`PolarBleApiImpl` garde son `listener` privé. Il faut donc chercher si une API
publique donne accès à la session ou au client PsFTP — sinon cette voie est
fermée elle aussi, et il faudra soit forker le SDK, soit renoncer au Bluetooth
et garder le câble.
**Le câble, lui, fonctionne intégralement** : `tools/polar/README.md` du dépôt
`coach_sportif`. Rien de ce qui a été livré côté serveur n'est perdu.
## Ce qui reste inconnu, et ne se lèvera qu'ici ## Ce qui reste inconnu, et ne se lèvera qu'ici
1. **La V3 accepte-t-elle une connexion BLE tierce** alors qu'elle est appairée 1. **La V3 accepte-t-elle une connexion BLE tierce** alors qu'elle est appairée