我正在为我正在研究的课程项目探索蓝牙世界。
https://www.ralfebert.de/tutorials/ios-swift-multipeer-connectivity/
我一直在使用上面的教程进行蓝牙/ wifi连接,我学会了在两个设备之间发送数据。一切都很好!
我的问题是:我如何制作它,以便设备不会使用蓝牙自动连接到彼此。我希望你能够点击一个按钮,打开一个菜单,你可以根据名字选择蓝牙连接设备。我无法找到任何在线教程,并希望有人可以帮助我。
我正在寻找弹出此菜单的功能: https://i.stack.imgur.com/4hP3h.png
答案 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
更改foundPeer
和lostPeer
以跟踪对等列表。
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
祝你好运!