2

GKSession の動作に問題があります。以下は、特定のボタンが押されたときに実行される私のコードです。

GKSession *session;
if (connectButtonHasBeenPressed == false) {
    NSLog(@"connectToBluetoothDevice has been called");
    connectButtonHasBeenPressed = true;
    GKSession *session = [[GKSession alloc] initWithSessionID:@"Unicorn" displayName:nil sessionMode:GKSessionModePeer];
    [session setDataReceiveHandler:self withContext:nil];
    [session setDelegate:self];
    [session setAvailable:YES];
    NSLog(@"Session ID: %@", [session sessionID]);
    NSLog(@"Currently Available Peers: %i", [[session peersWithConnectionState:GKPeerStateAvailable] count]);
    if ([session isAvailable]) {
        NSLog(@"The Session Is Available");
    }
    [connectToDeviceButton setTitle:@"Searching..." forState:UIControlStateNormal];

}
else {
    NSLog(@"Currently Available Peers: %i", [[session peersWithConnectionState:GKPeerStateAvailable] count]);
}

最初にボタンを押した後、すべてが正常に機能しているように見えます。その後ボタンを押すたびに、「Currently Available Peers: 0」と表示されます。これは、ボタンを押した状態で両方のプログラムを実行して、2 つのデバイスを隣り合わせに配置していない場合に期待される出力です。また、すべての GKSessionDelegate メソッドがこのクラスに実装されており、これらすべてがメッセージをコンソールに記録します。これらのメソッドはいずれも実行されません。これはすべて、デバイスがお互いを見つけることができなかったことを示しています。

ただし、GKSession を使用して 2 つのデバイスを接続するサンプル プログラム GKRocket を実行したところ、同じ 2 つのデバイス間で問題なく動作しました。GKRocket のコードと私のプログラムのコードを比較しましたが、GKSession に影響を与えると思われる違いは見つかりませんでした。

助言がありますか?

4

1 に答える 1

2

GKSession のインスタンスが 2 つあるようです。1 つはステートメントの外側、もう 1 つはifステートメントの内側です。

これは、それconnectButtonHasBeenPressedfalse保持する独自のバージョンの GKSession を作成することを意味します。しかし、そうであれば、true等しいsessionですnil

またnil、バンドル ID を使用して設定されるため、セッション ID として使用することをお勧めします。これは個人的な好みかもしれませんが。

次のようなものを使用してみてください。

if (session == nil)
{
    NSLog(@"connectToBluetoothDevice has been called");
    session = [[GKSession alloc] initWithSessionID:nil displayName:nil sessionMode:GKSessionModePeer];
    [session setDataReceiveHandler:self withContext:nil];
    [session setDelegate:self];
    [session setAvailable:YES];

    NSLog(@"Session ID: %@", [session sessionID]);
    if ([session isAvailable])
    {
        NSLog(@"The Session Is Available");
    }
    [connectToDeviceButton setTitle:@"Searching..." forState:UIControlStateNormal];

    connectButtonHasBeenPressed = true;
}

NSLog(@"Currently Available Peers: %i", [[session peersWithConnectionState:GKPeerStateAvailable] count]);

GKSession が nil に等しいかどうかを確認するだけでよいので、実際には変数を持つ必要はありませんconnectButtonHasBeenPressed。これは、接続がない場合は常にそうあるべきです。セッションが終了したら、常にすべてのセッション アクションをキャンセルして set を設定する必要がありますsession = nil;

session変数は、クラス全体で使用できるように、実際には .h ファイルで宣言する必要があります。したがって、それGKSession *session;はもう必要ありません。

注:connectToBluetoothDevice has been calledログからのメモです。私の経験から、GKSession は利用可能なものに応じて WiFi または Bluetooth を使用します。Bluetooth のみをオンにしたデバイス、WiFi のみをオンにしたデバイス、両方をオンにした最後のデバイスの 3 つのデバイスを使用できます。

お役に立てれば。

編集:コード例から不要なconnectButtonHasBeenPressed変数を削除し、さらに説明を追加しました。

于 2013-06-03T17:37:03.450 に答える