Bluetooth に代えてWiFiを使ったピア接続をやってみる。
GKPeerPickerConnectionTypeOnline
WiFi経由で接続する場合は GKPeerPickerController.connectionTypesMask に GKPeerPickerConnectionTypeOnline を加える。
picker.connectionTypesMask = GKPeerPickerConnectionTypeOnline|GKPeerPickerConnectionTypeNearby;GKPeerPickerConnectionTypeOnline だけでは駄目で GKPeerPickerConnectionTypeNearby を一緒に指定する必要がある。設定しない場合エラーとなる。
[2152:307] *** Terminating app due to uncaught exception 'GKInvalidArgumentException', reason: 'A GKPeerPickerController must support GKPeerPickerConnectionTypeNearby at a minimum.'
すると最初に WiFiと Bluetoothのどちらを使うか選択ダイアログが表示されるようになる。
GKSession作成
WiFi の場合は GKPeerPickerControllerDelegate の -[GKPeerPickerController peerPickerController:didSelectConnectionType:] を実装する。
- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type { if (type == GKPeerPickerConnectionTypeOnline) { picker.delegate = nil; [picker dismiss]; [picker autorelease]; self.session = [[[GKSession alloc] initWithSessionID:nil displayName:nil sessionMode:GKSessionModePeer] autorelease]; self.session.delegate = self; self.session.available = YES; [self.session setDataReceiveHandler:self withContext:nil]; } }WiFi の場合 GKPeerPickerController がやってくれるのはここまでで、これ以降は接続まで自前で実装する必要がある(Bluetoothの場合は接続可能な端末がリストアップされ選択=接続することができる)。
GKSession を作成した後、-[GKSessionDelegate session:peer:didChangeState:] が呼び出されて GKSessionが利用可能になる(GKPeerStateAvailable)。その時点で接続可能な端末が見つかると割り当てられた peerID から端末名を取得することができる。これをリストアップすれば Bluetoothの場合と同様に接続可能リストが表示できそうだ。今回は無条件に connectToPeer:withTimeout: を呼び出して見つかった端末へ接続しに行く。
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { switch (state) { case GKPeerStateAvailable: NSLog(@"connecting to %@ ...", [session displayNameForPeer:peerID]); [session connectToPeer:peerID withTimeout:10]; break; case GKPeerStateConnected: self.message.text = @"connected"; self.peerID = peerID; break; case GKPeerStateDisconnected: self.message.text = @"disconnected"; self.session = nil; default: break; } }このプログラムを2台の端末で実行すると両方で接続要求をだすので片方はエラーが出る。
Error Domain=com.apple.gamekit.GKSessionErrorDomain Code=30510 "Connection to peer already in progress after initially succeeding." UserInfo=0x9342b10 {NSLocalizedFailureReason=Found in progress after success., NSLocalizedDescription=Connection to peer already in progress after initially succeeding.}しかし、その後片方が成功して接続が確立する。後は Bluetooth同様にデータの送受信が可能。
ソースコード
BluetoothSample at 2010-12-11 from xcatsan/iOS-Sample-Code - GitHub
参考情報
Game Kit Programming Guide: About Game Kit
iOS Reference Library
Game Kit Programming Guide の日本語版(PDF)が提供されている。
匿名
2012年12月2日 18:38
この方法を試してみたのですが、なぜかBlueToothで接続されてしまいます。
匿名
2012年12月2日 18:38
この方法を試してみたのですが、なぜかBlueToothで接続されてしまいます。
匿名
2013年4月18日 18:01
Wifiで全く動作しない
匿名
2013年4月18日 18:01
Wifiで全く動作しない