Подтвердить что ты не робот

Отправка файла изображения через Bluetooth 4.0 LE

Я пытаюсь отправить файл изображения .png с одного устройства iOS на другое через 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 }

РЕДАКТИРОВАТЬ 8-27-13: Я могу отправить файл с одним пиксельным размером 1by1 пикселя .png, который имеет размер около 5 600 байт. Я не могу отправить многоцветный 20by20pixel.png файл, который составляет всего около 2000 байт. Я могу отправить более крупный файл, содержащий только один цвет и меньше пикселей, но не могу отправить меньший файл, содержащий много цветов и больше пикселей.

РЕДАКТИРОВАТЬ 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 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;
    }
}}

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

4b9b3361

Ответ 1

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

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

Ответ 2

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