2 votes

Comment empêcher les appareils de se connecter automatiquement les uns aux autres via Bluetooth

Je suis en train d'explorer le monde du bluetooth pour un projet de classe sur lequel je travaille.

https://www.ralfebert.de/tutorials/ios-swift-multipeer-connectivity/

J'ai utilisé le tutoriel ci-dessus pour une connexion bluetooth/wifi et j'ai appris à envoyer des données entre deux appareils. Tout fonctionne très bien !

Ma question est la suivante : comment faire en sorte que les appareils ne se connectent pas automatiquement l'un à l'autre en utilisant le bluetooth. J'aimerais que vous puissiez cliquer sur un bouton qui ouvre un menu dans lequel vous pouvez choisir des appareils pour une connexion bluetooth en fonction de leur nom. Je n'ai pas trouvé de tutoriels en ligne et j'espérais que quelqu'un ici pourrait m'aider.

Je cherche à pouvoir faire apparaître ce menu : https://i.stack.imgur.com/4hP3h.png

1voto

ericWasTaken Points 41

Étant donné que votre question est très spécifique à l'article exemple, je répondrai directement sur ce que vous pouvez modifier dans ce code. Notez que je n'ai pas écrit ce code à l'origine et que je n'ai apporté que des modifications minimales pour le faire fonctionner comme vous l'avez demandé.

Voici le lien : https://www.ralfebert.de/tutorials/ios-swift-multipeer-connectivity/

Ce code connecte effectivement automatiquement les appareils sans aucune intervention de l'utilisateur. La raison pour laquelle les appareils se connectent est que dans le délégué MCNearbyServiceBrowserDelegate, la méthode browser(browser:foundPeer:withDiscoveryInfo) appelle immédiatement la méthode invitePeer.

// C'est ce qui provoque la connexion immédiate aux appareils
browser.invitePeer(peerID, to: self.session, withContext: nil, timeout: 10)

En passant, le but de la méthode de délégué browser(browser:foundPeer:withDiscoveryInfo) est en effet de vous informer que de nouveaux pairs sont disponibles. C'est à vous de vous connecter à eux si vous le souhaitez !

Pour faire ce que vous voulez (c'est-à-dire vous connecter manuellement en sélectionnant un appareil auquel vous connecter), au lieu de vous connecter automatiquement, vous devez suivre les pairs que vous avez trouvés, communiquer cela à votre vue et laisser la vue afficher une liste, ou tout autre UI que vous souhaitez afficher.

Faisons cela.

Tout d'abord, à l'intérieur de protocol ColorServiceManagerDelegate {} :

// Ajoutez une méthode de protocole pour communiquer que les pairs "trouvés" ont changé.
// Nous devrons implémenter cela dans la vue et le ferons plus tard !
func foundPeersChanged(manager: ColorServiceManager, peersFound: [String])

Ensuite, à l'intérieur de la classe principale class ColorServiceManager : NSObject {}, ajoutons 2 propriétés pour suivre les pairs trouvés :

// Ajoutez deux propriétés de classe pour suivre les pairs que nous avons trouvés
fileprivate var peerNames: [String] = []
fileprivate var peerObjects: [MCPeerID] = []

Ensuite, dans MCNearbyServiceBrowserDelegate, modifiez foundPeer et lostPeer pour suivre la liste des pairs.

func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
  NSLog("%@", "foundPeer: \(peerID)")

  // Ici, nous avons trouvé un pair.

  // Ajouter la liste des pairs trouvés
  if !self.peerNames.contains(peerID.displayName) {
    self.peerNames.append(peerID.displayName)
  }
  if !self.peerObjects.contains(peerID) {
    self.peerObjects.append(peerID)
  }

  // Déclencher notre délégué pour informer les implémentants qu'il y a eu un changement dans les pairs trouvés
  self.delegate?.foundPeersChanged(manager: self, peersFound: self.peerNames.sorted())

}

func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
  NSLog("%@", "lostPeer: \(peerID)")

  // Ici, nous notons que nous avons perdu un pair.

  // Bien sûr, nous devons également supprimer les pairs de l'ensemble des pairs trouvés lorsque nous en perdons un.
  self.peerNames = self.peerNames.filter { (peerName) -> Bool in
    peerName != peerID.displayName
  }
  self.peerObjects = self.peerObjects.filter({ (peerToTest) -> Bool in
    peerToTest != peerID
  })

  // Déclencher notre délégué pour informer les implémentants qu'il y a eu un changement dans les pairs trouvés
  self.delegate?.foundPeersChanged(manager: self, peersFound: self.peerNames.sorted())

}

Ensuite, vous aurez besoin d'un moyen de se connecter à un pair, donc dans la classe ColorServiceManager, juste après la méthode init(), ajoutez une nouvelle méthode :

func invite(peer peerName: String) {
  NSLog("%@", "peerName: \(peerName)")
  // Trouver le nom du pair dans le tableau peerNames et si trouvé, l'inviter à se connecter
  if let indexOfPeer = self.peerNames.index(of: peerName) {
    // Trouvé, donc inviter le pair à se connecter
    let peerToInvite = self.peerObjects[indexOfPeer]
    NSLog("%@", "invitePeer: \(peerToInvite)")
    self.serviceBrowser.invitePeer(peerToInvite, to: self.session, withContext: nil, timeout: 10)
  }
}

Dans votre contrôleur de vue, vous devez implémenter une tableView et les méthodes associées ainsi que la nouvelle méthode dans le délégué.

Allez dans Interface Builder et ajoutez une Table View à la vue, puis reliez-la à votre contrôleur de vue comme d'habitude :

@IBOutlet weak var tableView: UITableView!

Assurez-vous d'ajouter une cellule prototype à la tableview dans IB. Réglez la cellule sur Style : Basic et définissez l'Identifiant sur foundPeerCell.

Ajoutez également une propriété à votre contrôleur de vue pour sauvegarder la tableView :

var foundPeers: [String] = []

Ensuite, ajoutez ce qui suit à extension ColorSwitchViewController: ColorServiceManagerDelegate {}

func foundPeersChanged(manager: ColorServiceManager, peersFound: [String]) {
  // La liste des pairs trouvés a changé, nous mettons à jour notre tableView
  NSLog("Liste actuelle des pairs:\n\(peersFound)")
  self.foundPeers = peersFound
  DispatchQueue.main.async {
    self.tableView.reloadData()
  }
}

Enfin, ajoutez le code nécessaire pour gérer la tableView :

/**
Source de données UITableView
*/
extension ColorSwitchViewController: UITableViewDataSource {

  func numberOfSections(in tableView: UITableView) -> Int {
    return 1
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return foundPeers.count
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "foundPeerCell")!
    cell.textLabel?.text = foundPeers[indexPath.row]
    return cell
  }

}

/**
Délégué UITableView
*/
extension ColorSwitchViewController: UITableViewDelegate {

  // gérer le clic sur une ligne
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Renvoyer l'invitation au pair.
    colorService.invite(peer: foundPeers[indexPath.row])
    // Désélectionner la ligne
    tableView.deselectRow(at: indexPath, animated: true)
  }

}

Remarquez que tableView(tableView:didSelectRowAt) est l'endroit où nous revenons au ColorServiceManager et invitons le pair que l'utilisateur a tapé.

Notez que je n'ai pas ajouté beaucoup de gestion des erreurs, vous voudrez donc renforcer, etc., ce code.

Une version modifiée du projet est disponible ici : https://github.com/ericwastaken/Bluetooth_ConnectedColors/tree/stack_overflow_answer_manual_device_connection

Bonne chance !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X