То, что я хочу сделать, это иметь несколько контроллеров представления, где один соединяет вас с другим устройством в многопользовательском соединении.Затем я хочу, чтобы пользователь мог переключать контроллеры представления и сохранять это соединение.Я немного исследовал это, и я обнаружил, что мне нужно создать собственный класс и делать все многопользовательские вещи там.Я нашел пример проекта, который демонстрирует это, но есть только одна проблема, если код не находится в контроллере представления, как мне сделать MCBrowserViewController.
Вот код для пользовательского класса:
import Foundation
import MultipeerConnectivity
protocol ColorServiceDelegate {
func connectedDevicesChanged(manager : ColorService, connectedDevices: [String])
func colorChanged(manager : ColorService, colorString: String)
}
class ColorService : NSObject {
// Service type must be a unique string, at most 15 characters long
// and can contain only ASCII lowercase letters, numbers and hyphens.
private let ColorServiceType = "example-color"
private let myPeerId = MCPeerID(displayName: UIDevice.current.name)
private let serviceAdvertiser : MCNearbyServiceAdvertiser
private let serviceBrowser : MCBrowserViewController
var delegate : ColorServiceDelegate?
lazy var session : MCSession = {
let session = MCSession(peer: self.myPeerId, securityIdentity: nil, encryptionPreference: .required)
session.delegate = self
return session
}()
override init() {
self.serviceAdvertiser = MCNearbyServiceAdvertiser(peer: myPeerId, discoveryInfo: nil, serviceType: ColorServiceType)
self.serviceBrowser = MCBrowserViewController(peer: myPeerId, serviceType: ColorServiceType)
super.init()
self.serviceAdvertiser.delegate = self
self.serviceAdvertiser.startAdvertisingPeer()
}
deinit {
self.serviceAdvertiser.stopAdvertisingPeer()
self.serviceBrowser.stopBrowsingForPeers()
}
func send(colorName : String) {
NSLog("%@", "sendColor: \(colorName) to \(session.connectedPeers.count) peers")
if session.connectedPeers.count > 0 {
do {
try self.session.send(colorName.data(using: .utf8)!, toPeers: session.connectedPeers, with: .reliable)
}
catch let error {
NSLog("%@", "Error for sending: \(error)")
}
}
}
}
extension ColorService : MCNearbyServiceAdvertiserDelegate {
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) {
NSLog("%@", "didNotStartAdvertisingPeer: \(error)")
}
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
NSLog("%@", "didReceiveInvitationFromPeer \(peerID)")
invitationHandler(true, self.session)
}
}
extension ColorService : MCNearbyServiceBrowserDelegate {
func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) {
NSLog("%@", "didNotStartBrowsingForPeers: \(error)")
}
// This is what pairs:
func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
NSLog("%@", "foundPeer: \(peerID)")
NSLog("%@", "invitePeer: \(peerID)")
browser.invitePeer(peerID, to: self.session, withContext: nil, timeout: 10)
}
func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
NSLog("%@", "lostPeer: \(peerID)")
}
}
extension ColorService : MCSessionDelegate {
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state{
case MCSessionState.connected:
print("connected: \(peerID.displayName)")
case MCSessionState.connecting:
print("connecting: \(peerID.displayName)")
case MCSessionState.notConnected:
print("NotConnected: \(peerID.displayName)")
}
}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
let str = String(data: data, encoding: .utf8)!
self.delegate?.colorChanged(manager: self, colorString: str)
}
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
NSLog("%@", "didReceiveStream")
}
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
NSLog("%@", "didStartReceivingResourceWithName")
}
func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {
NSLog("%@", "didFinishReceivingResourceWithName")
}
}
То, к чему я привык, когда объявляю MCBrowserViewController, таково:
let mcBrowser = MCBrowserViewController(serviceType: "doesnt-matter", session: self.mcSession)
mcBrowser.delegate = self
self.present(mcBrowser, animated: true, completion: nil)
Но я понятия не имею, как бы я делал это извне контроллера вида