Multipeer connectivity framework issue in swift 4 - swift4

i hope all is well
please i have create app that share photos between nearby devices using the multiplier connectivity framework.
i have an issue every time i press connect when i share the session and the browser it's tell me connected but i have receive this message and the sending photos it's fail below the error message:
[ERROR] ProcessEvent:1199 Send BINDING_REQUEST failed(C01A0000).
[GCKSession] Not in connected state, so giving up for participant [7A5C490D] on channel [0].
[GCKSession] Not in connected state, so giving up for participant [7A5C490D] on channel [1].
[ERROR] ICEStopConnectivityCheck:2688 ICEStopConnectivityCheck() found no ICE check with call id (2052868365)
[GCKSession] Not in connected state, so giving up for participant [7A5C490D] on channel [2].
[ERROR] ICEStopConnectivityCheck:2688 ICEStopConnectivityCheck() found no ICE check with call id (2052868365)
the code which i was use it below:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
peerID = MCPeerID(displayName: UIDevice.current.name)
// init the session
mcSession = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .none)
mcSession.delegate = self
}
#IBAction func showAlertForShare(_ sender: UIBarButtonItem) {
let alertController = UIAlertController(title: "Share Photos", message: "Do You Want Share The Photo With Other User?", preferredStyle: .actionSheet)
let alertHostSession = UIAlertAction(title: "Host A Session", style: .default) { (alertAction) in
self.mcAdvertiserAssistant = MCAdvertiserAssistant(serviceType: "hws-desertqwert", discoveryInfo: nil, session: self.mcSession)
self.mcAdvertiserAssistant.start()
}
let alertJoinSession = UIAlertAction(title: "Join A Session", style: .default) { (alertAction) in
self.mcbrowserViewController = MCBrowserViewController(serviceType: "hws-desertqwert", session: self.mcSession)
self.mcbrowserViewController.delegate = self
self.present(self.mcbrowserViewController, animated: true, completion: nil)
}
let alertCancel = UIAlertAction(title: "Cancel", style: .cancel) { (alertAction) in
alertController.dismiss(animated: true, completion: nil)
}
alertController.addAction(alertHostSession)
alertController.addAction(alertJoinSession)
alertController.addAction(alertCancel)
self.present(alertController, animated: true, completion: nil)
}
// multipeer delegate methods
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .connected:
print("Connected: \(peerID)")
case .connecting:
print("Connecting: \(peerID)")
case .notConnected:
print("Not Connecting: \(peerID)")
}
}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
print(data)
if let getImage = UIImage(data: data) {
print(self.mcSession.connectedPeers.count)
self.arrayOfImages.append(getImage)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
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) {
self.dismiss(animated: true, completion: nil)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
self.dismiss(animated: true, completion: nil)
}
so please can anyone fix this issue?
thanks a lot

Related

App is crashing on first run, but works on sequential ones. And UserState text is not working

