views:

461

answers:

3

Gamekit applications running under 4.0 do not properly handle removing GKSession objects. Running under 3.1.3 or 3.2, if a peer disconnects and the session is cleaned up (as in Apple demos):

[gkSession disconnectFromAllPeers];
[gkSession setAvailable:NO];
[gkSession setDelegate:nil];
[gkSession setDataReceiveHandler:nil withContext:nil];

then the other peers receive state changes and a table view of peers can be updated.

In my application, one peer starts up as a server and the other starts up as a client. The client requests to connect to the server and the client's name appears in the server's list of players. If the server chooses to accept the request, the session connection is established and they can play the game. If however the client quits before the server accepts the request, the client cleans up the session (as above) and the client disappears from the server's peer list in response (when it receives a state change). This works amazingly on 3.1–3.2

When you run the same application running under 4.0 the server and client throw an error and it takes a very long time for peers to receive the state change, and when they do, the application crashes without any errors (even with NSZombieEnabled=YES in build arguments). The server never receives a "state change" message from the client. Instead, the following errors are thrown:

Thu Jul  8 23:27:26 unknown com.apple.mDNSResponder[18] <Notice>: BTLocalDeviceRemoveData: 60 byte key, 18 byte value
Thu Jul  8 23:27:26 unknown MobileBluetooth[29] <Notice>: BTLocalDeviceRemoveData - BT_ERROR_INVALID_HANDLE
Thu Jul  8 23:27:26 unknown com.apple.mDNSResponder[18] <Notice>: Call to BTLocalDeviceRemoveData failed with error 7
Thu Jul  8 23:13:39 unknown mDNSResponder[18] <Error>: external_stop_advertising_service:   18 00Z1Tud0A\\.\\.Tonberry\M-b\M^@\M^Ys\\032iPhone._1htnu3uko0uvsp._udp.local. TXT txtvers=1\M-B\M-&state=A
Thu Jul  8 23:13:39 unknown MobileBluetooth[29] <Notice>: BTLocalDeviceRemoveData - BT_ERROR_INVALID_HANDLE

With what I think is the key error:

Tue Jul 13 21:04:50 Tonberry com.apple.mDNSResponder[21] <Notice>: Call to BTDiscoveryAgentStopScan failed with error 400

Looks to me like the session is not being made unavailable (error in stopping advertising the service). The actual crash:

Thread 3 Crashed:
0   GameKitServices                 0x06352f90 gckSessionChangeStateCList + 411
1   GameKitServices                 0x0635b49c gckSessionRecvProc + 1474
2   libSystem.B.dylib               0x981c181d _pthread_start + 345
3   libSystem.B.dylib               0x981c16a2 thread_start + 34

I've filed a bug with my full application in progress. The app itself is done and was almost ready to submitted and runs pretty well under 3.1.3/3.2 but with the current state of Gamekit in 4.0 I can no longer submit it. Supremely disappointed and so hoping this bug report helps in the future. If anyone understands this error or what I might be doing wrong I would be supremely grateful.

Please help if you can. I'm about to throw in the towel here on this application and it's so close.

+1  A: 

My suggestion would be to use ultimate pre-release builds of 4.1 and to report the "new" problem (either reopen the existing bug as not fixed or create a new one). That's IMHO your best bet to get the problem entirely fixed before the final release or a decent work around from Apple.

Pascal Thivent
Yep, going to have to bite the bullet, sadly. Enjoy your 500! :D
Typeoneerror
oops, thought accepting an answer awarded. Done and done.
Typeoneerror
@Typeoneerror: Big thanks :D
Pascal Thivent
A: 

For anyone looking for help on this, I've find a workaround for the issues on 4.0.x (4.1 remedies the crashes but not the disconnect times). Just auto-accept everything. When someone requests a GameKit connection with connectToPeer:, just accept it. Don't give the user the option to select it. Disconnecting a peer from an established connection notifies the server immediately. If you leave them in just the "available" state, when they leave the connection, it will crash the server. Connect early and accept often!

Typeoneerror
A: 

SDK 4.1 is out - but still I get the same error - i thought its fixed in 4.1 ?

And : how would I "accept all connections" with the PeekPickerView ? dont know how to do that.. could you please give me some hint?

hhamm
You'll get the errors if your device is running 4.0.x. Doesn't matter that you compiled against the 4.1 SDK. Upgrade your device. I'm talking about if you roll your own connections, not using the peer picker view. You don't have as much control over that.
Typeoneerror