我怎么做到这样设备不会使用蓝牙自动连接到彼此

时间:2017-03-19 04:50:58

标签: ios swift bluetooth multiplayer

我正在为我正在研究的课程项目探索蓝牙世界。

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

我一直在使用上面的教程进行蓝牙/ wifi连接,我学会了在两个设备之间发送数据。一切都很好!

我的问题是:我如何制作它,以便设备不会使用蓝牙自动连接到彼此。我希望你能够点击一个按钮,打开一个菜单,你可以根据名字选择蓝牙连接设备。我无法找到任何在线教程,并希望有人可以帮助我。

我正在寻找弹出此菜单的功能: https://i.stack.imgur.com/4hP3h.png

1 个答案:

答案 0 :(得分:1)

由于您的问题对示例文章非常具体,我将直接回答您可以对该代码进行更改的内容。请注意,我最初没有编写该代码,我只做了很少的更改,使其适用于您所要求的内容。

这是链接: https://www.ralfebert.de/tutorials/ios-swift-multipeer-connectivity/

该代码确实自动将设备“连接”在一起,而无需用户输入任何内容。设备连接的原因是因为在委托MCNearbyServiceBrowserDelegate中,browser(browser:foundPeer:withDiscoveryInfo)正在立即执行invitePeer方法调用。

// This is what is causing the immediate connection to the devices
browser.invitePeer(peerID, to: self.session, withContext: nil, timeout: 10)

顺便说一下,browser(browser:foundPeer:withDiscoveryInfo)委托方法的目的确实是让你知道新的同伴可用。如果你愿意,你可以联系他们!

要执行您想要的操作(通过选择要连接的设备手动连接),而不是自动连接,您需要跟踪您找到的同伴,将其传达给您的视图并让视图显示列表或您希望显示的任何其他UI。

我们这样做。

首先,在protocol ColorServiceManagerDelegate {}内:

// Add a protocol method to communicate the "found" peers has changed.
// We will need to implement this in the view and will do so later on!
func foundPeersChanged(manager: ColorServiceManager, peersFound: [String])

然后,在主类class ColorServiceManager : NSObject {}内,让我们添加2个属性来跟踪找到的同伴:

// Add two class properties to keep track of the peers we've found
fileprivate var peerNames: [String] = []
fileprivate var peerObjects: [MCPeerID] = []

接下来,在MCNearbyServiceBrowserDelegate更改foundPeerlostPeer以跟踪对等列表。

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

  // Here, we found a peer.

  // Add the list of found peers
  if !self.peerNames.contains(peerID.displayName) {
    self.peerNames.append(peerID.displayName)
  }
  if !self.peerObjects.contains(peerID) {
    self.peerObjects.append(peerID)
  }

  // Fire off our delegate to let implementers know there's been a change in found peers
  self.delegate?.foundPeersChanged(manager: self, peersFound: self.peerNames.sorted())

}

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

  // Here, we note that we've lost a peer.

  // Of course, we also need to remove peers from the set of found peers when we lose a peer.
  self.peerNames = self.peerNames.filter { (peerName) -> Bool in
    peerName != peerID.displayName
  }
  self.peerObjects = self.peerObjects.filter({ (peerToTest) -> Bool in
    peerToTest != peerID
  })

  // Fire off our delegate to let implementers know there's been a change in found peers
  self.delegate?.foundPeersChanged(manager: self, peersFound: self.peerNames.sorted())

}

然后,您需要一种方法连接到对等方,所以在ColorServiceManager类中,在init()方法之后,添加一个新方法:

func invite(peer peerName: String) {
  NSLog("%@", "peerName: \(peerName)")
  // Find the peerName in peerNames array and if found, invite to connect
  if let indexOfPeer = self.peerNames.index(of: peerName) {
    // Found it, so invite the peer to connect
    let peerToInvite = self.peerObjects[indexOfPeer]
    NSLog("%@", "invitePeer: \(peerToInvite)")
    self.serviceBrowser.invitePeer(peerToInvite, to: self.session, withContext: nil, timeout: 10)
  }
}

在视图控制器中,您需要在委托中实现tableView和相关方法以及新方法。

转到Interface Builder并向视图添加表视图,然后照常将其链接到视图控制器:

@IBOutlet weak var tableView: UITableView!

确保将原型单元格添加到IB中的表格视图中。将单元格设置为样式:基本,并将标识符设置为foundPeerCell

此外,向视图控制器添加一个属性以备份tableView:

var foundPeers: [String] = []

然后,将以下内容添加到extension ColorSwitchViewController: ColorServiceManagerDelegate {}

func foundPeersChanged(manager: ColorServiceManager, peersFound: [String]) {
  // The list of found peers has changed, so we update our tableView
  NSLog("Current list of peers:\n\(peersFound)")
  self.foundPeers = peersFound
  DispatchQueue.main.async {
    self.tableView.reloadData()
  }
}

最后,添加管理tableView所需的代码:

/**
 UITableView Data Source
 */
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
  }

}

/**
 UITableView Delegate
 */
extension ColorSwitchViewController: UITableViewDelegate {

  // handle tap on a row
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Send back the invite to the peer.
    colorService.invite(peer: foundPeers[indexPath.row])
    // De-select the row
    tableView.deselectRow(at: indexPath, animated: true)
  }

}

请注意tableView(tableView:didSelectRowAt)是我们连接回ColorServiceManager的地方,并邀请用户点击的同行。

注意,我没有添加很多错误处理,因此您需要强化此代码等。

此处提供了项目的编辑版本: https://github.com/ericwastaken/Bluetooth_ConnectedColors/tree/stack_overflow_answer_manual_device_connection

祝你好运!