1

I am using the following code to convert nsdata to bytearray. It works fine in simulator. On device, it allocates memory like crazy to 600 MB [on the 'addobject' line inside the loop] and crashes. The file size I am reading is 30 MB. The error I see in output windows is "memory issue". The file is a "zip" file

NSData *data = [[NSData alloc] initWithContentsOfFile:file];
const unsigned char *bytes = [data bytes];
NSUInteger length = [data length];
NSMutableArray *byteArray = [NSMutableArray array];
for (NSUInteger i = 0; i < length; i++) {
@autoreleasepool {
         [byteArray addObject:[NSNumber numberWithUnsignedChar:bytes[i]]];                                                  }
       }

I am using this bytearray inside a NSDictionary and do a "dataWithJSONObject" on the dictionary to post the json to a REST web service.

teeboy
  • 408
  • 3
  • 13

1 Answers1

0

For a more memory efficient way to convert NSData to byte array, see How to convert NSData to byte array in iPhone?

If your goal is ultimately to post the binary data to a web service in JSON, try the following:

  1. Base64-encode the the data in a String, as described here. This can be passed in the JSON Body.
  2. Alternatively, if you have flexibility on changing the server-side of this transfer, avoid base64-encoded data in a JSON and rather directly post the binary content using an HTTP POST or PUT. This will be more efficient.

For the second approach, I can think of two ways to do this:

  • Here is an example for the scenario of sending an image, but any file type will work so long as you can load it into an NSData object.

  • Or, something like this should work

    NSData *data = [NSData dataWithContentsOfFile:file];
    NSURL *url = [NSURL URLWithString:@"your_url_here"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"PUT"];
    NSDictionary *headers = @{@"Content-Type": @"application/octet-stream"};
    [request setAllHTTPHeaderFields:headers];
    [request setHTTPBody:data]
    // Use an URLSession object task to execute the request
    

Lastly, if the data can be compressed on the client before encoding and sending, that would be even better!

I hope you find this helpful.

kevdoran
  • 703
  • 4
  • 11
  • Thank you Kevdoran. Your 2nd option worked perfectly. Changed server API to accept httppost. – teeboy Jul 24 '17 at 15:01