Reputation: 147
I have made an iPhone game with Bluetooth mode, you can play 1 vs 1 via Bluetooth. My implementation for a picker is the following:
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[picker show];
I don't know which code gives the error so I'll also paste my code for all the other methods that have something to do with the picker:
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *dataDictionary = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects:dataString, peer, session, nil] forKeys:[NSArray arrayWithObjects:@"data", @"peer", @"session", nil]];
[dataString release];
[self performSelectorOnMainThread:@selector(receivedData:) withObject:dataDictionary waitUntilDone:YES];
}
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker
sessionForConnectionType:(GKPeerPickerConnectionType)type {
// Create a new session if one does not already exist
if (!self.currentSession) {
self.currentSession = [[[GKSession alloc] initWithSessionID:@"Session" displayName:nil sessionMode:GKSessionModePeer] autorelease];
self.currentSession.delegate = self;
}
return self.currentSession;
}
-(void)peerPickerController:(GKPeerPickerController *)pk didConnectPeer:(NSString *)peerID toSession:(GKSession *)session {
self.currentSession = session;
session.delegate = self;
[session setDataReceiveHandler:self withContext:nil];
picker.delegate = nil;
[picker dismiss];
[picker autorelease];
}
-(void)peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
picker.delegate = nil;
[picker autorelease];
[self.navigationController popViewControllerAnimated:YES];
}
// FAIL
- (void)session:(GKSession *)session didFailWithError:(NSError *)error {
NSLog(@"error : %@", [error description]);
}
// SESSION VIND ANDERE SESSION -> CONNECT
-(void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
switch (state) {
case GKPeerStateConnected:
NSLog(@"connect met peer %@", [currentSession displayNameForPeer:peerID]);
[self generateRandomNumberAndSendIt];
break;
case GKPeerStateDisconnected:
NSLog(@"disconnected");
[self.currentSession disconnectFromAllPeers];
currentSession = nil;
[self.navigationController popViewControllerAnimated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Whoopsie" message:@"The connection failed" delegate:nil cancelButtonTitle:@"Okido" otherButtonTitles:nil];
[alert show];
[alert release];
[super viewDidDisappear:YES];
break;
}
}
Sometimes when I accept an incoming request, the picker removes itself on one device, and on another device I get the error: wait_fences: failed to receive reply: 10004003
. I think it has something to do with the alertview itself. I have got other alertviews set up in this view.
I hope you guys can help me.
Thanks in advance.
Upvotes: 3
Views: 321
Reputation: 32497
Try to wrap your UIAlertView
calls in blocks to invoke on the main thread, e.g.
dispatch_async(dispatch_get_main_queue(), ^{
// Show UIAlertView
}
While I have not used GK like this before, I guess that it (like many network based libraries) can trigger callbacks from other threads than your main GUI thread. Presenting or even manipulating user interface from other than the main GUI thread is a big no-no in most GUI libraries, and Cocoa is no exception (although it is usually surprisingly forgiving).
Upvotes: 1
Reputation: 16714
You need to set some breakpoints and debug where the code crashes, it is impossible for anyone to be sure of where your code is crashing, the best we can do is guess by pointing out oddities in your code. The error might not even be in the code you provided.
As someone else mentioned you should definitely not have the statement [super viewDidDisappear:YES];
in a non-viewDidAppear:
method.
I am also guessing that if you are debugging then there is a much more helpful error message in the console than wait_fences: failed to receive reply: 10004003
. Make sure you have enabled breakpoints on all exceptions. If you don't know how to do that, here are some instructions. Step through the exception, figure out what line it is on, and figure out what error is being thrown.
Your [picker autorelease];
calls are a little bizarre as well. If you want to autorelease the picker, just do picker = [[[GKPeerPickerController alloc] init] autorelease];
. It is weird to put the autorelease statement down in your GameKit delegate methods.
Upvotes: 1