2016-11-24 2 views
0

Je sais que la réponse est "non", mais je veux dire vraiment -et si l'application passe en arrière-plan (avec le traitement de fond BTLE activé)? Pour 24 heures? Dans une mise à jour d'application? Sous la rubrique «Reconnexion aux périphériques», ce Apple documentation décrit un flux de travail de reconnexion qui tente d'abord de se reconnecter à des périphériques préalablement associés par retrievePeripheralsWithIdentifiers:, puis redémarre la numérisation si vous ne parvenez pas à vous connecter. Comment savez-vous quand abandonner connect -ing à un périphérique précédemment trouvé s'il n'y a pas de timeout formel? Comment savoir quand démarrer/continuer la numérisation si l'idée est de se reconnecter à un appareil BTLE trouvé à chaque fois que vous revenez à proximité, sans que l'utilisateur n'interagisse nécessairement avec votre application? En outre, une note plus bas dans cette page indique que certains périphériques BTLE pourraient s'inventer un identifiant aléatoire chaque fois qu'ils sont allumés. Ainsi, même si vous trouvez des périphériques précédemment appariés de retrievePeripheralsWithIdentifiers:, vous ne pourrez peut-être pas vous connecter. à eux comme leurs noms ont changé. Est-ce que les appareils BTLE le font dans la pratique? C'est fou!Est-ce que CBCentralManager se connecte en permanence?

Répondre

7

Il est difficile de répondre à cette question. Le cadre CoreBluetooth lui-même n'a pas de délai d'expiration officiel sur les demandes de connexion. En fait, il essayera de connecter le périphérique aussi longtemps que possible. Mais combien de temps est-ce?

Eh bien, malheureusement, ce n'est pas quelque chose qui est très bien défini. Vous pouvez être sûr que la connexion ne sera pas interrompue lorsque l'application est au premier plan, mais dès que vous impliquez des connexions en arrière-plan, les choses ne sont plus aussi drôles. Évidemment, comme vous le mentionnez, la connexion en attente ne restera pas après un redémarrage du téléphone, etc., ce qui est bien, car aucun utilisateur ne s'attendrait à ce que l'application soit encore en cours d'exécution après un redémarrage de toute façon. En ce qui concerne les connexions en cours d'exécution longues, vous trouverez dans la documentation d'Apple qu'ils vous demandent d'activer la conservation et la restauration d'état afin de vous assurer que les connexions en attente sont correctement conservées tant que l'application est suspendue. Ce serait bien si cela fonctionnait comme annoncé, mais malheureusement ce n'est pas le cas. Après de nombreuses années de travail avec cela, j'ai trouvé qu'il est presque impossible d'obtenir une connexion fiable en arrière-plan sur iOS. J'ai signalé de nombreux bugs sur ce sujet mais jusqu'à présent, aucun n'a été résolu.

Il y a quelques questions en particulier que je pense que vous devriez porter une attention particulière à:

  1. État conservation et la restauration va complètement cesser de fonctionner si un événement Bluetooth changement d'état se produit pendant que votre application est en l'état terminé. Cela signifie essentiellement que si la puce bluetooth est réinitialisée pour une raison quelconque (par exemple en basculant Bluetooth/mode de vol/etc ..), votre application ne sera plus jamais relancée par Core Bluetooth lorsque le périphérique fait de la publicité à portée. La raison en est que toutes les connexions en attente qui ont été définies par votre application seront effacées chaque fois que la puce bluetooth est redémarrée. Le problème avec ceci est que votre application ne sera pas relancée pour être avertie de ce changement, ainsi les connexions en attente ne seront jamais récupérées. Donc, votre application va penser que les périphériques vont se connecter, alors qu'en fait ils ne le seront pas. Pour moi, celui-ci est le problème le plus sérieux et seul le CoreBluetooth est extrêmement peu fiable. Parfois, le cadre est "bloqué" dans un mauvais état (éventuellement par une condition de course interne ou similaire). Cela peut se produire de manière aléatoire, mais vous pouvez très facilement le reproduire en appelant connectPeripheral immédiatement dans le rappel didFailToConnect ou didDisconnect. Lorsque cela se produit, la propriété "état de connexion" est définie sur "connexion" lorsqu'une connexion en attente n'est en fait pas définie. Pour éviter cela, j'ai trouvé que vous devriez attendre au moins environ 20ms avant de vous connecter, par exemple en utilisant un dispatch_after ou quelque chose comme ça.

  2. La structure utilise en interne les connexions XPC pour la communication interprocessus afin de fournir un événement bluetooth. Dans certains cas, cela se casse pour une raison quelconque et la connexion sera perdue. Je ne sais pas pourquoi cela se produit, mais chaque fois que cela se produit, la préservation de l'état cesse de fonctionner et vous devrez manuellement relancer l'application pour en récupérer. Parfois, je parviens à attraper dans les journaux sysdiagnose de l'appareil ...

  3. L'utilisation d'un iPhone 7 et en même temps avoir une Apple Watch (apparié le téléphone) va complètement casser toutes les reconnexions derrière l'écran de verrouillage au cas où le La montre n'est pas actuellement connectée (hors de portée/mode de vol/batterie faible ou pour toute autre raison). C'est particulièrement mauvais car il a été introduit récemment! Mais il semble que l'Apple Watch pour une raison quelconque a "priorité" sur les autres périphériques Bluetooth.

Ce sont du haut de ma tête, mais il y a aussi d'autres problèmes. En ce qui concerne les adresses aléatoires, le plus souvent ces périphériques utilisent des adresses dites "random resolvable". Cela signifie qu'ils apparaissent aléatoires mais en fait ils peuvent être résolus en utilisant une clé IRK (Identity Resolving Key) qui est généralement partagée lors de la liaison Bluetooth initiale. Les appareils qui utilisent des adresses complètement aléatoires sont, à ma connaissance, peu courants.