gpt4 book ai didi

swift - 通过多个 View Controller 的多点连接

转载 作者:行者123 更新时间:2023-11-30 11:07:10 26 4
gpt4 key购买 nike

我想要做的是拥有多个 View Controller ,其中一个将您与多点连接中的另一台设备连接起来。然后我希望用户能够切换 View Controller 并保持该连接。我对此进行了一些研究,发现我需要创建一个自定义类并在那里完成所有的多人工作。我找到了一个示例项目来展示这一点,但只有一个问题,如果代码不在 View Controller 中,我如何制作 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)

但我不知道如何从 View Controller 外部执行此操作

最佳答案

您可以将 service 设置为 View Controller 类的属性。

这个服务类并不是设计为您共享的代码片段中的单例,这里有意义的是为您将呈现的每个 View Controller 实例化一个服务类。

要记住的一件重要的事情是:如果您要关闭 View Controller 并重新呈现它们,那么您将需要维护一个强引用(let)其他类(也许是您正在呈现的类?),以便 View Controller 不会被初始化并终止您的 session 。

请告诉我这是否有帮助,否则如果您有更多信息,我可以编辑我的答案。

关于swift - 通过多个 View Controller 的多点连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52581443/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com