Why is my app crashing whenever I press the host button for the first time. It happens when the invite function is called. It works when I close the app and try again. I am not sure why, because shouldn't it work every time, if it works sequentially? Also, I can't get the user.userState text to show up.
import SwiftUI
import MultipeerConnectivity
class userState {
#State var userStatus: String = ""
}
var user = userState()
class synkeMultipeerSession: NSObject, ObservableObject {
var peerID: MCPeerID
var session: MCSession
var nearbyServiceAdvertiser: MCNearbyServiceAdvertiser?
override init() {
peerID = MCPeerID(displayName: UIDevice.current.name)
session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
super.init()
session.delegate = self
}
func advertise() {
nearbyServiceAdvertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "gt-synke")
nearbyServiceAdvertiser?.delegate = self
nearbyServiceAdvertiser?.startAdvertisingPeer()
}
func invite() {
let browser = MCBrowserViewController(serviceType: "gt-synke", session: session)
browser.delegate = self
UIApplication.shared.rootViewController?.present(browser, animated: true)
}
}
var mpSession: synkeMultipeerSession = synkeMultipeerSession()
struct SelectionScreenView: View {
var isHosting = false
var isJoining = false
var body: some View {
ZStack{
skyBlue
.ignoresSafeArea()
Text("Choose to either host, or join others ")
.foregroundColor(.white)
.offset(x:10, y:-145)
.frame(width: 385, height: 200, alignment: .topLeading)
.font(.system(size:40).bold())
Button("Host") {
mpSession.advertise()
user.userStatus = "You are now hosting."
}
.offset(x:-75)
.foregroundColor(.red)
.font(.system(size: 35).bold().italic())
.padding(.all)
.buttonStyle(.bordered)
Button("Join") {
user.userStatus = "Joining"
mpSession.invite()
}
.offset(x:74)
.foregroundColor(.blue)
.font(.system(size: 35).bold().italic())
.padding(.all)
.buttonStyle(.bordered)
Text(user.userStatus)
.foregroundColor(.white)
.offset(x:10, y:200)
.frame(width: 385, height: 200, alignment: .topLeading)
.font(.system(size:40).bold())
}
}
struct SelectionScreenView_Previews: PreviewProvider {
static var previews: some View {
SelectionScreenView()
}
}
}
extension synkeMultipeerSession: MCSessionDelegate {
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
switch state {
case .connecting:
print("\(peerID) state: Connecting...")
case .connected:
print("\(peerID) state: Connected.")
user.userStatus = "You are now successfully connected as a peer."
case .notConnected:
print("\(peerID) state: Not Connected.")
#unknown default:
print("\(peerID) state: Unknown.")
}
}
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?) {
}
}
extension synkeMultipeerSession: MCNearbyServiceAdvertiserDelegate {
func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: #escaping (Bool, MCSession?) -> Void) {
invitationHandler(true, session)
}
}
extension synkeMultipeerSession: MCBrowserViewControllerDelegate {
func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true)
}
func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
browserViewController.dismiss(animated: true)
}
}
extension UIApplication {
var currentKeyWindow: UIWindow? {
UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.map { $0 as? UIWindowScene }
.compactMap { $0 }
.first?.windows
.filter { $0.isKeyWindow }
.first
}
var rootViewController: UIViewController? {
currentKeyWindow?.rootViewController
}
}

How do I pair devices using core bluetooth?

I am trying to develop bluetooth based application that will provide users the functionality to share data via bluetooth pairing. I am facing issue while pairing the device.
This is my scenario
The user will login the application and will be prompted to enable bluetooth service. This is the code for the same :-
//MARK: - DECLARATIONS
var cbCentralManager : CBCentralManager?
var peripheral : CBPeripheral?
var peripherals: [CBPeripheral] = []
//MARK: - VIEW_METHODS
override func viewDidLoad() {
super.viewDidLoad()
self.setUpView()
}
func setUpView() {
cbCentralManager = CBCentralManager(delegate: self, queue: nil)
}
//MARK: - EXTENSION
extension ViewController : CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
print("Bluetooth is enabled..")
central.scanForPeripherals(withServices: nil, options: nil)
} else {
print("Bluetooth is not enabled..")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
guard peripheral.name != nil else {return}
print("Sensor Found!")
//stopScan
cbCentralManager?.stopScan()
//connect
cbCentralManager?.connect(peripheral, options: nil)
self.peripheral = peripheral
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
//discover all service
peripheral.discoverServices(nil)
peripheral.delegate = self
}
In the next step, on the click of button, near by BLE devices will be scanned.
func startScan() {
let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey:
NSNumber(value: false)]
peripherals = []
print("Now Scanning...")
self.timer.invalidate()
centralManager?.scanForPeripherals(withServices: nil, options: options)
Timer.scheduledTimer(timeInterval: 17, target: self, selector: #selector(self.cancelScan), userInfo: nil, repeats: false)
}
After the user selects a device to be paired from the list of scanned BLE devices, below code will be executed for establishing connection between devices.
func connectToDevice(device:CBPeripheral) {
centralManager = CBCentralManager(delegate: self, queue: .main)
self.blePeripheral = device
self.blePeripheral?.delegate = self
centralManager?.connect(self.blePeripheral!, options: nil)
}
The delegate methods are extended
extension HomeVC : CBPeripheralDelegate {
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
if peripheral.state == .poweredOn {
return
}
print("Peripheral manager is running")
}
//Check when someone subscribe to our characteristic, start sending the data
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
print("Device subscribe to characteristic")
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
print("*******************************************************")
if ((error) != nil) {
print("Error discovering services: \(error!.localizedDescription)")
return
}
guard let services = peripheral.services else {
return
}
//We need to discover the all characteristic
for service in services {
peripheral.discoverCharacteristics(nil, for: service)
// bleService = service
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if ((error) != nil) {
print("Error discovering services: \(error!.localizedDescription)")
return
}
guard let services = peripheral.services else {
return
}
//We need to discover the all characteristic
for service in services {
peripheral.discoverCharacteristics(nil, for: service)
// bleService = service
}
print("Discovered Services: \(services)")
}
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
if let error = error {
print("\(error)")
let errorStr = "\(error)"
let alert = UIAlertController(title: "Alert", message: errorStr, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
}
}
I am stuck as I am not getting the alert for pairing devices. Can anyone guide me in this ?
Thanks in advance.

