Ci sono due modi per farlo.
Il primo modo utilizza l'API GameKit. Si inizia con due classi separate, una che implementa il protocollo GKSessionDelegate
e funge da "gestore" di GameKit/Bluetooth e l'altra come interfaccia utente della presentazione (molto probabilmente una sorta di viewcontroller con una vista tabella). Il modo in cui lo collegheresti è che il gestore gestisce le notifiche di GameKit, ecc. Quindi chiama i metodi delegati sull'interfaccia utente per aggiornare la vista tabella quando un peer si connette/scende, ecc. In questo modo, quando i dispositivi vanno e vengono, l'elenco di selezione dovrebbe aggiornare per mostrare chi c'è in giro.
Di seguito è riportato un codice per iniziare:
- (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);
}
Il secondo modo per farlo è quello di utilizzare meccanismi di selezione del servizio standard di Bonjour. GameKit è implementato su Bonjour (ma tramite Bluetooth anziché WiFi), quindi una volta che le due parti hanno raggiunto la raggiungibilità della rete tra loro e connesse, sono registrate sotto Bonjour e si comportano come farebbe qualsiasi servizio Bonjour. Il modo GameKit è probabilmente un po 'più semplice, ma se hai già il codice per il WiFi puoi riutilizzarlo anche per il Bluetooth.
Ehi, grazie mille per questo modello da cui partire. Un'altra domanda, posso vedere come la sessione: peer: il metodo didChangeState sarebbe andato nel file delegate.h/.m, ma per quanto riguarda gli altri metodi? StartPeer e stopPeer andrebbero nei miei file viewcontroller.h/.m o l'intero modello andrà nel file delegato? –
In questo caso, si presume che tutti questi siano nel gestore delegato poiché si occupano del sottostante impianto idraulico GameKit. Non c'è motivo per cui non puoi mettere tutto dentro il viewcontroller ma è una buona idea mantenere il codice UI disgiunto dal codice di rete.Dopo aver aggiornato l'array di peer, l'oggetto 'handler' richiama il proprio metodo delegato personalizzato "peerListChanged" che notifica al viewcontroller che l'elenco è stato modificato in modo che possa richiedere una ricarica della tabella e mostrare il nuovo elenco all'utente. – Ramin
Funziona solo su Wi-Fi o troverà anche peer tramite Bluetooth? Devi usare il peer picker per usare bluetooth? – typeoneerror