osx - NSMutableURLRequest and memory issue -


good morning, i'm developing application uploads files; there no real issues, 1 big problem: if try upload 1gb of files allocates 1gb of memory, , can understand not thing.

here's code: allocate data nsdata , use nsmutableurlrequest + nsurlconnection upload them; question is: there ways without needing allocate whole memory? i've searched out, found nothing...

_uploaddatafile nsdata sub-class instance allocated before.

nsmutableurlrequest *request = [[[nsmutableurlrequest alloc] initwithurl:[nsurl urlwithstring:@"http://my.server/page"]                                                             cachepolicy:nsurlrequestreloadignoringcachedata                                                         timeoutinterval:60.0] autorelease];  nsdata *datafile;  if (_uploaddatafile == nil) {     nserror *error = nil;     datafile = [[[nsdata alloc] initwithcontentsoffile:@"pathtofile" options:nsdatareadinguncached error:&error] autorelease];      if (error) {         nslog(@"error %i: %@", [error code], [error localizeddescription]);         [self fermaupload]; //stop upload         return;     } }  else      datafile = [_uploaddatafile file];  nsmutabledictionary *dictpost = [[[nsmutabledictionary alloc] init] autorelease]; [dictpost setvalue:datafile forkey:@"uploads[]"];  nsdata *mutdata = [self dataforpostwithdictionary:dictpost boundary:@"0194784892923" nomefile:[@"pathtofile" lastpathcomponent]];  nsstring *postlength = [nsstring stringwithformat:@"%d", [mutdata length]];  [request sethttpmethod:@"post"]; [request setvalue:postlength forhttpheaderfield:@"content-length"]; [request setvalue:@"multipart/form-data; boundary=0194784892923" forhttpheaderfield:@"content-type"]; [request sethttpbody:mutdata]; [request sethttpshouldhandlecookies:yes];  theconnection = [[nsurlconnection alloc] initwithrequest:request delegate:self]; 

and here's how - (nsdata *)dataforpostwithdictionary:boundary:nomefile: method looks like:

- (nsdata *)dataforpostwithdictionary:(nsdictionary *)adictionary boundary:(nsstring *)aboundary nomefile:(nsstring *)nomefile { nsarray *mydictkeys = [adictionary allkeys]; nsmutabledata *mydata = [nsmutabledata datawithcapacity:1]; nsstring *myboundary = [nsstring stringwithformat:@"--%@\r\n", aboundary];  for(int = 0;i < [mydictkeys count];i++) {     id myvalue = [adictionary valueforkey:[mydictkeys objectatindex:i]];     [mydata appenddata:[myboundary datausingencoding:nsutf8stringencoding]];     //if ([myvalue class] == [nsstring class]) {     if ([myvalue iskindofclass:[nsstring class]]) {         [mydata appenddata:[[nsstring stringwithformat:@"content-disposition: form-data; name=\"%@\"\r\n\r\n", [mydictkeys objectatindex:i]] datausingencoding:nsutf8stringencoding]];         [mydata appenddata:[[nsstring stringwithformat:@"%@", myvalue] datausingencoding:nsutf8stringencoding]];     } else if(([myvalue iskindofclass:[nsurl class]]) && ([myvalue isfileurl])) {         [mydata appenddata:[[nsstring stringwithformat:@"content-disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", [mydictkeys objectatindex:i], [[myvalue path] lastpathcomponent]] datausingencoding:nsutf8stringencoding]];         [mydata appenddata:[[nsstring stringwithformat:@"content-type: application/octet-stream\r\n\r\n"] datausingencoding:nsutf8stringencoding]];         [mydata appenddata:[nsdata datawithcontentsoffile:[myvalue path]]];     } else if(([myvalue iskindofclass:[nsdata class]])) {         [mydata appenddata:[[nsstring stringwithformat:@"content-disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", [mydictkeys objectatindex:i], nomefile] datausingencoding:nsutf8stringencoding]];         [mydata appenddata:[[nsstring stringwithformat:@"content-type: application/octet-stream\r\n\r\n"] datausingencoding:nsutf8stringencoding]];         [mydata appenddata:myvalue];     } // eof if()      [mydata appenddata:[[nsstring stringwithstring:@"\r\n"] datausingencoding:nsutf8stringencoding]]; } // eof for() [mydata appenddata:[[nsstring stringwithformat:@"--%@--\r\n", aboundary] datausingencoding:nsutf8stringencoding]];  return mydata; } // eof dataforpostwithdictionary:boundary: 

thank , sorry english.

a interesting problem! there 2 ways of feeding body data nsurlconnection/request:

  • nsdata
  • nsinputstream

unfortunately, neither want out of box, since want upload file + form data. ideally, subclass nsinputstream provide data formatted require. however, last time checked, nsurlconnection unable handle such subclasses. instead, like:

  1. create pair of streams using cfstreamcreateboundpair(). returns cfwritestream , cfreadstream, toll-free bridged nsoutputstream , nsinputstream, respectively
  2. set output stream's delegate
  3. -sethttpbodystream: on url request input stream
  4. start connection

the output stream's delegate should called periodically, requesting data. need feed in post data, followed chunks of file data. entire file never entirely in memory @ once.


Comments

Popular posts from this blog

objective c - Change font of selected text in UITextView -

php - Accessing POST data in Facebook cavas app -

c# - Getting control value when switching a view as part of a multiview -