Questo tutorial di iOS ti insegnerà come stabilire una connessione Bluetooth tra due dispositivi iOS utilizzando il GKPeerPickerController
, GKPeerPickerControllerDelegate
, GKSession
, e GKSessionDelegate
classi. Vedremo anche come inviare dati avanti e indietro attraverso la connessione creando una semplice app di messaggistica di testo.
Avvia Xcode e fai clic File> Nuovo> Progetto. Fai clic su "Applicazione" sotto il pannello iOS sulla sinistra. Fare clic sull'icona "Single View Application" e fare clic su "Avanti".
Nel campo "Nome prodotto", digita "BluetoothTextMessenger" e inserisci un nome per l'identificatore della tua azienda, come "com.mobiletuts". Scegli "iPhone" dal menu "Famiglia di dispositivi". Deseleziona "Usa storyboard" e "Includi test unitari", quindi seleziona "Utilizza il conteggio dei riferimenti automatici". Fai clic su "Avanti", scegli una posizione per salvare il progetto, quindi fai clic su "Crea".
Iniziamo dichiarando e definendo i metodi per connettersi a un dispositivo e inviare dati. Nel file "ViewController.m", aggiungi il seguente codice:
@interface ViewController () - (void) sendMessage: (id) mittente; - (void) connectToDevice: (id) mittente; @end - (void) connectToDevice: (id) sender - (void) sendMessage: (id) sender
Creiamo due pulsanti, un'etichetta e un campo di testo per il nostro messenger di testo. Fare clic sul file "ViewController.h" e aggiungere il seguente codice:
@property (strong, nonatomic) UILabel * messageReceivedLabel; @property (strong, nonatomic) UITextField * messageToSendTextField; @property (strong, nonatomic) sessione di GKSession *; @property (strong, nonatomic) UIButton * sendButton;
Fare clic sul file "ViewController.m" e aggiungere il seguente codice per completare le proprietà.
@synthesize messageReceivedLabel = _messageReceivedLabel; @synthesize messageToSendTextField = _messageToSendTextField; @synthesize session = _session; @synthesize sendButton = _sendButton;
Mentre si trova ancora nel file "ViewController.m", aggiungere il codice seguente per creare l'interfaccia a livello di codice:
// Pulsante per connettersi all'altro dispositivo UIButton * connectButton = [Pulsante UIButtonWithType: UIButtonTypeRoundedRect]; connectButton.frame = CGRectMake (20.0f, 20.0f, 80.0f, 40.0f); [connectButton setTitle: @ "Connect" forState: UIControlStateNormal]; connectButton.tintColor = [UIColor darkGrayColor]; [connectButton addTarget: self action: @selector (connectToDevice :) forControlEvents: UIControlEventTouchUpInside]; [self.view addSubview: connectButton]; // Pulsante per inviare un messaggio all'altro dispositivo UIButton * sendButton_ = [Pulsante UIButtonWithType: UIButtonTypeRoundedRect]; sendButton_.frame = CGRectMake (220.0f, 20.0f, 80.0f, 40.0f); [sendButton_ setTitle: @ "Invia" forState: UIControlStateNormal]; sendButton_.tintColor = [UIColor darkGrayColor]; sendButton_.enabled = NO; [sendButton_ addTarget: self action: @selector (sendMessage :) forControlEvents: UIControlEventTouchUpInside]; self.sendButton = sendButton_; [self.view addSubview: self.sendButton]; // Etichetta per il messaggio ricevuto self.messageReceivedLabel = nil; Messaggio CGRectReceivedLabel_Frame = CGRectMake (20.0f, 80.0f, 280.0f, 44.0f); UILabel * messageReceivedLabel_ = [[UILabel alloc] initWithFrame: messageReceivedLabel_Frame]; messageReceivedLabel_.textAlignment = UITextAlignmentCenter; messageReceivedLabel_.font = [UIFont boldSystemFontOfSize: 20.0f]; self.messageReceivedLabel = messageReceivedLabel_; [self.view addSubview: self.messageReceivedLabel]; // Campo di testo per inserire il messaggio per inviare il messaggio CGRectToSendTextField_Frame = CGRectMake (20.0f, 144.0f, 280.0f, 44.0f); UITextField * messageToSendTextField_ = [[UITextField alloc] initWithFrame: messageToSendTextField_Frame]; messageToSendTextField_.font = [UIFont systemFontOfSize: 20.0f]; messageToSendTextField_.backgroundColor = [UIColor whiteColor]; messageToSendTextField_.clearButtonMode = UITextFieldViewModeAlways; messageToSendTextField_.placeholder = @ "Inserisci un messaggio da inviare"; messageToSendTextField_.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; self.messageToSendTextField = messageToSendTextField_; [self.view addSubview: self.messageToSendTextField];
I due pulsanti avviano la connessione e inviano un messaggio di testo, mentre il campo di testo contiene il messaggio in uscita e l'etichetta visualizza il messaggio in arrivo.
GameKit fornisce un modo semplice per connettersi tramite Bluetooth. utilizzando GKPeerPickerControllerDelegate
e GKSessionDelegate
, le complessità della connessione, come le finestre per mostrare le connessioni e chi è nelle vicinanze, sono gestite automaticamente dal delegato. Inizia con l'importazione del framework "GameKit". Fai clic sulla destinazione dell'app, il file Xcode elencato nella parte superiore del riquadro a sinistra. Scorri fino al riquadro "Strutture e librerie collegate". Fai clic sul pulsante più e digita "GameKit". Fare clic su "GameKit.framework" e quindi fare clic su "Aggiungi".
Fare clic sul file "ViewController.h" e modificare il seguente codice per conformarsi a GKSessionDelegate
e GKPeerPickerControllerDelegate
protocolli.
@interface ViewController: UIViewController
Le due classi svolgono ciascuna compiti diversi relativi a una connessione. GKPeerPickerController
fornisce un'interfaccia per stabilire la connessione tra due dispositivi, quindi fornisce a GKSession
oggetto come risultato della connessione. Il GKSession
oggetto gestisce quindi la connessione e tutti i dati passati a seconda di come è configurata la tua app.
Aggiungiamo la logica nell'ordine in cui si verifica. Innanzitutto, creeremo una connessione usando GKPeerPickerController
. Torna al metodo precedentemente definito connectToDevice:
e aggiungere la seguente logica all'interno delle parentesi graffe per tentare di connettersi a un dispositivo quando si tocca il pulsante di connessione.
if (self.session == nil) // crea il peer picker e mostra il selettore delle connessioni GKPeerPickerController * peerPicker = [[GKPeerPickerController alloc] init]; peerPicker.delegate = self; peerPicker.connectionTypesMask = GKPeerPickerConnectionTypeNearby; [show peerPicker];
Nel codice sopra, controlliamo per assicurarci che non ci sia una sessione, il che significa che il dispositivo non è connesso. Se non ci sono sessioni, a GKPeerPickerController
è creato e il ViewController
è assegnato come delegato in modo che possa implementare il GKPeerPickerControllerDelegate
metodi. Infine, il GKPeerPickerController
viene visualizzato sullo schermo con un elenco delle connessioni Bluetooth disponibili nelle vicinanze.
GKSession
OggettoUna volta il peerPicker
viene mostrato, viene chiamata una serie di metodi delegati che gestiscono la connessione. Mentre sei ancora nel file "ViewController.m", aggiungi il seguente codice:
- (GKSession *) peerPickerController: (GKPeerPickerController *) picker sessionForConnectionType: (GKPeerPickerConnectionType) type // Crea ID per sessione NSString * sessionIDString = @ "MTBluetoothSessionID"; // crea l'oggetto GKSession GKSession * session = [[GKSession alloc] initWithSessionID: sessionIDString displayName: nil sessionMode: GKSessionModePeer]; sessione di ritorno;
Questo metodo delegato ottiene una sessione in base al tipo di connessione specificato. In questo caso, GKSessionModePeer
è usato perché vogliamo cercare dispositivi di connessione come un client e pubblicizzare la connessione come un server. Il sessionID
è necessario identificare la sessione e può essere qualsiasi valore adatto alle tue esigenze. Il ritorno GKSession
usa il sessionID
come identificativo, e nuovi peer possono usare l'identificatore per connettersi allo stesso GKSession
.
Successivamente, ti consigliamo di implementare peerPickerController: didConnectPeer: toSession:
per prendere il controllo della sessione e respingere il selezionatore. Digitare il seguente codice nel file "ViewController.m".
- (void) peerPickerController: (GKPeerPickerController *) selettore didConnectPeer: (NSString *) peerID toSession: (GKSession *) session // imposta il delegato della sessione e chiude il selettore session.delegate = self; self.session = session; picker.delegate = nil; [picker respingere];
Il delegato della sessione è impostato su se stesso
In modo che la ViewController
può implementare il GKSessionDelegate
metodi. Poi il ViewController
viene rimosso come delegato del raccoglitore e il selettore viene rimosso poiché non è più necessario.
ViewController
ricevere datiImpostare l'oggetto ViewController per ricevere dati dai suoi pari aggiungendo il seguente codice.
- (vuoto) sessione: (GKSession *) sessione peer: (NSString *) peerID didChangeState: (GKPeerConnectionState) stato if (stato == GKPeerStateConnected) [sessione setDataReceiveHandler: self withContext: nil]; // imposta ViewController per ricevere i dati self.sendButton.enabled = YES; // abilita il pulsante send quando la sessione è connessa else self.sendButton.enabled = NO; // disabilita il pulsante send se la sessione è disconnessa self.session.delegate = nil; self.session = nil; // consente alla sessione di riconnettersi se viene disconnessa
Ogni volta che cambia lo stato della connessione, viene chiamato questo metodo delegato. Nel codice, controlliamo se la sessione è connessa e, se lo è, ViewController è impostato per gestire i dati ricevuti dai peer connessi alla sessione. Se la sessione non è connessa, il delegato e la sessione sono impostati su zero per poter stabilire un'altra connessione.
Per inviare il contenuto del campo di testo al dispositivo che è connesso, tornare al metodo precedentemente definito invia messaggio:
e aggiungi il seguente codice all'interno delle parentesi.
// pacchetto testo del campo di testo come oggetto NSData NSData * textData = [self.messageToSendTextField.text dataUsingEncoding: NSASCIIStringEncoding]; // invia i dati a tutti i dispositivi connessi [self.session sendDataToAllPeers: textData withDataMode: GKSendDataReliable error: nil];
La prima riga racchiude il testo del campo di testo come un NSData
oggetto in modo che possa essere inviato tramite Bluetooth. La seconda riga indica alla sessione di inviare i dati a tutti i peer connessi alla sessione.
I dati ricevuti da un peer si presentano sotto forma di un NSData
oggetto. Per decomprimere il testo, aggiungi il seguente codice:
- (void) receiveData: (NSData *) data fromPeer: (NSString *) peer inSession: (GKSession *) contesto di sessione: (void *) context // decomprime NSData in NSString e imposta il testo in entrata come testo dell'etichetta NSString * receivedString = [ [NSString alloc] initWithData: data encoding: NSASCIIStringEncoding]; self.messageReceivedLabel.text = receivedString;
La prima riga di codice in questo metodo decomprime il file NSData
oggetto, restituendo un NSString
oggetto. Successivamente la proprietà text dell'etichetta viene impostata come stringa in entrata.
Collega un dispositivo al tuo computer. Clic Prodotto> Esegui, o la freccia Esegui nell'angolo in alto a sinistra, per costruire ed eseguire l'app su un dispositivo. Una volta che l'app è in esecuzione su un dispositivo, scollegalo e collega un secondo dispositivo al computer. Costruisci ed esegui l'app anche su questo dispositivo. Avvia l'app su entrambi i dispositivi. Tocca il pulsante Connetti su entrambi i dispositivi e segui le istruzioni per connettere i tuoi dispositivi. Digita un messaggio e tocca "Invia" per vederlo visualizzato sull'altro dispositivo.
Una cosa da tenere a mente è che una connessione Bluetooth è progettata per inviare piccoli bit di dati, come testo o set di numeri. Se stai pianificando di inviare qualcosa di grande come una foto, probabilmente vorrai utilizzare il Wi-Fi o una connessione Internet. Anche se questa app probabilmente non ti lascerà cadere il tuo messenger di testo preferito, mostrerà come collegare e inviare bit di dati tramite Bluetooth, una comoda funzionalità per qualsiasi app che potrebbe beneficiare della condivisione di piccoli blocchi di dati tra dispositivi.