Xcode 11 更新后多点连接不工作
Multipeer Connectivity not working after Xcode 11 update
我正在尝试构建一个基本应用程序,以便使用 Multipeer Connectivity Framework 在附近的 iOS 设备之间发送消息。我尝试了很多教程,但似乎 Xcode11 浏览附近的设备和接受请求无法像以前那样工作。
这是我的视图控制器和委托方法:
import UIKit
import MultipeerConnectivity
class ViewController: UIViewController,MCSessionDelegate,MCBrowserViewControllerDelegate {
var peerID: MCPeerID?
var session: MCSession?
override func viewDidLoad() {
super.viewDidLoad()
peerID = MCPeerID(displayName: UIDevice.current.name)
session = MCSession(peer: peerID!, securityIdentity: nil, encryptionPreference: .none)
session!.delegate = self
}
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .connected: print("Connected to \(peerID.displayName)")
case .connecting: print("Connecting: \(peerID.displayName)")
case .notConnected: print("Not Connected: \(peerID.displayName)")
default: print("")
}
}
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?) {
}
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true, completion: nil)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true, completion: nil)
}
}
我在 UI 中添加了 2 个按钮,一个用于托管,另一个用于加入。以下是方法:
@IBAction func hostBtnTapped(_ sender: Any) {
hostSession()
}
@IBAction func joinBtnTapped(_ sender: Any) {
joinSession()
}
他们叫:
func hostSession() {
let advertiser = MCAdvertiserAssistant(serviceType: "mg-testing", discoveryInfo: nil, session: session!)
advertiser.start()
}
func joinSession() {
let browser = MCBrowserViewController(serviceType: "mg-testing", session: session!)
browser.delegate = self
self.present(browser, animated: true, completion: nil)
}
当我编译 & 运行 时,一切看起来都很好。我在我的第一台设备上单击 "Host" 并在我的第二台设备上进入 "Join" 模式(显示 MCBrowserViewController
),但加入设备从未检测到托管设备。控制台中没有输出,也没有错误。加入设备的 "Searching..." 指示灯会一直亮着,附近的任何设备都不会出现。这可能是什么原因造成的?我该如何解决?我正在使用 Xcode 11.0 和 iOS 12 & 13。
MCAdvertiserAssistant
和 MCBrowserViewController
似乎没有针对 iOS 和 Swift 的最新版本进行更新,因此它们无法正常工作。
我用 MCNearbyServiceAdvertiser
代替 MCAdvertiserAssistant
和 MCNearbyServiceBrowser
代替 MCBrowserViewController
解决了这个问题。请注意,使用这些 类,您需要自己执行基本操作,例如列出已创建的设备、显示和处理邀请警报等。
您可以使用这些 类,如下所示。
定义:
var advertiser: MCNearbyServiceAdvertiser!
var browser: MCNearbyServiceBrowser!
初始化:
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
browser = MCNearbyServiceBrowser(peer: peerID, serviceType: "my-test")
分配代表并开始:
advertiser.delegate = self
advertiser.startAdvertisingPeer()
browser.delegate = self
browser.startBrowsingForPeers()
根据我前辈的回答,最大的问题似乎是MCAdvertiserAssistant
。 MCBrowserViewController
对我来说很好用。
如果您的代码应该 运行 基于 MCAdvertiserAssistant
和 MCBrowserViewController
,请尝试将 MCAdvertiserAssistant
替换为 MCNearbyServiceAdvertiser
。
这就是您所需要的一切,例如,如果您在 Paul Hudson 的 Swift 的 100 天内完成项目 25。 (当我必须找到问题的解决方案时,我才这样做)
var advertiser: MCNearbyServiceAdvertiser!
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
advertiser.delegate = self
advertiser.startAdvertisingPeer()
将 MCNearbyServiceAdvertiserDelegate
添加到您的协议列表并实施委托方法:
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
invitationHandler(true, mcSession)
}
这只会接受每个连接,但它也足够了,应该可以正常工作。
进一步调查:似乎是新 Xcode 模板和 info.plist 中的新 UIApplicationSceneManifest
以及 multi-[=39 的新 SceneDelegate 有问题=] 支持.
当我将其更改为旧的信息 plist 和 AppDelegate 系统时 MCAdvertiserAssistant
即使使用新的 Xcode 和 Swift 也能正常工作。
ps。基于最新的 Xcode 11.2 Beta 2
此问题是由 UISceneDelegate 引起的。在您选择退出 UISceneDelegate 并重建您的项目后,应该会很好。
有关如何选择退出 UISceneDelegate 的更多信息,请查看 post:
对于 Xcode 12 和 iOS 14:
同样来自hackingwithSwift project 25,我花了2小时比较代码:(最终,我认为是Xcode版本或iOS版本的问题。
要修复它,请先将 MCAdvertiserAssistant
替换为 MCNearbyServiceAdvertiser
。
更改startHosting方法如下:
func startHosting(action: UIAlertAction) {
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "hws-project25")
advertiser.delegate = self
advertiser.startAdvertisingPeer()
}
并实现这个新方法:我添加了一个 alertViewController 来显示授予提示,因为当我们进行上述更改时它不会出现。
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
let ac = UIAlertController(title: "Project25", message: "'\(peerID.displayName)' wants to connect", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Accept", style: .default, handler: { [weak self] _ in
invitationHandler(true, self?.mcSession)
}))
ac.addAction(UIAlertAction(title: "Decline", style: .cancel, handler: { _ in
invitationHandler(false, nil)
}))
present(ac, animated: true)
}
还有一件事:
对于iOS14,如果要使用多点连接,还需要在info.plist中添加这2个属性。
- 隐私 - 本地网络使用说明:“您的消息”
- Bonjour 服务:_yourServiceTypeName._tcp
我正在尝试构建一个基本应用程序,以便使用 Multipeer Connectivity Framework 在附近的 iOS 设备之间发送消息。我尝试了很多教程,但似乎 Xcode11 浏览附近的设备和接受请求无法像以前那样工作。
这是我的视图控制器和委托方法:
import UIKit
import MultipeerConnectivity
class ViewController: UIViewController,MCSessionDelegate,MCBrowserViewControllerDelegate {
var peerID: MCPeerID?
var session: MCSession?
override func viewDidLoad() {
super.viewDidLoad()
peerID = MCPeerID(displayName: UIDevice.current.name)
session = MCSession(peer: peerID!, securityIdentity: nil, encryptionPreference: .none)
session!.delegate = self
}
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .connected: print("Connected to \(peerID.displayName)")
case .connecting: print("Connecting: \(peerID.displayName)")
case .notConnected: print("Not Connected: \(peerID.displayName)")
default: print("")
}
}
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?) {
}
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true, completion: nil)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true, completion: nil)
}
}
我在 UI 中添加了 2 个按钮,一个用于托管,另一个用于加入。以下是方法:
@IBAction func hostBtnTapped(_ sender: Any) {
hostSession()
}
@IBAction func joinBtnTapped(_ sender: Any) {
joinSession()
}
他们叫:
func hostSession() {
let advertiser = MCAdvertiserAssistant(serviceType: "mg-testing", discoveryInfo: nil, session: session!)
advertiser.start()
}
func joinSession() {
let browser = MCBrowserViewController(serviceType: "mg-testing", session: session!)
browser.delegate = self
self.present(browser, animated: true, completion: nil)
}
当我编译 & 运行 时,一切看起来都很好。我在我的第一台设备上单击 "Host" 并在我的第二台设备上进入 "Join" 模式(显示 MCBrowserViewController
),但加入设备从未检测到托管设备。控制台中没有输出,也没有错误。加入设备的 "Searching..." 指示灯会一直亮着,附近的任何设备都不会出现。这可能是什么原因造成的?我该如何解决?我正在使用 Xcode 11.0 和 iOS 12 & 13。
MCAdvertiserAssistant
和 MCBrowserViewController
似乎没有针对 iOS 和 Swift 的最新版本进行更新,因此它们无法正常工作。
我用 MCNearbyServiceAdvertiser
代替 MCAdvertiserAssistant
和 MCNearbyServiceBrowser
代替 MCBrowserViewController
解决了这个问题。请注意,使用这些 类,您需要自己执行基本操作,例如列出已创建的设备、显示和处理邀请警报等。
您可以使用这些 类,如下所示。
定义:
var advertiser: MCNearbyServiceAdvertiser!
var browser: MCNearbyServiceBrowser!
初始化:
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
browser = MCNearbyServiceBrowser(peer: peerID, serviceType: "my-test")
分配代表并开始:
advertiser.delegate = self
advertiser.startAdvertisingPeer()
browser.delegate = self
browser.startBrowsingForPeers()
根据我前辈的回答,最大的问题似乎是MCAdvertiserAssistant
。 MCBrowserViewController
对我来说很好用。
如果您的代码应该 运行 基于 MCAdvertiserAssistant
和 MCBrowserViewController
,请尝试将 MCAdvertiserAssistant
替换为 MCNearbyServiceAdvertiser
。
这就是您所需要的一切,例如,如果您在 Paul Hudson 的 Swift 的 100 天内完成项目 25。 (当我必须找到问题的解决方案时,我才这样做)
var advertiser: MCNearbyServiceAdvertiser!
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
advertiser.delegate = self
advertiser.startAdvertisingPeer()
将 MCNearbyServiceAdvertiserDelegate
添加到您的协议列表并实施委托方法:
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
invitationHandler(true, mcSession)
}
这只会接受每个连接,但它也足够了,应该可以正常工作。
进一步调查:似乎是新 Xcode 模板和 info.plist 中的新 UIApplicationSceneManifest
以及 multi-[=39 的新 SceneDelegate 有问题=] 支持.
当我将其更改为旧的信息 plist 和 AppDelegate 系统时 MCAdvertiserAssistant
即使使用新的 Xcode 和 Swift 也能正常工作。
ps。基于最新的 Xcode 11.2 Beta 2
此问题是由 UISceneDelegate 引起的。在您选择退出 UISceneDelegate 并重建您的项目后,应该会很好。
有关如何选择退出 UISceneDelegate 的更多信息,请查看 post:
对于 Xcode 12 和 iOS 14:
同样来自hackingwithSwift project 25,我花了2小时比较代码:(最终,我认为是Xcode版本或iOS版本的问题。
要修复它,请先将 MCAdvertiserAssistant
替换为 MCNearbyServiceAdvertiser
。
更改startHosting方法如下:
func startHosting(action: UIAlertAction) {
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "hws-project25")
advertiser.delegate = self
advertiser.startAdvertisingPeer()
}
并实现这个新方法:我添加了一个 alertViewController 来显示授予提示,因为当我们进行上述更改时它不会出现。
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
let ac = UIAlertController(title: "Project25", message: "'\(peerID.displayName)' wants to connect", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Accept", style: .default, handler: { [weak self] _ in
invitationHandler(true, self?.mcSession)
}))
ac.addAction(UIAlertAction(title: "Decline", style: .cancel, handler: { _ in
invitationHandler(false, nil)
}))
present(ac, animated: true)
}
还有一件事:
对于iOS14,如果要使用多点连接,还需要在info.plist中添加这2个属性。
- 隐私 - 本地网络使用说明:“您的消息”
- Bonjour 服务:_yourServiceTypeName._tcp