2012-10-13 75 views
26

在iOS 6中使用authenticateHandler時,如果用戶取消登錄視圖,遊戲中心將不會顯示登錄視圖。我意識到遊戲中心會在3次取消嘗試後自動鎖定應用程序,但我只談論2次嘗試。如果他們取消登錄,他們必須離開應用程序,然後在遊戲中心將顯示登錄,即使通過authenticateHandler重新設置。關於如何在iOS 6中處理這種情況的任何想法?iOS 6 Game Center authenticateHandler取消後無法登錄

它使用的是舊authenticateWithCompletionHandler方法時正常工作:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 
    GKLocalPlayer.localPlayer.authenticateHandler = authenticateLocalPlayerCompleteExtended; 
#else 
    [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:authenticateLocalPlayerComplete]; 
#endif 

的原因,這是我的應用程序重要的是,它需要多玩家遊戲中心。該應用程序會在啓動時嘗試向遊戲中心進行身份驗證,但如果用戶取消,我們不會再次啓動,因此他們不會感到嘮叨。如果他們在選擇多人遊戲時沒有登錄,我們所做的就是顯示一個Game Center登錄按鈕。登錄按鈕通過調用authenticateWithCompletionHandler強制遊戲中心登錄(現在通過再次設置GKLocalPlayer.localPlayer.authenticateHandler)。

+1

聽起來你已經這麼做了,但調用[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil]將導致authenticateHandler再次被認證視圖控制器調用。儘管在iOS6中,此方法已棄用。 – Greg

+0

我正在使用折舊呼叫來使此工作,但我正在尋找「正確」的方式來做到這一點,而不使用過時的呼叫。我嘗試設置新的GKLocalPlayer.localPlayer.authenticateHandler爲零,然後返回到我的處理程序,看看是否會工作,並得到一個異常,試圖將其設置爲零。我沒有嘗試設置它到一個不同的處理程序,看看是否會觸發登錄(這看起來很瘋狂) –

+0

我試着將處理程序切換到另一個處理程序,並且不會觸發新的登錄對話框打開。我在開發人員論壇上張貼,看看有沒有人有任何建議,並會在我聽到任何消息時回覆。 https://devforums.apple.com/message/744983 – Greg

回答

2

更好地使用運行時檢查(instancesRespondToSelector :)而不是預處理程序#if語句,以便您可以在建議的方法可用時使用它們,並在其他地方使用折舊的方法。我居然發現我需要設置邀請處理程序之前區分三種情況下,作爲認證處理程序也可能會調用一個零視圖控制器:

-(void)authenticateLocalPlayer 
{ 
    if ([[GKLocalPlayer class] instancesRespondToSelector:@selector(setAuthenticateHandler:)]) { 
     [[GKLocalPlayer localPlayer] setAuthenticateHandler:^(UIViewController *gameCenterLoginViewController, NSError *error) { 
      if (gameCenterLoginViewController) { 
       [self.presentedViewController presentViewController:gameCenterLoginViewController 
                  animated:YES 
                  completion:^{ 
                   [self setInviteHandlerIfAuthenticated]; 
                  }]; 
      } else { 
       [self setInviteHandlerIfAuthenticated]; 
      } 
     }]; 
    } else { // alternative for iOS < 6 
     [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) { 
      [self setInviteHandlerIfAuthenticated]; 
     }]; 
    } 
} 

然而,更多的情況下,必須邀請處理程序中加以區分,因爲matchForInvite: :在iOS6中也是全新的,並且避免了通過遊戲中心視圖控制器的又一回合:

-(void)setInviteHandlerIfAuthenticated 
{ 
    if ([GKLocalPlayer localPlayer].isAuthenticated) { 
     [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) { 
      if (acceptedInvite) { 
       if ([GKMatchmaker instancesRespondToSelector:@selector(matchForInvite:completionHandler:)]) { 
        [self showInfoAnimating:YES completion:NULL]; 
        [[GKMatchmaker sharedMatchmaker] matchForInvite:acceptedInvite 
                completionHandler:^(GKMatch *match, NSError *error) { 
                 // ... handle invited match 
                }]; 
       } else { 
        // alternative for iOS < 6 
        GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease]; 
        mmvc.matchmakerDelegate = self; 
        // ... present mmvc appropriately 
        // ... handle invited match found in delegate method matchmakerViewController:didFindMatch: 
       } 
      } else if (playersToInvite) { 
       // ... handle match initiated through game center 
      } 
     }; 
    } 
} 

讓我知道這是否有幫助。

+1

預處理器宏僅用於調試並顯示問題。我遇到的問題是,如果用戶取消Game Center顯示的初始登錄,則無法使用iOS 6公共API觸發登錄。 pre-ios6 API支持這種行爲是重置處理程序。 –

0

我不認爲這是可能的iOS 6.0中。在早期的SDK構建中有API調用會在發佈之前刪除。

在的WWDC 2012視頻: - 會話516遊戲中心早8點半]集成您的遊戲他們實際上在那裏你調用一個方法authenticate顯示代碼:

GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; 
localPlayer.authenticationHandler = //handle the callback... 
[localPlayer authenticate]; 

現在這種方法是私有的API,但你可以通過調用看到它在行動:

[[GKLocalPlayer localPlayer] performSelector:@selector(_authenticate)]; 

這不正是你想要的東西,但不能使用,因爲它現在是私人。


您還可以通過張貼通知UIApplicationWillEnterForegroundNotification觸發認證過程:

[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]]; 

我認爲這將是不明智爲此在現場代碼。