2013-08-27 3 views
13

Я пытаюсь отправить файл изображения PNG с одного устройства iOS на другой через Bluetooth 4.0 LE.Отправка файла изображения по Bluetooth 4.0 LE

Я могу использовать простые данные, такие как строки, но неспособные успешно отправлять и использовать файлы изображений.

в периферийном устройстве, я начать с этим

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

Затем я сделать myData значение Характерным в.

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

В центральном аппарате, у меня есть это, когда значение Характерная обновляется

- (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: Я могу отправить через одного цвета 1by1 пикселя .png файл, который имеет размер около 5 600 байт. Я не могу отправить многоцветный 20by20pixel .png файл, который составляет всего около 2000 байт. Я могу отправить более крупный файл, содержащий только один цвет и меньше пикселей, но не могу отправить меньший файл, содержащий много цветов и больше пикселей.

EDIT 8-30-13: Мне определенно нужно разобрать данные на более мелкие куски. В одном из примеров проектов Apple я нашел метод, который делает именно это. Я не могу точно понять, как реализовать это в своем собственном коде, но сейчас я пытаюсь выяснить, как это сделать. Вот код:

- (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; 
    } 
}} 

imageView Мои является черным квадратом, который должен быть отображение изображения я отправляемый через. enter image description here

+0

Вы смогли отправить изображение, используя это? – hmlasnk

ответ

2

BTLE значительно ограничен с точки зрения объема данных, которые могут быть отправлены как в характеристиках, так и в любом пакете данных. Вы должны установить соединение между устройствами, а затем разделить данные изображения и отправить несколько небольших пакетов. Видеоролики WWDC 2013 года предоставят вам хороший обзор и образцы кода.

+0

Спасибо @Wain. Я смотрел видео WWDC 2013 и тщательно просматривал pdf-файл презентации CoreBluetooth. Я также не могу найти примеры проектов, которые иллюстрируют разделение данных (предпочтительные файлы изображений) на куски для отправки через BTLE. – tagabek

+0

На видео показаны контактные данные, разделяемые на пакеты и отправленные. Я думаю, это было второе видео BT. Не изображение, но тот же принцип. – Wain

+0

Я обнаружил, что фрагмент кода разбивает данные, и я все еще пытаюсь понять, как реализовать его в моем проекте. Я отредактировал оригинальный пост. – tagabek

11

На iOS 6 BLE позволяет отправлять около 20 байтовых данных. Для примера того, как вы можете нарезать данные для отправки и как использовать передачу на основе уведомлений, загрузите BTLE Transfer Apple Example application.

Чтобы лучше понять, какие скорости вы можете достичь, я предлагаю вам проанализировать эту диаграмму. http://www.scriptreactor.com/conn_interval-throughput.pdf Он показывает достижимые скорости в зависимости от интервала соединения. iOS не дает вам такого тонкого контроля, но эта информация по-прежнему ценна для вас.

+0

Спасибо за ваш ответ. Я использовал приложение BTLE Transfer Example в качестве основы для функций BTLE моего приложения. Я нашел метод send-data '- (void), и я начинаю понимать, что именно мне нужно делать. Благодарю. – tagabek

+2

@tagabek сделал тот или иной ответ, решив вашу проблему? Если на ваш вопрос будет дан ответ, необходимо принять правильное решение. Вы можете сделать это с помощью галочки в ответе. – allprog

+1

@allprog - есть ли какая-либо новая информация о размере кусков, которые вы можете отправить в iOS7? Я не смог найти нигде документированное ограничение на этот размер ... – Gal