iphone - Upload with Buffer iOS 7 -


i trying implement upload random data , measure speed. generating random nsdata this:

void * bytes = malloc(""); nsdata * mydata = [nsdata datawithbytes:bytes length:"bytes"]; free("bytes"); 

but there memory problems if want upload big file...

my upload process this:

nsurlsessionconfiguration *sessionconfig = [nsurlsessionconfiguration defaultsessionconfiguration];  nsurlsession *session = [nsurlsession sessionwithconfiguration:sessionconfig                               delegate:self                          delegatequeue:nil];  nsurl * urll = [nsurl urlwithstring:upload_server]; nsmutableurlrequest * urlrequest = [nsmutableurlrequest requestwithurl:urll]; [urlrequest sethttpmethod:@"post"]; [urlrequest addvalue:@"keep-alive" forhttpheaderfield:@"connection"];  nsstring *boundary = @"*****"; nsstring *contenttype = [nsstring stringwithformat:@"multipart/form-data; boundary=%@",boundary]; [urlrequest addvalue:contenttype forhttpheaderfield: @"content-type"];  nsmutabledata *body = [nsmutabledata data]; [body appenddata:[[nsstring stringwithformat:@"\r\n--%@\r\n",boundary] datausingencoding:nsutf8stringencoding]]; [body appenddata:[@"content-type: application/octet-stream\r\n\r\n" datausingencoding:nsutf8stringencoding]]; [body appenddata:[[nsstring stringwithformat:@"\r\n--%@--\r\n",boundary] datausingencoding:nsutf8stringencoding]]; // setting body of post reqeust [urlrequest sethttpbody:body];  void * bytes = malloc(250000000); nsdata * uploaddata = [nsdata datawithbytes:bytes length:250000000]; free(bytes);  ultask = [session uploadtaskwithrequest:urlrequest fromdata:uploaddata];  [ultask resume]; 

is there way upload buffer or something?! generate small data, upload , generate new 1 , upload again?!

i suggest start upload , keep sending data. can avoid creation of 250mb buffer, using uploadtaskwithstreamedrequest , create nsinputstream subclass keeps providing more data until tell stop. can implement urlsession:task:didsendbodydata:totalbytessent:totalbytesexpectedtosend: monitor progress of upload (so can presumably monitor speed data being sent).

anyway, create upload request:

@interface viewcontroller () <nsurlsessiondelegate, nsurlsessiontaskdelegate>  @property (nonatomic, strong) customstream *inputstream;  @end  @implementation viewcontroller  - (void)viewdidload {     [super viewdidload];      self.inputstream = [[customstream alloc] init];      nsurl *url = [nsurl urlwithstring:kurlstring];     nsmutableurlrequest *request = [nsmutableurlrequest requestwithurl:url];     [request sethttpmethod:@"post"];      nsurlsessionconfiguration *configuration = [nsurlsessionconfiguration defaultsessionconfiguration];     nsurlsession *session = [nsurlsession sessionwithconfiguration:configuration delegate:self delegatequeue:nil];      nsurlsessionuploadtask *task = [session uploadtaskwithstreamedrequest:request];      [task resume];      // don't know how want finish upload, i'm going      // stop after 10 seconds      dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(10.0 * nsec_per_sec)), dispatch_get_main_queue(), ^{         self.inputstream.finished = yes;     }); } 

you have implement appropriate delegate methods:

#pragma mark - nsurlsessiontaskdelegate  - (void)urlsession:(nsurlsession *)session task:(nsurlsessiontask *)task didsendbodydata:(int64_t)bytessent totalbytessent:(int64_t)totalbytessent totalbytesexpectedtosend:(int64_t)totalbytesexpectedtosend {     nslog(@"%lld %lld %lld", bytessent, totalbytessent, totalbytesexpectedtosend); }  - (void)urlsession:(nsurlsession *)session task:(nsurlsessiontask *)task neednewbodystream:(void (^)(nsinputstream *bodystream))completionhandler {     completionhandler(self.inputstream); }  - (void)urlsession:(nsurlsession *)session task:(nsurlsessiontask *)task didcompletewitherror:(nserror *)error {     nslog(@"%s: error = %@; data = %@", __pretty_function__, error, [[nsstring alloc] initwithdata:self.responsedata encoding:nsutf8stringencoding]); }  #pragma mark - nsurlsessiondatadelegate  - (void)urlsession:(nsurlsession *)session datatask:(nsurlsessiondatatask *)datatask didreceiveresponse:(nsurlresponse *)response completionhandler:(void (^)(nsurlsessionresponsedisposition disposition))completionhandler {     self.responsedata = [nsmutabledata data];     completionhandler(nsurlsessionresponseallow); }  - (void)urlsession:(nsurlsession *)session datatask:(nsurlsessiondatatask *)datatask didreceivedata:(nsdata *)data {     [self.responsedata appenddata:data]; } 

and customstream:

static nsinteger const kbuffersize = 32768;  @interface customstream : nsinputstream  @property (nonatomic, readonly) nsstreamstatus streamstatus; @property (nonatomic, getter = isfinished) bool finished;  @end  @interface customstream ()  @property (nonatomic) nsstreamstatus streamstatus; @property (nonatomic) void *buffer;  @end  @implementation customstream  - (instancetype)init {     self = [super init];     if (self) {         _buffer = malloc(kbuffersize);         nsassert(_buffer, @"unable create buffer");         memset(_buffer, 0, kbuffersize);     }     return self; }  - (void)dealloc {     if (_buffer) {         free(_buffer);         self.buffer = null;     } }  - (void)open {     self.streamstatus = nsstreamstatusopen; }  - (void)close {     self.streamstatus = nsstreamstatusclosed; }  - (nsinteger)read:(uint8_t *)buffer maxlength:(nsuinteger)len {     if ([self isfinished]) {         if (self.streamstatus == nsstreamstatusopen) {             self.streamstatus = nsstreamstatusatend;         }         return 0;     }      nsuinteger bytestocopy = min(len, kbuffersize);     memcpy(buffer, _buffer, bytestocopy);      return bytestocopy; }  - (bool)getbuffer:(uint8_t **)buffer length:(nsuinteger *)len {     return no; }  - (bool)hasbytesavailable {     return self.streamstatus == nsstreamstatusopen; }  - (void)scheduleinrunloop:(__unused nsrunloop *)arunloop                   formode:(__unused nsstring *)mode {}  - (void)removefromrunloop:(__unused nsrunloop *)arunloop                   formode:(__unused nsstring *)mode {}  #pragma mark undocumented cfreadstream bridged methods  - (void)_scheduleincfrunloop:(__unused cfrunloopref)arunloop                      formode:(__unused cfstringref)amode {}  - (void)_unschedulefromcfrunloop:(__unused cfrunloopref)arunloop                          formode:(__unused cfstringref)amode {}  - (bool)_setcfclientflags:(__unused cfoptionflags)inflags                  callback:(__unused cfreadstreamclientcallback)incallback                   context:(__unused cfstreamclientcontext *)incontext {     return no; }  @end 

i'd suggest refer bj homer's article subclassing nsinputstream of background on few of cryptic methods in nsinputstream subclass.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -