I'm currently working on a game where I need to connect 2 peers. To do this I have gone through this tutorial. I built the described demo app and it worked like a charm, i.e. I was able to chat between my iPhone 5 and my Macbook Pro. However, now that I'm working on the game application I'm not able to establish a connection anymore. Basically what I do is that I display in a table view all the advertisers. Once one clicks on a given cell, the following code will be executed:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var peer = appDelegate.mcManager.foundPeers.keys.array[indexPath.row] as MCPeerID
self.appDelegate.mcManager.joinGame(peer)
}
In the mcManager the joinGame looks like:
func joinGame(peer : MCPeerID){
// Setup Advertising:
self.setAdvertiserDiscoveryInfo(self.foundPeers[peer] as! [String:String])
self.advertiser.startAdvertisingPeer()
self.appDelegate.isAdvertising = true
// Create Connection
self.browser.invitePeer(peer, toSession: self.session, withContext: nil, timeout: self.connectingTimeout)
}
Obviously there are no error messages from XCode. Every code is executed as it should. Even the invitePeer(...) is being executed. But it always ends in a timeout.
I compared the demo app (from the tutorial above) and the game app in the debugger and I noticed one thing, that is that the demo app's browser variable contains an _netServices variable with one key/value pair, whereas the game app doesn't (_netServices is empty).
Currently I have no clue what is wrong, since I heavily base myself on the given tutorial, i.e. there is a lot of copy/paste involved. And since the first demo app is working I don't know what happened.
Just FYI, here is the init() of the mcManager:
override init() {
super.init()
peer = MCPeerID(displayName: UIDevice.currentDevice().name)
session = MCSession(peer: peer)
session.delegate = self
browser = MCNearbyServiceBrowser(peer: peer, serviceType: serviceType)
browser.delegate = self
advertiser = MCNearbyServiceAdvertiser(peer: peer, discoveryInfo: nil, serviceType: serviceType)
advertiser.delegate = self
}
I finally found the solution! After I went totally mad, because I did not find any problem, I created a new Project and added step by step the code from the game application. After every step I tested the code.
Finally I found out, that the problem was the advertiser and its discovery info. When the user creates a game I reinitialize the advertiser with the user generated discovery information. The problem was that after the reinitialization I forgot to put the delegate, i.e.:
func setAdvertiserDiscoveryInfo(discoveryInfo: Dictionary<String, String>) {
advertiser = MCNearbyServiceAdvertiser(peer: peer, discoveryInfo: discoveryInfo, serviceType: serviceType)
advertiser.delegate = self // I forgot this line!
}
Furthermore, I initialized the discovery info variable as [String : String]
. The compiler did not raise any error so I thought it was correct. However the connection was only possible when I changed the discovery information to Dictionary<String, String>
.