4

I am trying to implement an application that includes downloading files from Dropbox. It looks like there is a simple straightforward framework that does that (CloudRail). But the codes crashes when I try to work with the file downloaded (in this case an image), here is the example:

self.dropboxInstance = [[Dropbox alloc] initWithClientId:self.authDic[@“————“] clientSecret:self.authDic[@“————“]];
  id returnObject = [self.dropboxInstance downloadWithFilePath:@“/pictures/001.png“];

UIImage * image = [UIImage imageWithData:object]; // CRASH HERE

I checked the network and disk activity through Xcode tools and the download is performed correctly, so I believe it has something to do with the return of the download function.

Robert Reiz
  • 4,243
  • 2
  • 30
  • 43

1 Answers1

5

First of all, the return type of the method is an NSInputStream, that can be used to read the contents of the file you downloaded.

The reason why the code is not working is because you are treating it as an NSData type.

So the solution would be to first read all the content from the stream received as return, store it in an NSData object and then create an UIImage from the data.

self.dropboxInstance = [[Dropbox alloc] initWithClientId:self.authDic[@“————“] clientSecret:self.authDic[@“————“]];
  id returnObject = [self.dropboxInstance downloadWithFilePath:@“/pictures/001.png“];

  //NEW CODE
  NSInputStream * inputStream = returnObject;

  [inputStream open];
  NSInteger result;
  uint8_t buffer[1024]; // buffer of 1kB
  while((result = [inputStream read:buffer maxLength:1024]) != 0) {
    if(result > 0) {
      // buffer contains result bytes of data to be handled
      [data appendBytes:buffer length:result];
    } else {
      // The stream had an error. You can get an NSError object using [iStream streamError]
      if (result<0) {
        [NSException raise:@"STREAM_ERROR" format:@"%@", [inputStream streamError]];
      }
    }
  }
  //END NEWCODE

  UIImage * image = [UIImage imageWithData:data]; // NO CRASH ANYMORE :)

The above code is used to read from the stream in a procedural way (will block the thread). To read from the stream asynchronously refer to this other answer (Stream to Get Data - NSInputStream). Hope this helped.

Community
  • 1
  • 1