I am trying to write this code in Swift 3, it is for multiplayer

This code is in the old version of Swift 2. I am trying to write it in Swift 3 but I am having a problem. this is a multiplayer game. I am having a problem with "let userInfo ". I get this error "Extra argument 'userInfo' "in call
import UIKit
import MultipeerConnectivity
class MPCHander: NSObject, MCSessionDelegate {
var peerID:MCPeerID!
var session:MCSession!
var browser:MCBrowserViewController!
var advertiser:MCAdvertiserAssistant? = nil
func setupPeerWithDisplayName (displayName:String){
peerID = MCPeerID(displayName: displayName)
}
func setupSession(){
session = MCSession(peer: peerID)
session.delegate = self
}
func setupBrowser(){
browser = MCBrowserViewController(serviceType: "my-game", session: session)
}
func advertiseSelf(advertise:Bool){
if advertise{
advertiser = MCAdvertiserAssistant(serviceType: "my-game", discoveryInfo: nil, session: session)
advertiser!.start()
}else{
advertiser!.stop()
advertiser = nil
}
}
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
let userInfo = ["peerID":peerID,"state":state.rawValue]
dispatch_async(dispatch_get_main_queue(), { () -> Void in
NSNotificationCenter.defaultCenter().postNotificationName("MPC_DidChangeStateNotification", object: nil, userInfo: userInfo)
})
}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
let userInfo = [data:"data" , peerID:"peerID"] as [AnyHashable : String]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "MPC_DidChangeStateNotification"), object: nil, userInfo: userInfo)
}
func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {
}
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
}
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
}
}
You should've posted the entire console output.
The problem is with NSNotificationCenter. Swap your func session(_:, peer:, didChange:) method with:
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
let userInfo = ["peerID":peerID,"state":state.rawValue] as! [AnyHashable : String]
DispatchQueue.main.async {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "MPC_DidChangeStateNotification"), object: nil, userInfo: userInfo)
}
}

Type 'MPCManager' does not conform to protocol 'MCNearbyServiceAdvertiserDelegate'

