Reputation: 23
Currently trying to get MultiPeerConnectivity to work. The current problem is with the session host. The view controller that joins the session works correctly, as in it shows the name of the host and lets me try to connect, however instead of appearing a dialogue to accept or deny on the host device, nothing happens, and after a few seconds of waiting, the device trying to join the session times out and shows that the host declined. I don't get what I might be doing wrong, the relevant part of the code below.
View Controller joining the session:
import MultipeerConnectivity
class DisplayActualViewController: UIViewController, MCSessionDelegate, MCBrowserViewControllerDelegate {
var peerID: MCPeerID!
var mcSession: MCSession!
var mcAdvertiserAssistant: MCAdvertiserAssistant!
override func viewDidLoad() {
super.viewDidLoad()
peerID = MCPeerID(displayName: UIDevice.current.name)
mcSession = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
mcSession.delegate = self
}
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) {
dismiss(animated: true)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
dismiss(animated: true)
}
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("Not Connected: \(peerID.displayName)")
}
}
func joinSession() {
let mcBrowser = MCBrowserViewController(serviceType: "hws-testing", session: mcSession)
mcBrowser.delegate = self
present(mcBrowser, animated: true)
}
View Controller hosting the session:
import MultipeerConnectivity
class CounterViewController: UIViewController, MCSessionDelegate, MCBrowserViewControllerDelegate {
var peerID = MCPeerID(displayName: UIDevice.current.name)
var mcSession: MCSession!
var mcAdvertiserAssistant: MCAdvertiserAssistant!
override func viewDidLoad() {
super.viewDidLoad()
mcSession = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
mcSession.delegate = self
startHosting()
}
func startHosting() {
mcAdvertiserAssistant = MCAdvertiserAssistant(serviceType: "hws-testing", discoveryInfo: nil, session: mcSession)
mcAdvertiserAssistant.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 session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
}
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
dismiss(animated: true)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
dismiss(animated: true)
}
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("Not Connected: \(peerID.displayName)")
}
}
Upvotes: 2
Views: 435
Reputation: 561
The MCAdvertiserAssistant alert for accepting invitations is not presented. So the invitation times out and you get a declined response.
You can solve this by replacing MCAdvertiserAssistant with MCNearbyServiceAdvertiser.
Here's a way of doing that in 3 steps:
var mcNearbyServiceAdvertiser: MCNearbyServiceAdvertiser!
func startHosting() {
mcNearbyServiceAdvertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "hws-testing")
mcNearbyServiceAdvertiser.delegate = self
mcNearbyServiceAdvertiser.startAdvertisingPeer()
}
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "Invitation Received"
let ac = UIAlertController(title: appName, message: "'\(peerID.displayName)' wants to connect.", preferredStyle: .alert)
let declineAction = UIAlertAction(title: "Decline", style: .cancel) { [weak self] _ in invitationHandler(false, self?.mcSession) }
let acceptAction = UIAlertAction(title: "Accept", style: .default) { [weak self] _ in invitationHandler(true, self?.mcSession) }
ac.addAction(declineAction)
ac.addAction(acceptAction)
present(ac, animated: true)
}
Upvotes: 2
Reputation: 36
This worked for me:
Downgrade from using SceneDelegate and don't use UIScene.
Completely remove the “Application Scene Manifest” entry from Info.plist
Remove the SceneDelegate class, and remove the scene-related methods in AppDelegate
Add 'var window: UIWindow?' to your AppDelegate class.
Your app under iOS 13 it will have the same life cycle as iOS 12. And Multipeer connectivity should work as it is originally designed.
Upvotes: 1