-
问题
承接上文[iOS实现WIFI传书],如果去掉局域网会如何?能否实现设备间文件传输
iOS设备间的数据传输常用方式:
1.蓝牙 2.airdrop 3.MultipeerConnectivity
该篇单讲MultipeerConnectivity
-
上菜
设备作为服务端
- 要有一个标志自己的PeerID
lazy var me: MCPeerID = { let peer = MCPeerID(displayName: UIDevice.current.name) return peer }()
- 一个session
lazy var session: MCSession = { let ss = MCSession(peer: me, securityIdentity: nil, encryptionPreference: .none) ss.delegate = self return ss }()
- 广播出去,其他设备才能搜索到
lazy var advertiser: MCNearbyServiceAdvertiser = { let advertiser = MCNearbyServiceAdvertiser(peer: me, discoveryInfo: ["demo": "data"], serviceType: "shanzhai") advertiser.delegate = self return advertiser }()
- 开始广播
advertiser.startAdvertisingPeer()
- 广播的代理方法执行
extension MultipeerConnectVC: MCNearbyServiceAdvertiserDelegate { func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) { // 确认连接,赋值session invitationHandler(true, session) } func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) { advertiser.stopAdvertisingPeer() print("Woops! Advertising failed with error \(String(describing: error))") } }
设备作为客户端
- 要有一个标志自己的PeerID
lazy var me: MCPeerID = { let peer = MCPeerID(displayName: UIDevice.current.name) return peer }()
- 一个session
lazy var session: MCSession = { let ss = MCSession(peer: me, securityIdentity: nil, encryptionPreference: .none) ss.delegate = self return ss }()
- 需要一个搜索PeerID
lazy var browser: MCNearbyServiceBrowser = { let bs = MCNearbyServiceBrowser(peer: me, serviceType: "shanzhai") bs.delegate = self return bs }()
- 开始搜索
browser.startBrowsingForPeers()
- 代理中检索到附近的PeerID, 检索到可以自己存下来,也可以直接链接,依业务需求来,此处直连
extension MultipeerConnectVC: MCNearbyServiceBrowserDelegate { func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) { print("search peerId = \(peerID)") //搜到了peerID可以放入数组中,选择想要连接的peerID连接,这里直接连接 browser.invitePeer(peerID, to: session, withContext: nil, timeout: 10) } func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) { print("lost peerID = \(peerID)") } func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) { print("error = \(error)") } }
连接过程看Session,session代理中看各个过程
extension MultipeerConnectVC: MCSessionDelegate { func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { } func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) { } func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) { } func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) { } func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) { } }
-
代理方法didChange didChange方法中 MCSessionState == .connected,表示连接上,连接上后可传递数据
-
代理方法didFinishReceivingResourceWithName,可以查看接收到的数据
-
也可使用MCBrowserViewController,搜索到的PeerID,无需自己写界面
-
结语
该方式并未打通iOS与Android,适用于苹果设备之间的无网络数据传输。FileChat在苹果设备之间的实现方式应该是基于此进行的
网友评论