如何将GKMatchmakerViewController呈现给呈现的视图控制器?

时间:2013-01-11 09:37:08

标签: iphone ios game-center

我正在将实时游戏中心应用到我的游戏中,我在呈现GKMatchmakerViewController时遇到问题。这是我的情况:

  1. 有一个HomeViewController,我在其中提供GameViewController下一个代码:

     GameViewController *gameViewController = [[GameViewController alloc] initWithNibName:@"GameViewController" bundle:nil];
     gameViewController.delegate = self;
     [self presentViewController:gameViewController animated:NO completion:nil];
    
  2. 然后在GameViewController我加入GCHelper并致电游戏中心开始比赛:

    -(void)viewDidAppear:(BOOL)animated
    
    {
        [super viewDidAppear:animated];
    
    
        [[GCHelper sharedInstance] authenticateLocalUser];
    
        [[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:self delegate:(id)self];
    
    
    }
    
  3. 问题在于,我再次回到游戏中心的小警报显示: enter image description here

    但是没有显示游戏中心的大窗口。我确信问题在于我正在提出GameViewController

    我该如何解决这个问题?

    更新:

    当我尝试在HomeViewConroller中调用Game Center时,一切都很完美。

    更新2(已尝试): 我尝试了GCHelper:

    [presentingViewController presentViewController:mmvc animated:YES completion:nil];
    

    使用:

    AppDelegate * appdelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
    [appdelegate.homeViewController presentViewController:mmvc animated:YES completion:nil];
    

    然后我收到错误: 其视图不在窗口层次结构中!

2 个答案:

答案 0 :(得分:2)

GCHelper.h


//
//  GCHelper.h
//  KvK
//
//  Created by Kalim on 11/22/12.
//
//

#import <Foundation/Foundation.h>
#import <GameKit/Gamekit.h>

@interface GCHelper : NSObject<GKMatchmakerViewControllerDelegate, GKMatchDelegate>
{
    BOOL isUserAuthenticated;

    UIViewController *presentingViewController;
    GKMatch *match;
    BOOL matchStarted;

    GKInvite *pendingInvite;
    NSArray *pendingPlayersToInvite;
    NSMutableDictionary *playersDict;

    NSString *MultiplayerID;
    NSData *MultiData;
    NSString *otherPlayerID;

    char AlertMessageBoxNo;

    BOOL isDataRecieved;
}

//variables

@property (assign, readonly) BOOL gameCenterAvailable;
@property (retain) UIViewController *presentingViewController;
@property (retain) GKMatch *match;
@property (retain) GKInvite *pendingInvite;
@property (retain) NSArray *pendingPlayersToInvite;
@property (retain) NSMutableDictionary *playersDict;

@property (retain) NSString *MultiplayerID;
@property (retain) NSData *MultiData;

-(NSString*)getOtherPlayerId;
-(void)setOtherPlayerId;
//Functions
+ (GCHelper *)sharedInstance;
-(BOOL)isGameCenterAvailable;
-(void)authenticationChanged;
-(void)authenticateLocalUser;

-(void)gameOver:(NSString*)message;

-(void)setDataRecieved:(BOOL)d;
-(BOOL)getDataRecieved;


- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController;

@end

GCHelper.mm


//
//  GCHelper.m
//  KvK
//
//  Created by Kalim on 11/22/12.
//
//

#import "GCHelper.h"
#import "IPadSharebleClass.h"


@implementation GCHelper

@synthesize gameCenterAvailable;
@synthesize presentingViewController;
@synthesize match;
@synthesize pendingInvite;
@synthesize pendingPlayersToInvite;
@synthesize playersDict;
@synthesize MultiData;
@synthesize MultiplayerID;

static GCHelper *sharedHelper = nil;

+(GCHelper *) sharedInstance
{
    if (!sharedHelper)
    {
        sharedHelper = [[GCHelper alloc] init];
    }
    return sharedHelper;
}


- (BOOL)isGameCenterAvailable
{
    Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
    NSString *reqSysVer = @"4.1";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
    return (gcClass && osVersionSupported);
}


- (id)init
{
    if ((self = [super init]))
    {
        gameCenterAvailable = [self isGameCenterAvailable];
        if (gameCenterAvailable)
        {
            NSNotificationCenter *nc =
            [NSNotificationCenter defaultCenter];
            [nc addObserver:self
                   selector:@selector(authenticationChanged)
                       name:GKPlayerAuthenticationDidChangeNotificationName
                     object:nil];
        }
        else
        {
            UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Game Center Not Available" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
            [alert release];
        }
    }
    return self;
}

-(void)authenticationChanged
{
    if ([GKLocalPlayer localPlayer].isAuthenticated && !isUserAuthenticated)
    {
        NSLog(@"Authentication changed: player authenticated.");
        isUserAuthenticated = TRUE;

        [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
        {
            NSLog(@"Received invite");
            self.pendingInvite = acceptedInvite;
            self.pendingPlayersToInvite = playersToInvite;
            IPadCallAnyWhereF.inviteReceived();
        };

    }
    else if (![GKLocalPlayer localPlayer].isAuthenticated && isUserAuthenticated)
    {
        NSLog(@"Authentication changed: player not authenticated");
        isUserAuthenticated = FALSE;
    }


}

- (void)authenticateLocalUser
{
    if (!gameCenterAvailable) return;

    NSLog(@"Authenticating local user...");
    if ([GKLocalPlayer localPlayer].authenticated == NO)
    {
        [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil];
    }
    else
    {
        NSLog(@"Already authenticated!");
    }
}

-(void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController
{
    if (!gameCenterAvailable) return;

    matchStarted = NO;
    self.match = nil;
    self.presentingViewController = viewController;
    if (pendingInvite != nil)
    {
        [presentingViewController dismissModalViewControllerAnimated:NO];
        GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease];
        mmvc.matchmakerDelegate = self;
        [presentingViewController presentModalViewController:mmvc animated:YES];

        self.pendingInvite = nil;
        self.pendingPlayersToInvite = nil;
    }
    else
    {
        [presentingViewController dismissModalViewControllerAnimated:NO];
        GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
        request.minPlayers = minPlayers;
        request.maxPlayers = maxPlayers;
        request.playersToInvite = pendingPlayersToInvite;

        GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
        mmvc.matchmakerDelegate = self;

        [presentingViewController presentModalViewController:mmvc animated:YES];

        self.pendingInvite = nil;
        self.pendingPlayersToInvite = nil;

    }

}


#pragma mark GKMatchmakerViewControllerDelegate
- (void)matchmakerViewControllerWasCancelled:(GKMatchmakerViewController *)viewController
{
    [presentingViewController dismissModalViewControllerAnimated:YES];

    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Game Cancel By you" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='E';
}

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFailWithError:(NSError *)error
{
    [presentingViewController dismissModalViewControllerAnimated:YES];
    NSLog(@"Error finding match: %@", error.localizedDescription);
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Connection Time out" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='A';
}


- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch
{
    [presentingViewController dismissModalViewControllerAnimated:YES];
    self.match = theMatch;
    match.delegate = self;
    if (!matchStarted && match.expectedPlayerCount == 0)
    {
        NSLog(@"***************Ready to start match!**************");
        [self lookupPlayers];
    }
}

- (void)lookupPlayers
{
    NSLog(@"Looking up %d players...", match.playerIDs.count);
    [GKPlayer loadPlayersForIdentifiers:match.playerIDs withCompletionHandler:^(NSArray *players, NSError *error)
     {
         if (error != nil)
         {
             NSLog(@"Error retrieving player info: %@", error.localizedDescription);
             matchStarted = NO;
             //IPadCallAnyWhereF.matchEnded();
             UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Error retrieving player info" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
             [alert show];
             [alert release];
             AlertMessageBoxNo='F';
         }
         else
         {
             self.playersDict = [NSMutableDictionary dictionaryWithCapacity:players.count];
             for (GKPlayer *player in players)
             {
                 NSLog(@"Found player: %@", player.alias);
                 [playersDict setObject:player forKey:player.playerID];
             }
             NSLog(@"Total Number of Players : %d",players.count);
             matchStarted = YES;
             IPadCallAnyWhereF.matchStarted();
         }
     }];

}

#pragma mark GKMatchDelegate
- (void)match:(GKMatch *)theMatch didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    if (match != theMatch) return;

    MultiData=data;
    MultiplayerID=playerID;
    if(otherPlayerID==nil)
    {
        otherPlayerID=[playerID retain];
    }
    IPadCallAnyWhereF.match();
}

-(void)setDataRecieved:(BOOL)d
{
    isDataRecieved=d;
}
-(BOOL)getDataRecieved
{
    return isDataRecieved;
}


-(NSString*)getOtherPlayerId
{
    return otherPlayerID;
}

-(void)setOtherPlayerId
{
    otherPlayerID=nil;
}

- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state
{
    if (match != theMatch) return;
    switch (state)
    {
        case GKPlayerStateConnected:
            NSLog(@"New Player connected!");
            if (!matchStarted && theMatch.expectedPlayerCount == 0)
            {
                NSLog(@"&&&&&&&&&& Ready to start match in the match!");
                [self lookupPlayers];
            }
            break;
        case GKPlayerStateDisconnected:
            NSLog(@"--------Player disconnected!--------");
            matchStarted = NO;
            UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Player Disconnected" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
            [alert show];
            [alert release];
            AlertMessageBoxNo='B';
            //IPadCallAnyWhereF.matchDisconnect();
            break;
    }
}

- (void)match:(GKMatch *)theMatch connectionWithPlayerFailed:(NSString *)playerID withError:(NSError *)error
{
    if (match != theMatch) return;

    NSLog(@"Failed to connect to player with error: %@", error.localizedDescription);
    matchStarted = NO;
    //IPadCallAnyWhereF.matchEnded();
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Failed to connect to player" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='C';

}

- (void)match:(GKMatch *)theMatch didFailWithError:(NSError *)error
{
    if (match != theMatch) return;

    NSLog(@"Match failed with error: %@", error.localizedDescription);
    matchStarted = NO;
    //IPadCallAnyWhereF.matchEnded();
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:@"Match failed" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='D';

}

-(void)gameOver:(NSString*)message
{
    UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"Game Center Alert" message:message delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:@"Main Menu", nil];
    [alert show];
    [alert release];
    AlertMessageBoxNo='G';
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];

    if([title isEqualToString:@"Try Again"])
    {
        IPadCallAnyWhereF.matchDisconnect();
    }
    else if([title isEqualToString:@"Main Menu"])
    {
        IPadCallAnyWhereF.gotoMainMenu();
    }

}



@end

答案 1 :(得分:2)

问题是 [presentsViewController dismissModalViewControllerAnimated:NO];

我应该删除dismissViewController,而且一切都还好。

//[presentingViewController dismissViewControllerAnimated:NO completion:nil]; // that I removed

GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = minPlayers;
request.maxPlayers = maxPlayers;
request.playersToInvite = pendingPlayersToInvite;

GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
mmvc.matchmakerDelegate = self;

[presentingViewController presentViewController:mmvc animated:YES completion:nil];

self.pendingInvite = nil;
self.pendingPlayersToInvite = nil;