Using this code to setup Multipeer connectivity under TViOS 10.0.
import UIKit
import MultipeerConnectivity
class MPCHandler: NSObject, MCSessionDelegate {
var peerID: MCPeerID!
var session: MCSession!
var browser: MCBrowserViewController!
var advertiser: MCAdvertiserAssistant? = nil
func setupPeerWithDisplayName (displayName: String) {
peerID = MCPeerID(displayName: UIDevice.current.name)
}
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
}
}
public class MyClass {
static let myNotification = Notification.Name("MPC_DidChangeStateNotification")
}
public class MyClass2 {
static let myNotification = Notification.Name("MPC_DidRecieveDataNotification")
}
func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
let userInfo = ["peerID":peerID,"state":state.rawValue] as [String : Any]
DispatchQueue.main.async {
NotificationCenter.default.post(name: MyClass.myNotification, object: nil, userInfo: userInfo)
}
}
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
let userInfo = ["data":data, "peerID":peerID] as [String : Any]
DispatchQueue.main.async {
NotificationCenter.default.post(name: MyClass2.myNotification, object: nil, userInfo: userInfo)
}
}
func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL, withError error: Error?) {
// code
}
func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
// code
}
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
// code
}
}
Reports connected, but I get this errors? Both devices TViOS and iPhone on the same network.
2016-09-08 11:13:13.602572 PeerCodeATV[172:7628] [ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (1969443468)
2016-09-08 11:13:17.168110 PeerCodeATV[172:7686] [ViceroyTrace] [ICE][ERROR] Send BINDING_REQUEST failed(C01A0041).
2016-09-08 11:13:18.044156 PeerCodeATV[172:7686] [ViceroyTrace] [ICE][ERROR] Send BINDING_REQUEST failed(C01A0041).
2016-09-08 11:13:18.766040 PeerCodeATV[172:7686] [ViceroyTrace] [ICE][ERROR] Send BINDING_REQUEST failed(C01A0041).
2016-09-08 11:13:20.015846 PeerCodeATV[172:7686] [ViceroyTrace] [ICE][ERROR]
2016-09-08 11:13:24.453030 PeerCodeATV[172:7588] [GCKSession] Not in connected state, so giving up for participant [7563528C] on channel [0].
2016-09-08 11:13:24.476176 PeerCodeATV[172:7588] [GCKSession] Not in connected state, so giving up for participant [7563528C] on channel [1].
2016-09-08 11:13:24.498394 PeerCodeATV[172:7588] [ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (1969443468)
2016-09-08 11:13:24.498840 PeerCodeATV[172:7588] [GCKSession] Not in connected state, so giving up for participant [7563528C] on channel [2].
2016-09-08 11:13:24.522667 PeerCodeATV[172:7588] [ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (1969443468)
2016-09-08 11:13:24.522954 PeerCodeATV[172:7588] [GCKSession] Not in connected state, so giving up for participant [7563528C] on channel [3].
2016-09-08 11:13:24.545934 PeerCodeATV[172:7588] [ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (1969443468)
I already tested the code iOS to iOS, it works perfectly across the same iOS, but iPad running iOS 9.2 -> TViOS 10.0 I see these errors?
It works if I reboot the AppleTV with these errors, subsequent connections however fail!!
Got an answer from Apple. Seems you can ignore these messages; they are a side effect related to logging changes it seems?
Watch this for details of the logging changes...
(If you’re curious about this change, check out this video from WWDC 2016: https://developer.apple.com/videos/play/wwdc2016/721/ ).
I confirm that yonivav was on the right track when encountering the following error during connection of peers:
[MCSession] Peer [DisplayName] has incompatible encryption preference [Required].
However, setting the session encryption preference to .none
did not work for me. At https://developer.apple.com/reference/multipeerconnectivity/mcsession/1407000-init it is stated that
On apps linked on or after iOS 9, the encryption is set to required. On apps linked prior to iOS 9, the encryption is set to optional.
Since I was using one client at iOS 10.1 and another client with a lower iOS version, I initialized the session using
var session = MCSession(peer: ownPeerID,
securityIdentity: nil,
encryptionPreference: .optional)
and the connection works reliably again.
However, I must confirm that the connection is not established using Bluetooth only. The invitation is sent and accepted, the connection state changes to connecting and then to not connected 10 seconds later. Right after changing the state to connecting a
[ViceroyTrace] [ICE][ERROR] ICEStopConnectivityCheck() found no ICE check with call id (108154439)
error is thrown.
If I turn on Wifi and Bluetooth on the the iOS 10.1 device, the Bluetooth only device is discovered, followed by a dozen
[ViceroyTrace] [ICE][ERROR] Send BINDING_REQUEST failed(C01A0041).
errors and a connection state change to not connected.
I updated the iPhone from iOS 10.1 to 10.1.1, and the errors still persist, no changes at all.
After the update from 10.2 (where it was still broken) to 10.2.1, it seems to work again (tested with one device using 10.2.1, the other device was an old iOS 8 device. A colleague tested with 10.2.1 and 10.2 and oddly it worked too)! The connection is established when using Bluetooth only (disabling WiFi). However, at times I still get all the ICE-errors and connection errors in the log, BUT not always. Right now I tried to reproduce them and it runs without warnings. Strange, but the good news is: it seems like Apple fixed the issue!
in my case, instead of:
_mpcSession = [[MCSession alloc] initWithPeer:self.mpcPeerID];
i used:
_mpcSession = [[MCSession alloc] initWithPeer:self.mpcPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
Multipeer in iOS 10 is a bag of hurt. I did testing yesterday and it seems like it will only work if wifi is turned on (bluetooth-only is broken).
As an alternative to Multipeer, you can use the dns_sd (Bonjour) approach and build your own. I made a framework (Pod) that does exactly this (it mimicks Multipeer). It is unicast not multicast, but supports roles and bluetooth-only. More info here: https://github.com/xaphod/Bluepeer . I'm afraid I have not tested with tvOS, so it might need some work. Pull-requests welcome ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With