MultipeerConnectivity in SwiftUI?

I tried now two different approaches (MCAdvertiserAssistant / MCBrowserViewController and MCNearbyServiceAdvertiser / MCNearbyServiceBrowser) to implement this in my first Swift app but always got the result that it stays at "Connecting" for a few seconds and than just declines the request. In a video from Hacking with Swift there was a popup if the connection should be accepted - this never comes up on my devices. So maybe this is the error already?

As for the browser part, I use this ViewController wrapper to make it available:
Code Block
import MultipeerConnectivity
import SwiftUI
struct MultipeerConnectivityBrowserView: UIViewControllerRepresentable {
  func makeUIViewController(context: UIViewControllerRepresentableContext<MultipeerConnectivityBrowserView>) -> MCBrowserViewController {
    let service = MultipeerConnectivityService.instance()
    guard let session = service.session else {
      print("Failed to load MCSession for Browser")
      return MCBrowserViewController()
    }
     
    let viewController = MCBrowserViewController(serviceType: service.serviceType, session: session)
    viewController.delegate = service
     
    return viewController
  }
  func updateUIViewController(_ uiViewController: MCBrowserViewController, context: UIViewControllerRepresentableContext<MultipeerConnectivityBrowserView>) {
  }
}
struct MultipeerConnectivityBrowserView_Previews: PreviewProvider {
  static var previews: some View {
    MultipeerConnectivityBrowserView()
  }
}


I can see my 2nd device in the upcoming dialog but when I click on it, as described above, it just hangs at "Connecting" until it, as it seems to me, timed out.

This is currently the main implementation for the MC in my app:
Code Block
import MultipeerConnectivity
class MultipeerConnectivityService: NSObject, MCSessionDelegate, MCBrowserViewControllerDelegate, MCAdvertiserAssistantDelegate {
private static var internalInstance: MultipeerConnectivityService? = nil
let serviceType = "sn-dueladviser"
let peerID = MCPeerID(displayName: UIDevice.current.name)
var session: MCSession?
var advertiserAssistant: MCAdvertiserAssistant?
static func instance() -> MultipeerConnectivityService {
if let instance = internalInstance {
return instance
}
internalInstance = MultipeerConnectivityService()
return internalInstance!
}
private override init() {
super.init()
session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
session?.delegate = self
}
func startHosting() {
guard let session = session else { return }
advertiserAssistant = MCAdvertiserAssistant(serviceType: serviceType, discoveryInfo: nil, session: session)
advertiserAssistant?.delegate = self
advertiserAssistant?.start()
}
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: { })
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true, completion: { })
}
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .connected:
print("Connected: \(peerID.displayName)")
case .connecting:
print("Connecting: \(peerID.displayName)")
case .notConnected:
print("Not Connected: \(peerID.displayName)")
@unknown default:
print("Unknown state received: \(peerID.displayName)")
}
}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
//todo: Receive data
}
}


I tried to add NSLocalNetworkUsageDescription and NSBonjourServices without any change (even if both are not mentioned in any guides except the official documentation). Sadly it didn't change anything + it seems like my XCode does not know these keys or at least do not replace the key name with another text like it did with other keys like camera permission.
For everyone with the same problem: Seems like it is an issue with iOS 13 and newer as described here: swiftydorado.github(dot)io/posts/2020-01-18-multipeer-connectivity/


It seems that after introducing the new SceneDelegate on iOS 13, MCAdvertiserAssistant is not working properly.


Is there any update on this? I have no problem creating a Multipeer Connection between two devices when using a traditional UIKit project but I have the same error as described above when I try and recreate it in Swift UI.
Has anybody found a solution to this? I'm having the exact same issue and I've found no solutions.

I have worked around this issue by replacing the SwiftUI application lifecycle with a plain old UIApplication/UIApplicationDelegate and just wrapping my SwiftUI content in a UIHostingController.

MultipeerConnectivity in SwiftUI?
 
 
Q