title: Sending image file over Bluetooth 4.0 LE
body: <p>I am trying to send an .png image file from one iOS Device to another over Bluetooth 4.0 LE.</p>
  
  <p>I am able to simple pieces of data like strings, but unable to successfully send and utilize image files.</p>
  
  <p><strong>In the Peripheral device, I start out with this</strong></p>
  
  <pre><code>pictureBeforeData = [UIImage imageNamed:@"myImage.png"];
  NSData *myData = UIImagePNGRepresentation(pictureBeforeData);
  </code></pre>
  
  <p>Then I make <code>myData</code> a characteristic's value. </p>
  
  <pre><code>_myCharacteristic =
  [[CBMutableCharacteristic alloc] initWithType:_myCharacteristicUUID
                                     properties:CBCharacteristicPropertyRead
                                          value:myData
                                    permissions:CBAttributePermissionsReadable];
  </code></pre>
  
  <p><strong>In the Central Device, I have this when the characteristic's value is updated</strong></p>
  
  <pre><code>- (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 }
  </code></pre>
  
  <p><strong>EDIT 8-27-13:</strong> I am able to send over a single color 1by1 pixel .png file successfully that file is about 5,600 bytes large. I am unable to send a multi-color 20by20pixel .png file that is only about 2,000 bytes. I am able to send over the larger file that contains only one color and less pixels, but unable to send the smaller file that contains many colors and more pixels.</p>
  
  <p><strong>EDIT 8-30-13:</strong> I definitely have to parse the data into smaller chunks. In one of Apple's example projects, I found a method that does just that. I can't seem to understand exactly how to implement this in my own code, but I am currently attempting to figure out how. Here's the code:</p>
  
  <pre><code>- (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 &gt;= 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 &gt; 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 &gt;= 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;
      }
  }}
  </code></pre>
  
  <p>My <code>imageView</code> is the black square, which should be displaying the image I have sent over.
  <img src="https://i.stack.imgur.com/IIQK9.png" alt="enter image description here"></p>