-
问题
承接上文 [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 在苹果设施之间的实现形式应该是基于此进行的