in my swift 2 app i get this two errors:
Protocol requires function
'advertiser(_:didReceiveInvitationFromPeer:withContext:invitationHandler:)'
with type '(MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer:
MCPeerID, withContext: NSData?, invitationHandler: (Bool, MCSession)
-> Void) -> Void'
AND
Candidate has non-matching type '(MCNearbyServiceAdvertiser,
didReceiveInvitationFromPeer: MCPeerID, withContext: NSData?,
invitationHandler: (Bool, MCSession!) -> Void) -> ()'
How can i solve this problems?
import UIKit
import MultipeerConnectivity
protocol MPCManagerDelegate {
func foundPeer()
func lostPeer()
func invitationWasReceived(fromPeer: String)
func connectedWithPeer(peerID: MCPeerID)
}
class MPCManager: NSObject, MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate {
var session: MCSession!
var peer: MCPeerID!
var browser: MCNearbyServiceBrowser!
var advertiser: MCNearbyServiceAdvertiser!
var foundPeers = [MCPeerID]()
var invitationHandler: (Bool, MCSession!) -> Void
var delegate: MPCManagerDelegate?
override init() {
super.init()
invitationHandler(false, nil)
peer = MCPeerID(displayName: UIDevice.currentDevice().name)
session = MCSession(peer: peer)
session.delegate = self
browser = MCNearbyServiceBrowser(peer: peer, serviceType: "appcoda-mpc")
browser.delegate = self
advertiser = MCNearbyServiceAdvertiser(peer: peer, discoveryInfo: nil, serviceType: "appcoda-mpc")
advertiser.delegate = self
}
func browser(browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
foundPeers.append(peerID)
delegate?.foundPeer()
}
func browser(browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
for (index, aPeer) in EnumerateSequence(foundPeers){
if aPeer == peerID {
foundPeers.removeAtIndex(index)
break
}
}
delegate?.lostPeer()
}
func browser(browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: NSError) {
print(error.localizedDescription)
}
func advertiser(advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: NSData?, invitationHandler: (Bool, MCSession!) -> Void) {
self.invitationHandler = invitationHandler
delegate?.invitationWasReceived(peerID.displayName)
}
func advertiser(advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: NSError) {
print(error.localizedDescription)
}
func session(session: MCSession, peer peerID: MCPeerID, didChangeState state: MCSessionState) {
switch state{
case MCSessionState.Connected:
print("Connected to session: \(session)")
delegate?.connectedWithPeer(peerID)
case MCSessionState.Connecting:
print("Connecting to session: \(session)")
default:
print("Did not connect to session: \(session)")
}
}
func sendData(dictionaryWithData dictionary: Dictionary<String, String>, toPeer targetPeer: MCPeerID) -> Bool {
let dataToSend = NSKeyedArchiver.archivedDataWithRootObject(dictionary)
let peersArray = NSArray(object: targetPeer) as! [MCPeerID]
do {
try session.sendData(dataToSend, toPeers: peersArray, withMode: MCSessionSendDataMode.Reliable)
} catch let error as NSError {
print(error.localizedDescription)
return false
}
return true
}
func session(session: MCSession, didReceiveData data: NSData, fromPeer peerID: MCPeerID) {
let dictionary: [String: AnyObject] = ["data": data, "fromPeer": peerID]
NSNotificationCenter.defaultCenter().postNotificationName("receivedMPCDataNotification", object: dictionary)
}
func session(session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, withProgress progress: NSProgress) { }
func session(session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, atURL localURL: NSURL, withError error: NSError?) { }
func session(session: MCSession, didReceiveStream stream: NSInputStream, withName streamName: String, fromPeer peerID: MCPeerID) { }
}
To omit the error, you can initialize invitationHandler property like the following.
var invitationHandler: (Bool, MCSession) -> Void = { success, session in }
The callback parameter invitationHandler: (Bool, MCSession!) -> Void has one of it's parameter unwrapped. Remove exclamation mark ! after MCSession datatype. This makes method not matching the original delegate method, and Swift can't find required delegate method of this protocol.
Updated
Change declaration of callback
var invitationHandler: (Bool, MCSession) -> Void = { status, session in }
In the init method, instead of nil you must pass a initialised MCSession instance
invitationHandler(false, session)

Swift: Cannot assign value '(Bool, MCSession) -> Void' to type '(Bool, MCSession!) -> Void!'

