2010-02-20 7 views
11

Estoy trabajando en una aplicación de iPhone que permitirá las conexiones de igual a igual. Por lo que entiendo, tengo la opción entre usar GKPeerPicker o GKSession. No me gusta la idea de usar PeerPicker porque quiero mostrar una interfaz personalizada, así que decidí ir con GKSession, y hey, BONUS es que también funciona a través de Wi-Fi, mientras que el Peer Picker no funciona.GKSession: ¿qué sucede si tengo Bluetooth y Wi-Fi apagados?

OK, entonces el problema es ... ¿qué pasa si el usuario tiene tanto Bluetooth como Wi-Fi apagados? En el Peer Picker, hay un aviso para activar Bluetooth sin salir de la aplicación. GKSession no lo tiene ... pero espere un segundo, parece que ni siquiera puedo verificar si Bluetooth está activado o no programáticamente.

Carpe Cocoa claims no problem, simplemente use el método session:didFailWithError: del Delegado. Pero, como se explica en los comentarios ... ¡parece que ya no funciona! Y en mi experiencia, estoy de acuerdo.

¿Hay alguna otra manera de verificar mediante programación si Bluetooth está activado? ¿Es esto algo por lo que debería aprovechar Alcance? ¿O es solo un error que Apple aún tiene que arreglar?

Para ser más específicos, estoy creando mi sesión de la siguiente manera:

GKSession *aSession = [[GKSession alloc] initWithSessionID:nil 
                displayName:user.displayName 
                sessionMode:GKSessionModePeer]; 

self.gkSession = aSession; 
[aSession release]; 

self.gkSession.delegate = self; 
self.gkSession.available = YES; 

[self.gkSession setDataReceiveHandler:self withContext:NULL]; 

La clase implementa el GKSessionDelegate, y sé que está funcionando porque cuando tengo activada la función Bluetooth, los métodos de delegado se llaman No hay problema. Yo les he implementado como tal:

#pragma mark - 
#pragma mark GKSessionDelegate methods 

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { 
    if (GKPeerStateAvailable == state) { 
      [session connectToPeer:peerID withTimeout:10]; 
    } else if (GKPeerStateConnected == state) { 
      // gets user 

      NSError *error = nil; 
      [session sendData:user.connectionData 
         toPeers:[NSArray arrayWithObjects:peerID,nil] 
       withDataMode:GKSendDataReliable error:&error]; 
      if (error) 
       NSLog(@"%@",error); 
    } 
} 



- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID { 
    NSError *error = nil; 
    [session acceptConnectionFromPeer:peerID error:&error]; 
    if (error) 
      NSLog(@"%@",error); 
} 

- (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error { 
    NSLog(@"%@",error); 
} 

- (void)session:(GKSession *)session didFailWithError:(NSError *)error { 
    NSLog(@"%@",error); 
} 

Ninguna de las declaraciones de registro se imprimen y establecer puntos de interrupción en cada método, pero ninguno de ellos se ven afectados cuando el usuario tiene Bluetooth y Wi-Fi apagados. Esperaba que ocurriera algo para activar la sesión: didFailWithError: para que yo pudiera pedirle al usuario que active el Bluetooth o se conecte a una red Wi-Fi.

+2

Suena como un error o posiblemente una solicitud de mejora. Debes archivar un radar. –

Respuesta

1

Un punto interesante, ¿ha intentado probarlo con Bluetooth DESACTIVADO y con el WiFi activado? Descubrí recientemente que, aunque mi programa llamaba a este mensaje 'Bluetooth no disponible', en realidad no estaba usando Bluetooth en absoluto, sino que se estaba conectando a través de mi red WiFi. No conozco una forma de forzar a GKSession a una conexión Bluetooth sin utilizar el objeto PeerPicker de Apple, pero el objeto PeerPicker permite que las personas creen sus propias interfaces. Lo que no parece permitir son los tipos de conexión distintos de Peer, por lo que si desea una configuración Cliente/Servidor, no será de mucha ayuda.

-Ash

0

puede activar mediante programación Blutooth, mediante el uso de la API privada de Apple (creo BluetoothManger.h), pero tenga cuidado, que hará que el rechazo en el empuje de Apple App Store.

-1

Debe usar el mismo sessionID.

+1

¿Qué quieres decir con esto? ¿Por qué? –

0

En segundo lugar, la noción de usar la accesibilidad de Apple. Como beneficio adicional, figura como una de las pautas de envío de la App Store de Apple.

No es tan difícil de implementar ya que la mayor parte del código necesario ya está escrito para usted.

Slf proporcionó un enlace a algún código fuente utilizando la clase Accesibilidad, adicionalmente aquí hay un enlace a Apple Dev's official reachability example.

Sin embargo, asegúrese de que está comprobando la capacidad de conexión de forma asíncrona.

Lo estoy usando en mi aplicación y, aunque no es la mejor solución, al menos notifica al usuario que necesita ajustar la configuración de conexión o que no existe ninguna red.

2

Ahora en iOS 5, esto se puede lograr de este modo:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil]; 
NSMutableArray * discoveredPeripherals = [NSMutableArray new]; 
CBCentralManager * manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 
[manager scanForPeripheralsWithServices:discoveredPeripherals options:options]; 
[manager stopScan]; 

Esto requiere que importe el marco CoreBluetooth en iOS 5. Si Bluetooth está apagado, el sistema mostrará una vista de alerta que se ofrece la opción de activar Bluetooth. De lo contrario, si encuentra un periférico llamará al método de delegado correspondiente, pero si no hay nada en esa implementación, no necesita preocuparse por ello.

Cuestiones relacionadas