ios: GameCenter相关

由于项目的需要,会接入ios的GameCenter排行榜、成就等等。简易的封了一下,方便使用。

GameCenterHelp.h

//  zhangwy
//  GameCenterHelp
//  Get GameCenter Data

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

#define GAMECENTER_ID       @"gamecenter_id"
#define GAMECENTER_ALIAS    @"gamecenter_alias"
#define GAMECENTER_NAME     @"gamecenter_name"

#define GAMECENTER_RANK_TITLE @"gamecenter_rank_title"
#define GAMECENTER_RANK_VALUE @"gamecenter_rank_value"
#define GAMECENTER_RANK_POS   @"gamecenter_rank_pos"

typedef enum
{
    STATUS_DEFAULT=0,
    STATUS_LOADING=1,
    STATUS_END=2
}TYPE_STATUS;

@protocol GameCenterHelpDelegate <NSObject>
@required
// 回调
- (void)onGameCenterPlayerFriend:(NSString*)strFriend;
- (void)onGameCenterRankInfo:(NSString*)strName rankInfo:(NSString*)jsonStr;
@end

@interface GameCenterHelp : NSObject<GKGameCenterControllerDelegate>
{}

+ (GameCenterHelp*)share;
// should be call this two before call other functions except share
- (void)initCommandCallback:(id<GameCenterHelpDelegate>)delegate;
- (void)initRootViewController:(UIViewController*)myRootViewController;

- (BOOL)IsLogin;
- (void)GameCenterLogin;
- (void)GameCenterShowAchievement;
- (void)GameCenterShowRank:(NSString*) rankName;
- (void)GameCenterChallenge:(int)nScore rankName:(NSString*)strName defaultMessage:(NSString*)strMessage;

// 达成成就
- (void)CompletedAchievement:(NSString*)strName;
// 提交排行榜数据
- (void)JoinIntRank:(int)nScore rankName:(NSString*)strNamse;
- (void)JoinFloatRank:(float)flScore rankName:(NSString*)strName;

// 获取GameCenter好友信息
- (void)GameCenterLoadFriends;
// 获取GameCenter排行榜数据
- (void)GameCenterLoadRankData:(NSString*)strName;

@property (nonatomic, strong) id<GameCenterHelpDelegate> delegate;
@end

 

GameCenterHelp.mm

//
//  GameCenterHelp
//

#import "GameCenterHelp.h"

@implementation GameCenterHelp
{
    UIViewController *myViewController;
    NSArray<GKPlayer *> *playerFriends;
    
    //NSMutableDictionary *pRanks;
    NSMutableArray *pRankNameArr;
    TYPE_STATUS rankRequest_status;
    BOOL bRequestRank;
}

+ (GameCenterHelp*)share
{
    static GameCenterHelp* share = nil;
    static dispatch_once_t one;
    dispatch_once(&one, ^
    {
        share = [[self alloc] init];
    });
    
    return share;
}

- (void)initCommandCallback:(id<GameCenterHelpDelegate>)delegate
{
    self.delegate = delegate;
}

- (void)initRootViewController:(UIViewController*)myRootViewController
{
    myViewController = myRootViewController;
}

- (BOOL)IsLogin
{
    return [GKLocalPlayer localPlayer].authenticated;
}

- (void)GameCenterLogin
{
    if (![self isSupport])
    {
        return;
    }
    if ([self IsLogin])
    {
        return;
    }
    
    GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
    localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
    {
        if (viewController != nil)
        {
            if ([self isViewControllerValid])
            {
                [myViewController presentViewController:viewController animated:YES completion:nil];
                NSLog(@"game center show suceess view");
            }
            NSLog(@"game center login success");
        }
        else
        {
            if ([GKLocalPlayer localPlayer].authenticated)
            {
                // Get the default leaderboard identifier.
                [[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error)
                 {
                     if (error != nil)
                     {
                         NSLog(@"game center load default leaderboard fail :%@", [error localizedDescription]);
                     }
                 }];
                NSLog(@"game center authenticat success");
            }
            else
            {
                NSLog(@"game center authenticat failed");
            }
        }
    };
}

- (void)GameCenterShowAchievement
{
    GKGameCenterViewController *gameView = [[GKGameCenterViewController alloc] init];
    if(gameView != nil)
    {
        gameView.gameCenterDelegate = self;
        if ([self isViewControllerValid])
        {
            [myViewController presentViewController:gameView
                                                    animated:YES
                                                  completion:^{ NSLog(@"GameCenter show achievement completion!");}];
        }
    }
}

- (void)GameCenterShowRank:(NSString*) rankName
{
    GKGameCenterViewController *gameView = [[GKGameCenterViewController alloc] init];
    if(gameView != nil)
    {
        gameView.gameCenterDelegate = self;
        
        [gameView setLeaderboardCategory:rankName];
        [gameView setLeaderboardTimeScope:GKLeaderboardTimeScopeAllTime];
        
        if ([self isViewControllerValid])
        {
            [myViewController presentViewController:gameView
                                           animated:YES
                                         completion:^{ NSLog(@"GameCenter show rank completion!");}];
        }
    }
}

