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

abb*_*ood 1 gksession ios

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

首先:使用GKPeerPicker ..但是,在这里我遇到了必须实现自己的WIFI接口的问题。.apple没有提供有关如何执行此操作的说明:

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

第二:跳过GKPeerPicker,自己完成整个工作,如本例所示。但是,应用开发文档没有提供有关如何在不使用GKPeerPicker的情况下发送/接收数据的说明。(我也无法在thew网站上找到任何示例)

Jon*_*lay 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
Run Code Online (Sandbox Code Playgroud)

现在我们有一些代表电话来回应。 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];
    }
Run Code Online (Sandbox Code Playgroud)

}

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

-(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];
    }
}
Run Code Online (Sandbox Code Playgroud)

终于收到我们的小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!");
    }
}
Run Code Online (Sandbox Code Playgroud)