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

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

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

任何想法的人?

如果您对教程感兴趣,Ray Wenderlich有一个关于创建蓝牙卡游戏的精彩教程。 他在这个游戏中实现了PeerPicker。

如何使用多人游戏和蓝牙制作简单的纸牌游戏,第1部分

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

从文档:

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

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

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

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