Hay dos formas de hacerlo.
La primera forma usa GameKit API. Empieza por tener dos clases separadas, una que implementa el protocolo GKSessionDelegate
y actúa como un "manejador" de GameKit/Bluetooth y la otra como la IU de presentación (lo más probable es algún tipo de controlador de vista con una vista de tabla). La forma en que lo conectarías es que el manejador maneja las notificaciones de GameKit, etc. y luego llama a los métodos de delegado en la UI para actualizar la vista de tabla cuando un compañero se conecta/deja caer, etc. De esta manera, cuando los dispositivos entran y salen, tu lista de selectores debería actualizar para mostrar quién está alrededor.
A continuación se muestra un código para que pueda empezar:
- (BOOL) startPeer
{
BOOL result = NO;
if (!_session) {
_session = [[GKSession alloc] initWithSessionID:BLUETOOTHSESSION
displayName:nil
sessionMode:GKSessionModePeer];
_session.delegate = self;
[_session setDataReceiveHandler:self withContext:nil];
_session.available = YES;
result = YES;
}
return result;
}
- (void) stopPeer
{
// Set up the session for the next connection
//
[_session disconnectFromAllPeers];
_session.available = YES;
[self cleanupProgressWindow];
}
- (void) loadPeerList
{
self.peerList = [[NSMutableArray alloc] initWithArray:[_session peersWithConnectionState:GKPeerStateAvailable]];
}
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state
{
BOOL peerChanged = NO;
switch(state) {
// When peer list changes, we adjust the available list
//
case GKPeerStateAvailable:
if (_peerList) {
[_peerList addObject:peerID];
peerChanged = YES;
}
break;
// When peer list changes, we adjust the available list
//
case GKPeerStateUnavailable:
if (_peerList) {
[_peerList removeObject:peerID];
peerChanged = YES;
}
break;
// Called when the peer has connected to us.
//
case GKPeerStateConnected:
// start reading and writing
break;
case GKPeerStateDisconnected:
{
if (_isWriter) {
_isConnected = NO;
_deviceToSend = nil;
[self cleanupProgressWindow];
} else {
// Other side dropped, clean up local data and reset for next connection
self.dataRead = nil;
}
}
break;
}
// Notify peer list delegate that the list has changed so they can update the UI
//
if (peerChanged)
CALLDELEGATE(_peerListDelegate, peerListChanged);
}
La segunda manera de hacerlo es utilizar mecanismos de selección de servicios estándar de Bonjour. GameKit se implementa encima de Bonjour (pero a través de Bluetooth en lugar de WiFi) por lo que una vez que las dos partes hayan alcanzado el alcance de la red y estén conectadas, se registrarán bajo Bonjour y actuarán como lo haría cualquier servicio de Bonjour. El modo GameKit es probablemente un poco más fácil, pero si ya tienes un código para WiFi, también se puede reutilizar para Bluetooth.
Oye, muchas gracias por esta plantilla para construir. Una pregunta más, puedo ver cómo la sesión: el método peer: didChangeState iría en el archivo delegate.h/.m, pero ¿qué pasa con los otros métodos? ¿Entrarían el startPeer y el stopPeer en mis archivos viewcontroller.h/.m o la plantilla completa iría en el archivo delegado? –
En este caso, se supone que todos están en el controlador de delegado, ya que tratan con la instalación de tuberías de GameKit subyacente. No hay ninguna razón por la que no pueda colocar todo dentro del controlador de visualización, pero es una buena idea mantener el código de UI desacoplado del código de red.Después de actualizar la matriz de pares, el objeto 'manejador' invoca su propio método de delegado personalizado "peerListChanged" que notifica al controlador de vista que la lista ha cambiado para poder solicitar una recarga de tabla y mostrar la nueva lista al usuario. – Ramin
¿Esto solo funciona a través de Wifi o también encontrará pares sobre bluetooth? ¿Tienes que usar el selector de pares para usar bluetooth? – typeoneerror