1

GKSession を使用して 2 台以上の電話間でデータを転送するアプリを作成しようとしています。問題は、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.
    }
}

2 番目:この例のように、GKPeerPicker をスキップして、自分ですべてを実行します。ただし、アプリの開発ドキュメントには、GKPeerPicker を使用せずにデータを送受信する方法についての説明はありません (Web でその例を見つけることもできませんでした)。

4

1 に答える 1

5

ピアピッカーなしでデバイスを接続する方法を見つけました。ドキュメントがかなり不明確であり、これに関する情報をインターネットで長い間探していたため、ちょっとした推測ゲームでした。ここですべてを説明して、将来誰もが持つ可能性のある質問を解決しようとします.

ドキュメントから:

GKSession オブジェクトは、Bluetooth または Wi-fi を使用して近くの iOS デバイスを検出して接続する機能を提供します。

これは私にとってそれを理解するための最初のステップでした。GKPeerPickerController が広告と接続を担当していると思っていましたが、実際には GKSession がすべてを行っています。

2 番目に理解しておくべきことは、ピアと呼ばれるものは必ずしもあなたとつながっているわけではないということです。それらは近くにいて、発見されて接続されるのを待っているだけです。すべてのピアには状態があります

  • 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!");
    }
}
于 2012-10-05T01:28:45.213 に答える