蓝牙对战
MultipeerConnectivity框架的使用
MultipeerConnectivity通过WiFi、P2P WiFi以及蓝牙个人局域网进行通信的框架,从而无需联网手机间就能传递消息。其原理是通过广播作为服务器去发现附近的节点,每个节点都以设备名称为标识。
myPeer = MCPeerID.init(displayName: UIDevice.current.name)
session = MCSession.init(peer: myPeer!, securityIdentity: nil, encryptionPreference: .none)
session?.delegate = self
MCSession的几个代理方法必须实现,否则无法建立连接
//监听连接状态
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .notConnected:
print("未连接")
case .connecting:
print("正在连接中")
case .connected:
print("连接成功")
}
}
//发送Dada数据
func sendData(_ messageVo: GPBMessage, successBlock:(()->())?,errorBlock:((NSError)->())?) {
guard let session = session else {
return
}
guard let data = NSDataTool.shareInstance().returnData(messageVo, messageId: 0) else {return}
do {
try session.send(data as Data , toPeers: session.connectedPeers, with: .reliable)
}catch let error as NSError {
errorBlock?(error)
return
}
successBlock?()
}
//接收到的Data数据
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
// 解析出过来的data数据包
NSDataTool.shareInstance().startParse(data) { (gpbMessage) in
self.getMessageBlock?(gpbMessage)
}
}
//接收到的流数据
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
print("streamName")
}
//接收到的文件类型数据
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
print("resourceName")
}
//接收到的文件类型数据,可将文件换路劲
func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL, withError error: Error?) {
}
我们通过MCAdvertiserAssistant(广播)开启搜索服务
advertiser = MCAdvertiserAssistant.init(serviceType: serviceStr, discoveryInfo: nil, session: session!)
//发出广播
advertiser?.start()
advertiser?.delegate = self
MCBrowserViewControllerDelegate代理方法
/// 发出广播请求
func advertiserAssistantWillPresentInvitation(_ advertiserAssistant: MCAdvertiserAssistant) {
print("advertiserAssistantWillPresentInvitation")
}
/// 结束广播请求
func advertiserAssistantDidDismissInvitation(_ advertiserAssistant: MCAdvertiserAssistant) {
print("advertiserAssistantDidDismissInvitation")
}
设置蓝牙连接页面,显示效果如图所示:
func setupBrowserVC() {
guard let session = session else {
return
}
browser = MCBrowserViewController.init(serviceType: serviceStr, session: session)
browser?.delegate = self
}
实现MCBrowserViewControllerDelegate代理方法
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
print("蓝牙连接完成")
browser?.dismiss(animated: true, completion: { [weak self] in
self?.browserBlock?()
})
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
print("取消蓝牙连接")
browser?.dismiss(animated: true, completion: nil)
}
小结
使用蓝牙技术进行传输数据,尽管不需要连接网络服务,但是真实因为这样存在着许多安全隐患,为此我们引入Google Protobuf框架进行数据传输。下一篇文章会对该技术的运用进行详解。
最后
代码具体实现地址
代码中具体实现了两个棋类游戏,包括在线对战,人机对战(算法不错哦),蓝牙对战。
代码编写不易,喜欢的请点赞,谢谢!