问题
I have used [[GKTurnBasedEventHandler sharedTurnBasedEventHandler] setDelegate:self];
but I am not receiving delegate calls. This was working at one point, and I can't figure out for the life of me what has changed.
The app is properly badged (on the device home screen, it shows a badge with the number of games where it is my turn). Furthermore, using GKTurnBasedMatch loadMatchesWithCompletionHandler:
is able to detect when it is the player's turn (or not). In fact, in every other conceivable way, GameCenter seems to be working perfectly. I can even send (and accept) challenges, but again, the delegate methods are not called: none of the GKTurnBasedEventHandlerDelegate
methods are invoked (including handleTurnEventForMatch:
, handleInviteFromGameCenter:
, etc.)
It gets even weirder: if I quit the app entirely and it becomes my turn, I don't see any GameCenter notification. However, I DO se a badge on my app! if I simply open the GameCenter app itself, I also see that it is my turn. So, even the OS-level notifications are not being received, despite the fact that the data is properly updated on the server...
I've heard talk that maybe the GameCenter Sandbox is just unreliable with notification delivery... but I really can't take that risk. I need to test my code!
Things I've tried:
- Ensured that I am testing on real devices (no simulators). I've tested on 4 real devices, including an iPhones+iPads and iOS6+iOS7.
- I am doing a
NSAssert([GKTurnBasedEventHandler sharedTurnBasedEventHandler].delegate == self
every 60 seconds to ensure that the delegate property is not lost (per this question: handleTurnEventForMatch:didBecomeActive: callbacks only arriving some of the time) - Double checked that I have push notifications enabled for the app within Settings
- Checked that the iTunesConnect
version
is exactly equal to myCFBundleShortVersionString
ininfo.plist
(0.0.1
) and that iTunesConnect shows GameCenter as "enabled" for the game. I even also set theCFBundleVersion
to also be the same value, just to ensure that there was no chance of confusion. - Playing with the version #s in step 3. I've set them each to be
1.0.0
and1.0
and0.1
, etc. I also print them out with aNSLog
to make sure that they are properly copied into the app. - Checked that I'm using explicit provisioning profiles, downloaded from
developer.apple.com
, and that XCode shows checkmarks next to all of the GameCenter steps inCapabilities
. (e.g., I am not using "teams"; I have logged into the provisioning profile center and created a Development profile, downloaded it, and explicitly set it to myProvisioning Profile
in Build Settings for Debug mode). - Explicitly requesting push notification permissions. I was able to successfully retrieve (and use) a token, so there seems to be no problem with the APN service.
- I've also tried simply... waiting. I have the debugger attached to the device whose turn it is becoming. 10+ minutes after the turn has been passed off, no delegate is hit (I'm using a breakpoint to determine this).
Update
This question was interesting: Sandbox Game Center Turn Event Notifications Not Consistent
It led me to attempt to use [[GKLocalPlayer localPlayer] registerListener:self]
instead of the GKTurnBasedEventHandler
delegate method. Unfortunately, the problem was still not fixed. I even tried compiling with the minimum version of the SDK set to 7.0
(since this is a 7+ feature addition).
回答1:
My current belief is that the GameCenter Sandbox is at fault, since it seems like many people have had problems with it. To be able to test my code, I actually wrote some code to poll GameCenter and look for changes.
WARNING This is DUMB. I have it enabled in DEBUG
mode only, simply so that I can test my handleTurnEventForMatch
code. That said... it works around the problem.
This code can go into the same class that provides your delegate methods. You'll need to do some obvious logic modifications. You should call onMultiplayerGameStarted
and onEndedMultiplayerTurn
in the appropriate places from your gameplay logic.
#if GAMEKIT_TURN_POLLING
NSMutableDictionary *_wasLocalPlayersTurnMap = nil;
- (void)pollGameCenter {
if(!_wasLocalPlayersTurnMap) {
_wasLocalPlayersTurnMap = [NSMutableDictionary new];
}
[AMGameData loadGames:^(NSArray *games) {
NSInteger validGameCount = 0;
for(AMGameData *gameData in games) {
if(gameData.isSinglePlayer) {
continue;
}
if(gameData.gameState != AMGameStatePlaying) {
continue;
}
validGameCount++;
if([_wasLocalPlayersTurnMap[gameData.name] boolValue]) {
continue;
}
if(!gameData.isLocalPlayersTurn) {
_wasLocalPlayersTurnMap[gameData.name] = @(NO);
continue;
}
// Hey, it's now our turn!
_wasLocalPlayersTurnMap[gameData.name] = @(YES);
[self handleTurnEventForMatch:gameData.match didBecomeActive:NO];
}
if(validGameCount) {
// Need to do this again later...
[self delayedPollGameCenter];
}
}];
}
- (void)delayedPollGameCenter {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(pollGameCenter) object:nil];
[self performSelector:@selector(pollGameCenter) withObject:nil afterDelay:10];
}
- (void)onMultiplayerGameStarted {
[self delayedPollGameCenter];
}
- (void)onEndedMultiplayerTurn:(AMGameData*)gameData {
_wasLocalPlayersTurnMap[gameData.name] = @(NO);
[self delayedPollGameCenter];
}
#else
- (void)onMultiplayerGameStarted{}
- (void)onEndedMultiplayerTurn:(AMGameData*)gameData {}
#endif
回答2:
I'm having the same problems as well. I'm getting notifications around ~ 25% of time and I can't test properly the app.
According to the documentation, GKTurnBasedEventHandler is deprecated on iOS7. If this is true - could this be the reason for these issues?
https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKTurnBasedEventHandler_Ref/Reference/Reference.html
来源:https://stackoverflow.com/questions/20906784/gkturnbasedeventhandler-delegate-is-not-receiving-any-messages