Im trying this tutorial and because of the new swift version some errors came up, one of them was MPCManager does not conform with the protocol MCNearbyServiceAdvertiserDelegate.
I tried to fix it so i changed the header of func advertiser to this one:
func advertiser(advertiser: MCNearbyServiceAdvertiser,
didReceiveInvitationFromPeer peerID: MCPeerID, withContext context:
NSData?, invitationHandler: (Bool, MCSession)->Void) {
but then it throws me an error
Cannot assign value '(Bool, MCSession) -> Void' to type '(Bool,
MCSession!) -> Void!'
which i don't know how to fix, help appreciated!
The actual file:
import UIKit
import MultipeerConnectivity
protocol MPCManagerDelegate {
func foundPeer()
func lostPeer()
func invitationWasReceived(fromPeer: String)
func connectedWithPeer(peerID: MCPeerID)
}
class MPCManager: NSObject, MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate {
var session: MCSession!
var peer: MCPeerID!
var browser: MCNearbyServiceBrowser!
var advertiser: MCNearbyServiceAdvertiser!
var foundPeers = [MCPeerID]()
var invitationHandler: (Bool, MCSession!)->Void!
var delegate: MPCManagerDelegate?
override init() {
super.init()
invitationHandler(false, nil)
peer = MCPeerID(displayName: UIDevice.currentDevice().name)
session = MCSession(peer: peer)
session.delegate = self
browser = MCNearbyServiceBrowser(peer: peer, serviceType: "appcoda-mpc")
browser.delegate = self
advertiser = MCNearbyServiceAdvertiser(peer: peer, discoveryInfo: nil, serviceType: "appcoda-mpc")
advertiser.delegate = self
}
func browser(browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
foundPeers.append(peerID)
delegate?.foundPeer()
}
func browser(browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
for (index, aPeer) in EnumerateSequence(foundPeers){
if aPeer == peerID {
foundPeers.removeAtIndex(index)
break
}
}
delegate?.lostPeer()
}
func browser(browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: NSError) {
print(error.localizedDescription)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ THE Error occurs here: ~~~~~~~~~~~~~~~~~~~~~~
func advertiser(advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: NSData?, invitationHandler: (Bool, MCSession)->Void) {
self.invitationHandler = invitationHandler
delegate?.invitationWasReceived(peerID.displayName)
}
func advertiser(advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: NSError) {
print(error.localizedDescription)
}
func session(session: MCSession, peer peerID: MCPeerID, didChangeState state: MCSessionState) {
switch state{
case MCSessionState.Connected:
print("Connected to session: \(session)")
delegate?.connectedWithPeer(peerID)
case MCSessionState.Connecting:
print("Connecting to session: \(session)")
default:
print("Did not connect to session: \(session)")
}
}
func sendData(dictionaryWithData dictionary: Dictionary<String, String>, toPeer targetPeer: MCPeerID) -> Bool {
let dataToSend = NSKeyedArchiver.archivedDataWithRootObject(dictionary)
let peersArray = NSArray(object: targetPeer) as! [MCPeerID]
do {
_ = try session.sendData(dataToSend, toPeers: peersArray, withMode: MCSessionSendDataMode.Reliable)
} catch let error as NSError {
print(error.localizedDescription)
return false
}
return true
}
func session(session: MCSession, didReceiveData data: NSData, fromPeer peerID: MCPeerID) {
let dictionary: [String: AnyObject] = ["data": data, "fromPeer": peerID]
NSNotificationCenter.defaultCenter().postNotificationName("receivedMPCDataNotification", object: dictionary)
}
func session(session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, withProgress progress: NSProgress) { }
func session(session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, atURL localURL: NSURL, withError error: NSError?) { }
func session(session: MCSession, didReceiveStream stream: NSInputStream, withName streamName: String, fromPeer peerID: MCPeerID) { }
}
You defined the invitationHandler variable with (Bool, MCSession!)->Void! type, then assign it with a value (Bool, MCSession)->Void) type. This is the reason which causes your error message.
To fix it, define your advertiser method with the param match type with the invitationHandler variable.
The property invitationHandler of the class MPCManager is defined as:
var invitationHandler: (Bool, MCSession!) -> Void!
... while the argument invitationHandler of advertiser method is defined as
invitationHandler: (Bool, MCSession) -> Void
There are 2 mismatches here:
Property's return value is Void! while argument returns Void
Second argument of the property is MCSession! while method takes MCSession
Firstly, I do not see the point to have Void! as return value. Void means nothing is being returned at all, so no need to implicitly unwrap it.
Secondly, the argument's types must match. So, either both should be MCSession or both MCSession!.
E.g. the following does not produce the error you mention:
var invitationHandler: (Bool, MCSession!) -> Void
// ...
func advertiser(advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: NSData?,
invitationHandler: (Bool, MCSession!) -> Void) {