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