- (void)GameCenterChallenge:(int)nScore rankName:(NSString*)strName defaultMessage:(NSString*)strMessage
{
    //NSString *challengeMessage = @"This game is very fun, I played high score. Can you do me behind?";
    GKScore *scoreObj = [[GKScore alloc] initWithLeaderboardIdentifier:strName];
    scoreObj.value = nScore;
    UIViewController *challengeView = [scoreObj challengeComposeControllerWithMessage:strMessage
                                                                              players:playerFriends
                                                                    completionHandler:^(UIViewController *composeController,
                                                                                        BOOL didIssueChallenge,
                                                                                        NSArray *sentPlayerIDs)
                                       {
                                           NSLog(@"challenge dismiss !");
                                           [composeController.presentingViewController dismissViewControllerAnimated: YES completion: nil];
                                       }];
    
    if ([self isViewControllerValid])
    {
        [myViewController presentViewController:challengeView
                                                animated:YES
                                              completion:^{ NSLog(@"GameCenter show challenge completion!");}];
    }
}

- (void)CompletedAchievement:(NSString*)strName
{
    //NSLog(@"GameCenter complete achievement : %@", name);
    GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:strName];
    [achievement setPercentComplete:100];
    [achievement reportAchievementWithCompletionHandler:^(NSError *error)
     {
         if(error != nil)
         {
             NSLog(@"GameCenter complete achievement failed, error:%@", [error localizedDescription]);
         }
     }];
}

- (void)JoinIntRank:(int)nScore rankName:(NSString*)strName
{
    //NSLog(@"GameCenter submit rank int. name:%@ value:%d", name, value);
    GKScore* selfScore = [[GKScore alloc] initWithLeaderboardIdentifier:strName];
    selfScore.value = nScore;
    [GKScore reportScores:[NSArray arrayWithObject:selfScore] withCompletionHandler:^(NSError* error)
     {
         if(error != nil)
         {
             NSLog(@"GameCenter submit rank and int score failed, error:%@", [error localizedDescription]);
         }
     }];
}

- (void)JoinFloatRank:(float)flScore rankName:(NSString*)strName
{
    //NSLog(@"GameCenter submit rank int. name:%@ value:%d", name, value);
    GKScore* selfScore = [[GKScore alloc] initWithLeaderboardIdentifier:strName];
    selfScore.value = flScore;
    [GKScore reportScores:[NSArray arrayWithObject:selfScore] withCompletionHandler:^(NSError* error)
     {
         if(error != nil)
         {
             NSLog(@"GameCenter submit rank and float score failed, error:%@", [error localizedDescription]);
         }
     }];
}

- (void)GameCenterLoadFriends
{
    GKLocalPlayer* localPlayer = [GKLocalPlayer localPlayer];
    if (localPlayer)
    {
        [localPlayer loadFriendPlayersWithCompletionHandler:^(NSArray *friends, NSError *error)
         {
             if (error==nil && [friends count]!=0)
             {
                 playerFriends = [NSArray arrayWithArray:friends];
                 [self parsePlayerFriendData];
                 /*
                  for (GKPlayer *obj in playerFriends)
                 {
                     NSLog(@" playerID: %@ name: %@ alias:%@ guestId:%@",obj.playerID, obj.displayName, obj.alias, obj.guestIdentifier);
                 }
                 NSLog(@"playerFriend Count: %lu", [playerFriends count]);
                  */
             }
             else
             {
                 NSLog(@"GameCenter load friend failed or no friend");
             }
         }];
    }
}

- (void)GameCenterLoadRankData:(NSString*)strName
{
    [self startLoad:strName];
}

// GKGameCenterControllerDelegate callback begin
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController NS_AVAILABLE(10_9, 6_0)
{
    // gamecenter view dismiss callback
    NSLog(@"GameCenter GKGameCenterView didFinish");
}

// GKGameCenterControllerDelegate callback end

// not public begin
- (id)init
{
    if(self = [super init])
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(playerChanged)
                                                     name:GKPlayerAuthenticationDidChangeNotificationName
                                                   object:nil];

        pRankNameArr = nil;
        rankRequest_status = STATUS_DEFAULT;
    }
    return self;
}

- (void)playerChanged
{
    // GameCenter Account Changed , need to reload all data
    if([GKLocalPlayer localPlayer].isAuthenticated)
    {}
    else
    {}
}

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

- (BOOL)isViewControllerValid
{
    if (myViewController)
    {
        return TRUE;
    }
    else
    {
        NSLog(@"GameCenterHelp Error : myViewController is nil");
        return FALSE;
    }
}

