1

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

第一:使用GKPeerPicker .. 但是在这里我被困在我必须实现自己的WIFI 接口的地方.. 苹果没有提供如何做到这一点的说明:

- (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 并自己做整个事情,就像在这个例子中一样。但是,应用程序开发文档没有提供有关如何在不使用 GKPeerPicker 的情况下发送/接收数据的任何说明。(我也无法在网络上找到任何示例)

4

1 回答 1

5

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

从文档中:

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

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

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

  • GKPeerStateAvailable(这是有用的!)
  • GKPeerState 不可用
  • 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!");
    }
}
于 2012-10-05T01:28:45.213 回答