I am trying to build a basic application to send messages between nearby iOS devices with Multipeer Connectivity Framework. I have tried many tutorials but it seems in Xcode 11 browsing nearby devices and accepting requests does not work as it did before.
Here is my view controller & delegate methods:
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)
}
}
I've added 2 buttons in the UI, one for hosting and the other one for joining. Here are the methods:
@IBAction func hostBtnTapped(_ sender: Any) {
hostSession()
}
@IBAction func joinBtnTapped(_ sender: Any) {
joinSession()
}
They call:
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)
}
When I compile & run it, everything looks fine. I click "Host" in my first device and enter "Join" mode in my second device (the MCBrowserViewController
shows up), but the joining device never detects the hosting device. There is no output in console and there are no errors. The joining device's "Searching..." indicator turns forever without any nearby devices showing up. What might be causing this? How can I solve it? I'm using Xcode 11.0 and iOS 12 & 13.
It seems MCAdvertiserAssistant
and MCBrowserViewController
are not updated for latest versions of iOS & Swift, hence they're not working properly.
I solved it by using MCNearbyServiceAdvertiser
instead of MCAdvertiserAssistant
and MCNearbyServiceBrowser
instead of MCBrowserViewController
. Note that by using these classes, you'll need to perform basic operations yourself such as listing founded devices, showing and handling invitation alert.. etc.
You can use these classes as below.
Definition:
var advertiser: MCNearbyServiceAdvertiser!
var browser: MCNearbyServiceBrowser!
Initialization:
advertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "my-test")
browser = MCNearbyServiceBrowser(peer: peerID, serviceType: "my-test")
Assigning delegates & starting:
advertiser.delegate = self
advertiser.startAdvertisingPeer()
browser.delegate = self
browser.startBrowsingForPeers()