如何在不使用GKPeerPicker的情况下通过GKSession在手机之间传输数据

时间:2012-08-06 13:03:23

标签: ios gksession

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

首先:使用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示例中一样。但是,app dev文档没有提供有关如何在不使用GKPeerPicker的情况下发送/接收数据的任何说明..(我也无法在网上找到任何示例)

1 个答案:

答案 0 :(得分:5)

我刚想出如何在没有peerpicker的情况下连接设备。这是一个猜测游戏,因为文档很不清楚,我已经在互联网上寻找这么长时间的任何信息。我会试着解释一下这里的所有内容,以便解决未来任何人可能遇到的任何问题。

来自文档:

  

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

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

要理解的第二件事是,所谓的 peer 并不一定与您有关。他们可以在附近等待被发现和连接。所有同行都有州

  • 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!");
    }
}