本文共 4538 字,大约阅读时间需要 15 分钟。
1.8 获取本地玩家的好友信息
问题
你已添加好友到本地玩家账户,但现在想枚举这些好友并获得他们的信息,比如他们的别名。
解决方案
使用本地玩家对象的friends属性。
讨论
GKLocalPlayer有一个叫作friends的属性,为NSArray类型。该属性“将”包含本地玩家的好友;数组使用玩家ID(参考条目1.6)表示玩家。
上面的段落中说的是“将”,这是因为在本地玩家通过身份验证后,该数组是空的(nil)。你需要调用GKLocalPlayer类的实例方法loadFriendsWithCompletionHandler:来加载该数组。取得ID后,调用另外一个方法获取每个好友的其它信息。
GKLocalPlayer类的实例方法loadFriendsWithCompletionHandler:接受一个参数,该参数必须是一个返回void(换句话说,就是无返回值)并且拥有两个参数的块对象。块对象的第一个参数为NSArray类型,将返回本地玩家的好友ID。第二个参数为NSError类型,返回处理过程中是否有错误发生。
为避免代码多次重复,此处假定本地玩家已经通过身份验证(参考条目1.5)。
下面看看加载本地玩家好友ID的示例:
void (^getLocalPlayerFriends)(void) = ^{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; if ([localPlayer isAuthenticated] == NO){ NSLog(@"The local player is not authenticated."); return; } NSLog(@"Loading local player's friend IDs..."); [localPlayer loadFriendsWithCompletionHandler: ^(NSArray *friends, NSError *error) { if (friends != nil){ NSLog(@"Successfully retrieved friends of the local player."); NSUInteger counter = 1; for (NSString *friendID in friends){ NSLog(@"Friend %lu = %@", (unsigned long)counter, friendID); counter++; } } if (error != nil){ NSLog(@"Error occurred. Error = %@", error); } }]; };如条目1.2中的第一步所提,我创建了三个游戏中心的玩家,这样才能向你演示游戏中心的功能。如果你仅创建了一个玩家,就无法去做诸如添加好友之类的事情,除非你能确切地知道沙盒上的其它玩家。不过,我再次强烈建议,你至少创建两位玩家,以便测试本书中的示例代码。
在iOS模拟器中运行该代码,获得类似如下的结果:
Loading local player's friend IDs...
Successfully retrieved friends of the local player. Friend 1 = G:1428629254 Friend 1 = G:1428629742如你所见,我添加了两位好友。如果你再次查看代码,就会注意到我检查了好友数组是否为nil,然后在then中检查加载过程中是否有错误发生。这么作的原因很简单:游戏中心只是试图加载本地玩家好友。即使有错误发生,也可能已经加载了一些信息。因此,你获得的数组中包含了本地玩家的部分好友。虽然只有好友的一部分,但你可能仍想继续执行下去。如果你要确定没有错误发生,我建议你首先检查错误参数,然后再打印数组friends的内容。
为侦测游戏中心是否能够成功加载好友列表,我们应当确保错误参数为nil;为侦测好友列表是否被部分接收,我们应当检查好友数组和错误参数是否都不是nil。如果有nil,则意味着,虽然我们可能获得了一些好友,但在获取其余好友时发生了错误。
一切都进行得不错,我拥有了本地玩家的好友的ID。为使用玩家ID取得GKPlayer类的实例,你得使用GKPlayer类的类方法loadPlayersForIdentifiers:withCompletionHandler:,完整的流程如下:
1. 验证本地玩家。
2. 获取本地玩家的ID。
3. 根据玩家ID获取GKPlayer的实例:
void (^getLocalPlayerFriendsDetails)(void) = ^{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; if ([localPlayer isAuthenticated] == NO){ NSLog(@"The local player is not authenticated."); return; } if ([[localPlayer friends] count] == 0){ NSLog(@"The local player has no friends. How sad!"); return; } NSLog(@"Loading players..."); [GKPlayer loadPlayersForIdentifiers:[localPlayer friends] withCompletionHandler:^(NSArray *players, NSError *error) { if (players != nil){ NSLog(@"Successfully loaded the players."); for (GKPlayer *player in players){ NSLog(@"%@", player); } } if (error != nil){ NSLog(@"Error happened. Error = %@", error); } }]; }; void (^getLocalPlayerFriends)(void) = ^{ GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; if ([localPlayer isAuthenticated] == NO){ NSLog(@"The local player is not authenticated."); return; } NSLog(@"Loading local player's friend IDs..."); [localPlayer loadFriendsWithCompletionHandler: ^(NSArray *friends, NSError *error) { if (friends != nil){ NSLog(@"Successfully retrieved friends of the local player."); dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(concurrentQueue, getLocalPlayerFriendsDetails); } if (error != nil){ NSLog(@"Error occurred. Error = %@", error); } }]; }; - (void) authenticateLocalPlayerAndGetHerInfo{ dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(concurrentQueue, ^(void) { GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; if ([localPlayer isAuthenticated] == NO){ [localPlayer authenticateWithCompletionHandler:^(NSError *error) { if (error == nil){ NSLog(@"Successfully authenticated."); dispatch_async(concurrentQueue, getLocalPlayerFriends); } else { NSLog(@"Failed to authenticate. Error = %@", error); } }]; } else { dispatch_async(concurrentQueue, getLocalPlayerFriends); } }); }调用authenticateLocalPlayerAndGetHerInfo之后,我获得了如下的信息(因为我通过身份验证的本地玩家,拥有两个好友):
Successfully authenticated.
Loading local player's friend IDs... Successfully retrieved friends of the local player. Loading players... Successfully loaded the players. <GKPlayer 0x5f32d90>(playerID: G:1428629254, alias: Test Game User 2, status: (null), rid:(null)) <GKPlayer 0x5f32cf0>(playerID: G:1428629742, alias: Test Game User 3, status: (null), rid:(null))拥有这些信息后,你可以将他们显示给玩家或持有在以后引用。不要将玩家ID保存在游戏中。无论玩家何时运行你的应用程序,你都必须重新获取好友列表,而不要假设几天前获取的好友仍然是本地玩家的好友。另外,玩家ID的格式也可能改变,正如Apple在其文档中所提:
Do not make assumptions about the contents of the player identifier string. Its format and length are subject to change.
转载地址:http://ieami.baihongyu.com/