【问题标题】:How to transfer data between phones over GKSession without using GKPeerPicker如何在不使用 GKPeerPicker 的情况下通过 GKSession 在手机之间传输数据
【发布时间】:2019-03-27 03:36:13
【问题描述】:

我正在尝试创建一个使用 GKSession 在两部以上手机之间传输数据的应用。事情是有两个选择:

首先: 使用GKPeerPicker.. 但是在这里我陷入了必须实现自己的WIFI interface.. 苹果没有提供有关如何执行此操作的说明:

- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:    (GKPeerPickerConnectionType)type {
    if (type == GKPeerPickerConnectionTypeOnline) {
        picker.delegate = nil;
        [picker dismiss];
        [picker autorelease];
       // Implement your own internet user interface here.
    }
}

第二个: 跳过 GKPeerPicker 并自己做所有事情,就像在 this 示例中一样。但是,应用程序开发文档没有提供任何关于如何在不使用 GKPeerPicker 的情况下发送/接收数据的说明。(我也无法在网上找到任何示例)

【问题讨论】:

  • 您在实现自己的 wifi 接口方面链接到的问题涉及您的游戏是否使用基于互联网的服务器来进行在线游戏 - 而不是 P2P,这是 PeerPicker 的用途.此外,当它说实现您自己的界面时 - 它表示用户界面,而不是您的问题中暗示的实际 wifi 界面。
  • 如果我的 connectionTypesMask 是 GKPeerPickerConnectionTypeNearby(即蓝牙),那么 PeerPicker 会显示一个模式弹出窗口,上面写着“正在搜索附近的 ipad/iphone 等”,并带有一个微调器。直到它找到一个设备并与它.. 触发 peerPickerController:didConnectPeer:toSession: 回调。但是,如果我的连接是 GKPeerPickerConnectionTypeOnline(即在线).. 那么我应该 搜索 附近的其他设备.. 我应该完成连接.. 我找不到任何有关与此程序相关的任何内容的文档..这就是我真正要问的

标签: ios gksession


【解决方案1】:

我刚刚弄清楚如何在没有 peerpicker 的情况下连接设备。这有点像猜谜游戏,因为文档很不清楚,我在互联网上寻找了很长时间的任何信息。我将尝试在这里解释所有内容,以澄清将来任何人可能遇到的任何问题。

来自文档:

GKSession 对象提供了发现和连接到 附近使用蓝牙或 Wi-fi 的 iOS 设备。

这是我理解它的第一步。我以为 GKPeerPickerController 负责广告和连接,但实际上 GKSession 做了所有这些。

要了解的第二件事是,所谓的 peers 不一定与您相关。他们可以在附近等待被发现和连接。所有对等点都有一个状态

  • GKPeerStateAvailable(这很有用!)
  • GKPeerStateUnavailable
  • GKPeerStateConnected
  • GKPeerStateDisconnected
  • GKPeerStateConnecting

那么我们如何实际连接?首先我们必须创建一个 GKSession 对象,以便能够找到我们周围的对等点并查看它们何时可用:

// nil will become the device name
GKSession *gkSession = [[GKSession alloc] initWithSessionID:@"something.unique.i.use.my.bundle.name" displayName:nil sessionMode:GKSessionModePeer];
[gkSession setDataReceiveHandler:self withContext:nil];
gkSession.delegate = self;
gkSession.available = YES; // I'm not sure this if this is the default value, this might not be needed

现在我们有一些代理调用要响应。session:didReceiveConnectionRequestFromPeer:session:peer:didChangeState(您还应该适当处理 GKSessionDelegate 的调用以导致断开连接和失败)

-(void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state
{
    if(state == GKPeerStateDisconnected)
    {
        // A peer disconnected
    }
    else if(state == GKPeerStateConnected)
    {   
        // You can now send messages to the connected peer(s)
        int number = 1337;
        [session sendDataToAllPeers:[NSData dataWithBytes:&number length:4] withDataMode:GKSendDataReliable error:nil];
    }
    else if (state == GKPeerStateAvailable)
    {
        // A device became available, meaning we can connect to it. Lets do it! (or at least try and make a request) 
        /*
        Notice: This will connect to every iphone that's nearby you directly. 
        You would maybe want to make an interface similar to peerpicker instead
        In that case, you should just save this peer in a availablePeers array and 
        call this method later on. For your UI, the name of the peer can be 
        retrived with [session displayNameForPeer:peerId]
        */
        [session connectToPeer:peerID withTimeout:10];
    }

}

另一个对等方现在收到了一个他应该响应的请求。

-(void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID
{
    // We can now decide to deny or accept
    bool shouldAccept = YES;
    if(shouldAccept)
    {
        [session acceptConnectionFromPeer:peerID error:nil];
    }
    else
    {
        [session denyConnectionFromPeer:peerID];
    }
}

终于收到我们的1337小消息

-(void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession*)session context:(void *)context
{
    int number = 1337;
    if([data isEqualToData:[NSData dataWithBytes:&number length:4]])
    {
        NSLog(@"Yey!");
    }
}

【讨论】:

    猜你喜欢
    • 2018-11-13
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 2012-02-08
    • 2020-02-24
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多