Les fenêtres de scan se privaient de l'unique émission d'état
Le manager lazy était bien réveillé — l'avertissement CoreBluetooth sur le restore identifier le prouve, il ne peut apparaître que si le manager existe. Et pourtant le publisher restait muet. La cause est mon découpage en cycles de 4 s. `bleStateSubject` ne publie que sur CHANGEMENT d'état : le premier cycle réveillait le manager et recevait `.poweredOn`, mais aux cycles suivants l'état ne changeait plus, donc plus rien n'était émis. Chaque nouvel abonnement attendait une transition qui avait déjà eu lieu. Un seul abonnement, de la durée du timeout, supprime le problème : on reçoit l'émission là où elle se produit, et le scan tourne sans être relancé. La boucle d'ouverture de session garde une marge au-delà du scan — couper à la seconde du timeout ferait échouer la seule montre trouvée. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -253,15 +253,25 @@ final class PolarPsFtpWriter {
|
|||||||
var sansPsFtp = 0 // aperçus mais ne portant pas le service FEEE
|
var sansPsFtp = 0 // aperçus mais ne portant pas le service FEEE
|
||||||
var muettes = 0 // portant FEEE mais dont waitPsFtpReady échoue
|
var muettes = 0 // portant FEEE mais dont waitPsFtpReady échoue
|
||||||
|
|
||||||
// Le scan se fait par fenêtres successives, et non en une seule passe :
|
// ⚠️ UN SEUL ABONNEMENT, SUR TOUTE LA DURÉE — pas des fenêtres.
|
||||||
// CoreBluetooth peut n'être pas encore `poweredOn` au premier appel — le
|
//
|
||||||
// scan ne démarre alors jamais, et une fenêtre unique conclurait à tort
|
// Le découpage en cycles de 4 s se privait de l'unique émission d'état :
|
||||||
// qu'aucun appareil n'existe. Réessayer couvre ce démarrage.
|
// `bleStateSubject` ne publie que sur CHANGEMENT. Le premier cycle
|
||||||
while Date().timeIntervalSince(debut) < timeout {
|
// réveillait le manager et recevait `.poweredOn` ; aux cycles suivants
|
||||||
let sessions = try await sessionsVues(listener, fenetre: 4)
|
// l'état ne changeait plus, donc plus rien n'était émis et le publisher
|
||||||
vues = max(vues, sessions.count)
|
// restait muet — mesuré le 2026-08-31, y compris après avoir réglé le
|
||||||
|
// réveil du manager.
|
||||||
|
//
|
||||||
|
// Une seule fenêtre, de la durée du timeout, supprime le problème : on
|
||||||
|
// reçoit l'émission là où elle a lieu, et le scan tourne sans être
|
||||||
|
// relancé.
|
||||||
|
do {
|
||||||
|
let sessions = try await sessionsVues(listener, fenetre: timeout)
|
||||||
|
vues = sessions.count
|
||||||
for session in sessions {
|
for session in sessions {
|
||||||
if Date().timeIntervalSince(debut) > timeout { break }
|
// Marge au-delà du scan : ouvrir une session prend du temps, et
|
||||||
|
// couper ici ferait échouer la seule montre trouvée.
|
||||||
|
if Date().timeIntervalSince(debut) > timeout * 2 { break }
|
||||||
listener.openSessionDirect(session)
|
listener.openSessionDirect(session)
|
||||||
guard let client = session.fetchGattClient(BlePsFtpClient.PSFTP_SERVICE)
|
guard let client = session.fetchGattClient(BlePsFtpClient.PSFTP_SERVICE)
|
||||||
as? BlePsFtpClient else {
|
as? BlePsFtpClient else {
|
||||||
|
|||||||
Reference in New Issue
Block a user