- (void)parsePlayerFriendData
{
    if ([playerFriends count]==0)
    {
        NSLog(@"Parse PlayerFriends Data Failed");
        return;
    }
    
    NSMutableDictionary *dicPlayer = [NSMutableDictionary dictionary];
    for(GKPlayer* objFriend in playerFriends)
    {
        [dicPlayer setValue:objFriend.playerID forKey:GAMECENTER_ID];
        [dicPlayer setValue:objFriend.displayName forKey:GAMECENTER_NAME];
        [dicPlayer setValue:objFriend.alias forKey:GAMECENTER_ALIAS];
        
        NSString *jsonStr = [NSString stringWithString:[self getJsonStringFromDictionary:dicPlayer]];
        NSLog(@"PlayerFriend jsonstr : %@", jsonStr);
        if(self.delegate)
           [self.delegate onGameCenterPlayerFriend:jsonStr];
        [dicPlayer removeAllObjects];
    }
}

- (NSString *)getJsonStringFromDictionary:(NSMutableDictionary *)dicData
{
    NSError *jsonError = nil;
    NSData  *jsonData = [NSJSONSerialization dataWithJSONObject:dicData options:NSJSONWritingPrettyPrinted error:&jsonError];
    if ([jsonData length]==0 || jsonError!=nil)
    {
        return nil;
    }
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    return jsonString;
}

- (void)startLoad:(NSString*)strName
{
    if (rankRequest_status==STATUS_LOADING)
    {
        if (!pRankNameArr)
        {
            pRankNameArr = [[NSMutableArray alloc] initWithCapacity:10];
        }
        [pRankNameArr addObject:[NSString stringWithString:strName]];
        return;
    }
    
    rankRequest_status = STATUS_LOADING;
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(loadingRankInfo:) object:strName];
    [thread start];
}

-(void)loadingRankInfo:(NSString* )strName
{
    int nPos = 1;
    int nTimes= 1;
    bRequestRank = true;
    
    while (rankRequest_status==STATUS_LOADING)
    {
        if (bRequestRank)
        {
            bRequestRank = false;
            NSLog(@"GameCenterHelp -- load rank pos : %d", nPos);
            GKLeaderboard* leaderboard = [[GKLeaderboard alloc] init];
            leaderboard.playerScope = GKLeaderboardPlayerScopeGlobal;
            leaderboard.range = NSMakeRange(nPos, 10);
            leaderboard.identifier = strName;
            [leaderboard loadScoresWithCompletionHandler:^(NSArray* scores, NSError* error)
             {
                 if(error != nil)
                 {
                     NSLog(@"GameCenterHelp -- load rank failed . pos:%d error:%@", nPos, [error description]);
                 }
                 if(scores != nil)
                 {
                     NSArray *tempScore = [NSArray arrayWithArray:leaderboard.scores];
                     NSMutableDictionary *dicRankInfo = [NSMutableDictionary dictionary];
                     for (GKScore *obj in tempScore)
                     {
                         //NSLog(@"playerID: %@ name: %@ value:%lld rank:%ld alias:%@",obj.playerID, obj.player.displayName, obj.value, obj.rank,obj.player.alias);
                         
                         [dicRankInfo setValue:strName forKey:GAMECENTER_RANK_TITLE];
                         [dicRankInfo setValue:obj.playerID forKey:GAMECENTER_ID];
                         [dicRankInfo setValue:[NSString stringWithFormat:@"%ld", (long)obj.rank] forKey:GAMECENTER_RANK_POS];
                         [dicRankInfo setValue:[NSString stringWithFormat:@"%ld", (long)obj.value] forKey:GAMECENTER_RANK_VALUE];
                         [dicRankInfo setValue:obj.player.displayName forKey:GAMECENTER_NAME];
                         [dicRankInfo setValue:obj.player.alias forKey:GAMECENTER_ALIAS];
                         
                         NSString *jsonStr = [NSString stringWithString:[self getJsonStringFromDictionary:dicRankInfo]];
                         NSLog(@"GameCenterHelp -- rankInfo jsonstr : %@", jsonStr);
                         if(self.delegate)
                             [self.delegate onGameCenterRankInfo:strName rankInfo:jsonStr];
                         [dicRankInfo removeAllObjects];
                     }
                 }
                 
                 // end condition
                 if (error==nil && scores==nil)
                 {
                     rankRequest_status= STATUS_END;
                     NSLog(@"GameCenterHelp -- rank -%@- load end, no error no data ", strName);
                 }
                 
                 // end condition
                 if (nTimes>100)
                 {
                     rankRequest_status= STATUS_END;
                     NSLog(@"GameCenterHelp -- rank -%@- load end, load too much times: %d ", strName, nTimes);
                 }
                 
                 bRequestRank = true;
             }];
            
            nPos = nTimes*10 + 1;
            nTimes++;
        }
    }
    
    if (pRankNameArr)
    {
        int nCount = [pRankNameArr count];
        if (nCount!=0)
        {
            NSString *strRank = [pRankNameArr objectAtIndex:nCount-1];
            [pRankNameArr removeObjectAtIndex:nCount-1];
            [self startLoad:strRank];
        }
    }
}

// not public end

- (void)dealloc
{
    [super dealloc];
}

@end

 

posted @ 2016-12-12 22:07  lucky_zhangwy  阅读(1422)  评论(0编辑  收藏  举报