Ios GameCenter玩家Id到别名

Ios GameCenter玩家Id到别名,ios,iphone,ios7,game-center,leaderboard,Ios,Iphone,Ios7,Game Center,Leaderboard,在我的应用程序中,我试图将GameCenter玩家ID转换为他们的别名。收到ID后,我从循环中调用以下方法。每次使用一个id调用该方法,并应返回一个别名。我只是尝试返回一个别名,但无法使其正常工作。起初,我把回程放在街区里,但是我发现你不能在里面回程。现在我已经设置好了,它将对象添加到数组中,并在块之后返回,但是它给了我以下错误:[[uuu NSArrayM objectAtIndex:]:索引0超出空数组的界限”。任何帮助都将不胜感激 @property (nonatomic, strong,

在我的应用程序中,我试图将GameCenter玩家ID转换为他们的别名。收到ID后,我从循环中调用以下方法。每次使用一个id调用该方法,并应返回一个别名。我只是尝试返回一个别名,但无法使其正常工作。起初,我把回程放在街区里,但是我发现你不能在里面回程。现在我已经设置好了,它将对象添加到数组中,并在块之后返回,但是它给了我以下错误:[[uuu NSArrayM objectAtIndex:]:索引0超出空数组的界限”。任何帮助都将不胜感激

@property (nonatomic, strong, retain) NSMutableArray * playerScores;


LoadPlayerForIdentifiers:withCompletionHandler:
异步加载播放器,因此完成处理程序。在为
[\u playerScores objectAtIndex:0]
调用时,尚未调用完成处理程序,
playerScores
为空。这就是您看到的错误的原因

对于任何解决方案,您都必须接受异步即异步。对于一个非常简单的解决方案,您可以让
loadPlayerData:
不返回任何内容(
void
\u playerScores
看起来已经像一个成员变量,您可以在以后重复检查它

编辑:引用明确声明在主线程上调用完成处理程序:

稍后,当任务完成时,游戏套件调用您的完成处理程序。始终在主线程上调用完成处理程序

这很好,因为这样您就可以安全地调用
[self.tableView reloadData]。但是,从您的编辑中,还有两个问题变得很清楚:

  • loadScoresWithCompletionHandler:
    的完成处理程序中的
    for
    -循环
    得分
    中,您重复实例化一个数组
    player
    ,用于传递给
    loadPlayerData:
    的玩家ID。最好先填充这个数组,然后用所有玩家ID同时调用
    loadPlayerData:

  • 即使在调用
    [self.tableView reloadData]
    时,
    loadPlayerData:
    也不会完成其工作,因为
    LoadPlayerForIdentifiers:
    是异步工作的

  • 对于快速修复,我可能希望简化查询玩家别名的方式,并仅在玩家别名从Game Center服务器到达后更新表视图

    [board loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
        if (error)
        {
            return;
        }
        NSArray *player_ids = [[NSMutableArray alloc] init];
        for (GKScore *s in scores)
        {
            [player addObject:s.playerID];
        }
        [self loadPlayerData:player];
    }];
    
    为了更清楚地说明这一点,我省略了你对实际分数的处理。现在您只需加载一次玩家别名(拥有多个引导板是另一个您可能需要单独解决的问题)


    现在,您可以使用
    \u playerAliases
    字典查找玩家ID的昵称。由于您从加载分数的完成处理程序中调用了
    loadPlayerData:
    ,所有数据都将在
    LoadPlayerForIdentifiers:
    完成后准备就绪。因此,这是一个方便的时间来触发表视图的更新。

    请为integration game center使用此演示
    你好!这对我很有用。

    这是我的密码:


    我仍然有点困惑你将如何重组它。我已经更新了上面的问题,以显示我是如何调用/实现它的。
    -(NSString*) loadPlayerData: (NSArray *) identifiers
    {
        if(!_playerScores){
        _playerScores = [[NSMutableArray alloc]init];
        }
        [GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray *players, NSError *error)
         {
    
             if (error != nil)
             {
                 // Handle the error.
             }
             if (players != nil)
             {
                     GKPlayer* player = [players objectAtIndex:0];
                     [_playerScores addObject:player.alias];
             }
         }];
    
        return [_playerScores objectAtIndex:0];
    }
    
    [board loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
        if (error)
        {
            return;
        }
        NSArray *player_ids = [[NSMutableArray alloc] init];
        for (GKScore *s in scores)
        {
            [player addObject:s.playerID];
        }
        [self loadPlayerData:player];
    }];
    
    -(void)loadPlayerData:(NSArray *)identifiers
    {
        if (! _playerAliases) {
            _playerAliases = [[NSMutableDictionary alloc]init];
        }
        [GKPlayer loadPlayersForIdentifiers:identifiers
            withCompletionHandler:^(NSArray *players, NSError *error)
        {
            if ((error) || (! players))
            {
                return;
            }
            for (GKPlayer p in players)
            {
                [_playerAliases setObject:player.alias forKey::player.id];
            }
            [self.tableView reloadData];
        }];
    }
    
    GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
    
    leaderboardRequest.identifier = kHighScoreLeaderboardCategory;
    
    
    
    [leaderboardRequest loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error)
    
     {
    
    if (error) {
    
    
    
    
    NSLog(@"%@", error);
            } 
    
    else if (scores) 
    {
    
            for (GKScore *s in scores)
    
            {
                NSLog(@"Local player name is : %@", s.player.alias);
    
                 NSLog(@"Local player score's: %@", s.formattedValue);
    
    
            }
    
        }
    }];