Multipeer Connectivity Not Connecting Programmatically
Asked Answered
A

6

14

I am creating an iOS/macOS app that uses remote control functionality via the Multipeer Connectivity Framework. Since the device to be remotely monitored and controlled will run over an extended period of time, it's not viable to use the automatic view controller methods since the monitoring device may be locked or go to sleep and then disconnect the connection. So I'm using the programatic approach so that when the monitoring devices lose connection, they will automatically pair up when they are unlocked/woken up and the app is started again. My connection works fine using the ViewController method but not the programatic delegate approach. The advertising, browsing and inviting works fine, but when the invitation is accepted on the remote side I get several errors and then a failed connection. What's weird is that several of the errors are GCKSession errors.

So why is it trying to use the GameCenter framework? And why is it failing after accepting the invitation? Could it just be a bug in the Xcode 8 / Swift 3 /iOS 10 / macOS Sierra Beta SDKs?

[ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (2008493930)
[GCKSession] Wrong connection data. Participant ID from remote connection data = 6FBBAE66, local participant ID = 3A4C626C
[MCSession] GCKSessionEstablishConnection failed (FFFFFFFF801A0020)
Peer Changing
Failed
[GCKSession] Not in connected state, so giving up for participant [77B72F6A] on channel [0]

Here is the code from my connection class

func startAdvertisingWithoutUI () {

    if advertiserService == nil {
        advertiserService = MCNearbyServiceAdvertiser (peer: LMConnectivity.peerID, discoveryInfo: nil, serviceType: "mlm-timers")
        advertiserService?.delegate = self
        session.delegate = self
    }

    advertiserService?.startAdvertisingPeer()

}

func browserForNearbyDevices () {

    if browserService == nil {
        browserService = MCNearbyServiceBrowser (peer: LMConnectivity.peerID, serviceType: "mlm-timers")
        browserService?.delegate = self
        session.delegate = self
    }

    browserService?.startBrowsingForPeers()
}

func sendInvitation(to peer: MCPeerID) {

    browserService?.invitePeer(peer, to: session, withContext: nil, timeout: 60)

}

func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: (Bool, MCSession?) -> Void) {

    let trustedNames = GetPreferences.trustedRemoteDevices

    for name in trustedNames {

        if name == peerID.displayName {
            invitationHandler(true,session)
            return
        }
    }

    invitationHandler (false, session)
}
Apraxia answered 3/8, 2016 at 13:41 Comment(2)
I'm seeing the same thing unfortunately. In my case it is a macOS and tvOS app.Billiot
Multipeer (the daemon, and services) run inside GameCenter services on iOS.Net
A
6

I found out what was wrong. The MCPeerID object that I was passing into the MCSession instances, I was vending it as a Computed Class Property instead of storing it as a Stored Property. So I changed it to a Stored Instance Property and everything started working! Thanks Tanya for pointing me in the direction of the MCPeerID object.

Old Code

// Class Properties

static var localPeer : MCPeerID { return MCPeerID(displayName: GetPreferences.deviceName!) }

New Code

// Instance Properties
let localPeer = MCPeerID (displayName: GetPreferences.deviceName!)
Apraxia answered 28/8, 2016 at 17:4 Comment(1)
Its contrdicting with Apple's recommended code but wierdly working well than recommended approach. :! Ref: developer.apple.com/documentation/multipeerconnectivity/…Licketysplit
F
16

None has worked for me.
I've resolved only disabling encryption...

let session = MCSession(peer:myPeerId, securityIdentity: nil, encryptionPreference: MCEncryptionPreference.none)
Fibrous answered 9/9, 2016 at 13:25 Comment(4)
also worked for me, after 6 hours of work. You don't know how much i THANK YOU !Futrell
Thanks for the suggestion. Would have been tearing hair out if I didn't come across this!Vadose
FYI, in MCEncryptionPreference.None "none" is now lowercase.Gregggreggory
setting encryption to none makes no effect on a device with iOS 12Baudelaire
A
6

I found out what was wrong. The MCPeerID object that I was passing into the MCSession instances, I was vending it as a Computed Class Property instead of storing it as a Stored Property. So I changed it to a Stored Instance Property and everything started working! Thanks Tanya for pointing me in the direction of the MCPeerID object.

Old Code

// Class Properties

static var localPeer : MCPeerID { return MCPeerID(displayName: GetPreferences.deviceName!) }

New Code

// Instance Properties
let localPeer = MCPeerID (displayName: GetPreferences.deviceName!)
Apraxia answered 28/8, 2016 at 17:4 Comment(1)
Its contrdicting with Apple's recommended code but wierdly working well than recommended approach. :! Ref: developer.apple.com/documentation/multipeerconnectivity/…Licketysplit
L
5

When the peerID used to make the session and the peerID used to make the advertiser or browser do not match, I get this part of the error.

[GCKSession] Wrong connection data. Participant ID from remote connection data = 6FBBAE66, local participant ID = 3A4C626C

Once peerIDs match, that part of the error goes away.

There might still be some other connection problems though.

Lashelllasher answered 10/8, 2016 at 13:31 Comment(3)
I observe the same behavior. MCPeerID instance should be the same.Odrick
Can you elobarote on how to sove this, i.e. how to make them match? What exactly causes this error? @TanyaSeiber
@MJQZ1347I'm not sure I remember anymore, but I had a subclass of these three: MCNearbyServiceAdvertiserDelegate, MCNearbyServiceBrowserDelegate, MCSessionDelegate I made a peerID for myself: let myPeerId = MCPeerID(displayName: UIDevice.current.name) Later on in the code, I made an advertiser and browser, using that same peerID: let serviceAdvertiser = MCNearbyServiceAdvertiser(peer: myPeerId, discoveryInfo: nil, serviceType: ShareServiceType) and let serviceBrowser = MCNearbyServiceBrowser(peer: myPeerId, serviceType: ShareServiceType) I think that's what I meant by matching.Lashelllasher
A
5

The problem for me was that I never set the delegate of MCSession. I got all the same error messages that the OP mentioned, which made me think the connection was broken, but really I just forgot to set the delegate. After setting the delegate, all the error messages still printed, but otherwise my delegate methods got called normally upon receiving a message!

I've inflicted this problem on myself twice. Hopefully this helps someone reading along!

Ailssa answered 31/1, 2017 at 4:38 Comment(0)
P
1

I got to work with TViOS 10.0 beta with this ...

 peerID = MCPeerID(displayName: UIDevice.current.name)

Although I am still seeing this error...

 2016-09-08 10:13:43.016600 PeerCodeATV[208:51135] [ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (847172408)
 2016-09-08 10:13:47.577645 PeerCodeATV[208:51155] [GCKSession] SSLHandshake returned with error [-9819].
Periderm answered 8/9, 2016 at 8:16 Comment(0)
C
1

Same problem for me with an app I've had on the itunes store for years. The latest 10.1 beta update now seems to fix the bluetooth issue with my app without any change to my code.

Caucasoid answered 8/10, 2016 at 2:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.