ios 蓝牙对战实现

蓝牙对战

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
    }
ios 蓝牙对战实现_第1张图片
image

实现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框架进行数据传输。下一篇文章会对该技术的运用进行详解。

最后

代码具体实现地址
代码中具体实现了两个棋类游戏,包括在线对战,人机对战(算法不错哦),蓝牙对战。
代码编写不易,喜欢的请点赞,谢谢!

你可能感兴趣的:(ios 蓝牙对战实现)