2013-08-27 11 views
13

Sto tentando di inviare un file di immagine .png da un dispositivo iOS a un altro tramite Bluetooth 4.0 LE.Invio di file di immagine tramite Bluetooth 4.0 LE

Sono in grado di eseguire semplici dati come stringhe, ma non riesco a inviare e utilizzare correttamente i file di immagine.

Nel dispositivo periferico, comincio con questo

pictureBeforeData = [UIImage imageNamed:@"myImage.png"]; 
NSData *myData = UIImagePNGRepresentation(pictureBeforeData); 

Poi faccio myData il valore di una caratteristica.

_myCharacteristic = 
[[CBMutableCharacteristic alloc] initWithType:_myCharacteristicUUID 
            properties:CBCharacteristicPropertyRead 
             value:myData 
            permissions:CBAttributePermissionsReadable]; 

In Device Central, ho questo quando il valore del caratteristico viene aggiornato

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { 
    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:_myCharacteristicUUID]]) { 
    NSLog(@"PICTURE CHARACTERISTIC FOUND"); // This successfully gets logged 

    NSData *dataFromCharacteristic = [[NSData alloc] initWithData:characteristic.value]; 

    UIImage *imageFromData = [[UIImage alloc]initWithData:dataFromCharacteristic]; 

    // This correctly logs the size of my image 
    NSLog(@"SIZE: %f, %f", imageFromData.size.height, imageFromData.size.width); 

    // This causes the imageView to turn completely black 
    _sentPictureImageView.image = imageFromData; 

    if (!([_myImagesArray containsObject:imageFromData])) 
    { 
     NSLog(@"DOES NOT CONTAIN"); // This is successfully logged 
     [_myImagesArray addObject:imageFromData]; // This runs but is apparently not adding the image to the array 
    } 

    NSLog(@"COUNT: %u", _contactsImagesArray.count); // This always logs 0 - The array is empty } 

EDIT 8-27-13: sono in grado di inviare più di un 1by1 pixel unico colore File .png con successo che il file è di circa 5.600 byte di grandi dimensioni. Non riesco a inviare un file .png multicolore a 20by20pixel che è solo di circa 2000 byte. Sono in grado di inviare il file più grande che contiene solo un colore e meno pixel, ma non è in grado di inviare il file più piccolo che contiene molti colori e più pixel.

MODIFICA 8-30-13: Devo assolutamente analizzare i dati in blocchi più piccoli. In uno dei progetti di esempio di Apple, ho trovato un metodo che fa proprio questo. Non riesco a capire esattamente come implementarlo nel mio codice, ma al momento sto cercando di capire come. Ecco il codice:

- (void)sendData { 
// First up, check if we're meant to be sending an EOM 
static BOOL sendingEOM = NO; 

if (sendingEOM) { 

    // send it 
    BOOL didSend = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; 

    // Did it send? 
    if (didSend) { 

     // It did, so mark it as sent 
     sendingEOM = NO; 

     NSLog(@"Sent: EOM"); 
    } 

    // It didn't send, so we'll exit and wait for peripheralManagerIsReadyToUpdateSubscribers to call sendData again 
    return; 
} 

// We're not sending an EOM, so we're sending data 

// Is there any left to send? 

if (self.sendDataIndex >= self.dataToSend.length) { 

    // No data left. Do nothing 
    return; 
} 

// There's data left, so send until the callback fails, or we're done. 

BOOL didSend = YES; 

while (didSend) { 

    // Make the next chunk 

    // Work out how big it should be 
    NSInteger amountToSend = self.dataToSend.length - self.sendDataIndex; 

    // Can't be longer than 20 bytes 
    if (amountToSend > NOTIFY_MTU) amountToSend = NOTIFY_MTU; 

    // Copy out the data we want 
    NSData *chunk = [NSData dataWithBytes:self.dataToSend.bytes+self.sendDataIndex length:amountToSend]; 

    // Send it 
    didSend = [self.peripheralManager updateValue:chunk forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; 

    // If it didn't work, drop out and wait for the callback 
    if (!didSend) { 
     return; 
    } 

    NSString *stringFromData = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding]; 
    NSLog(@"Sent: %@", stringFromData); 

    // It did send, so update our index 
    self.sendDataIndex += amountToSend; 

    // Was it the last one? 
    if (self.sendDataIndex >= self.dataToSend.length) { 

     // It was - send an EOM 

     // Set this so if the send fails, we'll send it next time 
     sendingEOM = YES; 

     // Send it 
     BOOL eomSent = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; 

     if (eomSent) { 
      // It sent, we're all done 
      sendingEOM = NO; 

      NSLog(@"Sent: EOM"); 
     } 

     return; 
    } 
}} 

mio imageView è il quadrato nero, che dovrebbe essere la visualizzazione dell'immagine ho inviato sopra. enter image description here

+0

Sei riuscito a inviare un'immagine utilizzando questo? – hmlasnk

risposta

2

BTLE è significativamente limitato in termini di quantità di dati che è possibile inviare sia nelle caratteristiche che in qualsiasi pacchetto di dati. È necessario effettuare la connessione tra i dispositivi e quindi suddividere i dati dell'immagine e inviare più piccoli pacchetti. I video del WWDC del 2013 ti forniranno una buona panoramica e esempi di codice.

+0

Grazie a @Wain. Ho guardato i video del WWDC 2013 e ho scansionato a fondo il pdf della presentazione di CoreBluetooth. Inoltre, non riesco a trovare progetti di esempio che esemplificino la suddivisione dei dati (file di immagine preferibili) in blocchi da inviare su BTLE. – tagabek

+0

Il video mostra i dati di contatto che vengono suddivisi in pacchetti e inviati. Penso che sia stato il secondo video di BT. Non un'immagine ma si applica lo stesso principio. – Wain

+0

Ho trovato uno snippet di codice che suddivide i dati e sto ancora cercando di capire come implementarlo nel mio progetto. Ho modificato il post originale. – tagabek

11

Su iOS 6, BLE consente di inviare circa 20 byte di blocchi di dati. Per un esempio di come è possibile suddividere i dati da inviare e come utilizzare la trasmissione basata su notifiche, scaricare BTLE Transfer Apple Example application.

Per una migliore comprensione di quali velocità è possibile ottenere, suggerisco di analizzare questo schema http://www.scriptreactor.com/conn_interval-throughput.pdf Mostra le velocità ottenibili in funzione dell'intervallo di connessione. iOS non ti dà un controllo così dettagliato, ma questa informazione è ancora preziosa per te da calcolare.

+0

Grazie per la risposta. Ho usato l'applicazione BTLE Transfer Example come base per la funzionalità BTLE della mia app. Ho trovato il metodo '- (void) sendData' e sto iniziando a capire cosa esattamente devo fare. Grazie. – tagabek

+2

@tagabek ha fatto questa o l'altra risposta per risolvere il tuo problema? Se la tua domanda ha una risposta, la soluzione corretta dovrebbe essere accettata. Puoi farlo con il segno di spunta alla risposta. – allprog

+1

@allprog - ci sono nuove informazioni sulla dimensione dei blocchi che puoi inviare in iOS7? Non sono riuscito a trovare da nessuna parte una limitazione documentata a queste dimensioni ... – Gal

Problemi correlati