2012-10-13 13 views
26

iOS 6'da authenticateHandler kullanıldığında, kullanıcı bunu iptal ederse oyun merkezi oturum açma görünümü görüntülenmez. Oyun merkezinin, 3 kez iptal denemesinden sonra bir uygulamayı otomatik olarak kilitleyeceğinin farkındayım, ancak sadece 2 denemeden bahsediyorum. Giriş işlemini iptal ederse, uygulamayı terk etmek zorunda kalırlar ve oyun merkezi kimlik doğrulamasından bile giriş bilgilerini sunmadan önce geri gelirler. IOS 6'da bu davayı nasıl ele alacağınıza dair herhangi bir fikir var mı?iOS 6 Game Center authenticateHandler, iptal edildikten sonra oturum açamaz

eski authenticateWithCompletionHandler yöntemini kullanarak zaman iyi çalışır: bu uygulamam için önemlidir

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

nedeni Oyun Merkezi'ni çok oyuncu için ihtiyaç olmasıdır. Uygulama, lansmandaki oyun merkezine kimlik doğrulamayı dener, ancak kullanıcı iptal ederse, tekrar başlatılmasın diye sormazlar, bu nedenle, nagged olmazlar. Yaptığımız şey, çoklu oyuncu seçtiğinde oturum açmamışlarsa Oyun Merkezi Giriş düğmesini gösterir. Giriş düğmesi, authenticateWithCompletionHandler (ve şimdi GKLocalPlayer.localPlayer.authenticateHandler öğesini yeniden ayarlayarak) çağırarak oyun merkezi girişini zorlar.

+1

Zaten bunu ancak [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler: nil] aradığınız gibi geliyor authenticateHandler bir kimlik doğrulama görünümü denetleyicisi ile tekrar çağrılmasına neden olur. Bu yöntem iOS6'da olsa da kullanımdan kaldırılmıştır. – Greg

+0

Bunu işe almak için amorti edilen çağrıyı kullanıyorum, ancak kullanımdan kaldırılmış aramalar kullanmadan bunu yapmanın "doğru" yolunu arıyorum. Ben nil yeni GKLocalPlayer.localPlayer.authenticateHandler ayarlama çalıştı ve daha sonra geri işleyicisi için bu işe yarayıp yaramayacağını görmek ve nil bunu ayarlamaya çalışırken bir istisna var.O (sadece gerçekten hacky görünüyordu) bir giriş tetikleyecek eğer ben başka işleyicisi için işleyici geçiş denedim –

+0

görmek için farklı bir işleyici olarak ayarlamayı deneyin vermedi ve aynı zamanda yeni bir giriş iletişim açıklığı tetiklemek etmediğini . Herhangi bir tavsiyede bulunup bulunmadığını görmek için geliştirici forumlarında yayınladım ve bir şey duyarsam geri göndereceğim. https://devforums.apple.com/message/744983 – Greg

cevap

2

Çalışma öncesi denetimleri (önkoşul #if ifadeleri yerine instancesRespondToSelector :) kullanmanız daha iyidir, böylece başka yerlerde kullanılabilir ve amortismana tabi tutulanlar için önerilen yöntemleri kullanabilirsiniz. Yine başka vakalar matchForInvite olarak, davet işleyicisi içinde ayırt edilmelidir

-(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]; 
     }]; 
    } 
} 

: Aslında kimlik doğrulama işleyicisi ayrıca nil görünüm kontrolörü ile çağrılıp edebileceğin gibi, işleyici davet ayarlamadan önce üç olgu ayırt etmek gerekir bulundu: : yanı iOS6 yeni ve henüz başka oyun merkezi görünümü denetleyicileri içinden yuvarlak önler:

-(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 
      } 
     }; 
    } 
} 

bu yardımcı olur bana bildirin.

+1

Önişlemci makroları yalnızca hata ayıklamak ve sorunu göstermek içindi. Kullanmakta olduğum sorun, kullanıcı Game Center tarafından gösterilen ilk girişi iptal ederse iOS 6 genel API'sini kullanarak bir girişi tetikleyemezsiniz. Pre-ios6 API, bu davranışı işleyiciyi sıfırlamak için destekler. –

0

Bunun iOS 6.0'da mümkün olduğunu düşünmüyorum. SDK'nın erken sürümlerinde, yayınlanmadan önce kaldırılan API çağrıları vardı. WWDC 2012 Video İçi

: - Oturum 516 Bir authenticate yöntemini çağırın nereye Oyun Merkezi [8:30] Your Oyunları entegre Onlar aslında kodunu gösterir:

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

Bu yöntem artık özel API ama arayarak eylem görebilirsiniz:

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

Bu tam olarak ne istediğini yapar, ama şimdi özel çünkü kullanılamaz.


Ayrıca UIApplicationWillEnterForegroundNotification bildirim yayınlayarak, kimlik doğrulama işlemini tetikleyebilir:

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

Ben canlı kodda bunu unadvisable olacağını varsayıyorum.