博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编写苹果游戏中心应用程序(翻译 1.8 获取本地玩家的好友信息)
阅读量:4217 次
发布时间:2019-05-26

本文共 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/

你可能感兴趣的文章
《浪潮之巅》5奔腾的芯 英特尔公司
查看>>
python语言程序设计基础笔记(三)从题目到方案
查看>>
读取txt文件出现出现多余空行问题
查看>>
从理论到实践开发自己的聊天机器人
查看>>
@***装饰器(python)
查看>>
最优化算法之梯度下降法
查看>>
激活函数之ReLU函数
查看>>
经典排序算法详解
查看>>
概述类加载器及类加载过程
查看>>
MySQL SQL优化总结
查看>>
MySQL MyISAM引擎的读锁与写锁
查看>>
面向对象与面向过程的本质的区别
查看>>
Java语言有哪些特点?
查看>>
idea创建maven项目并关联gitee
查看>>
HashMap和Hashtable的区别
查看>>
JVM 对 Java 的原生锁做了哪些优化?
查看>>
JAVA实现简单的阻塞队列
查看>>
我的2020
查看>>
idea快捷键使用
查看>>
2.1MAC协议概述
查看>>