Upload with Buffer iOS 7

I am trying to implement an Upload with random Data and measure the speed. For now i am generating my random NSData like this:

void * bytes = malloc("");
NSData * myData = [NSData dataWithBytes:bytes length:"bytes"];

But there will be Memory Problems if i want to upload a big File...

My Upload process is like this:

NSURLSessionConfiguration *sessionConfig =
[NSURLSessionConfiguration defaultSessionConfiguration];

NSURLSession *session =
[NSURLSession sessionWithConfiguration:sessionConfig

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 the body of the post to the reqeust
[urlRequest setHTTPBody:body];

void * bytes = malloc(250000000);
NSData * uploadData = [NSData dataWithBytes:bytes length:250000000];

ulTask = [session uploadTaskWithRequest:urlRequest fromData:uploadData];

[ulTask resume];

Is there a way to upload with a buffer or something?! like generate small data, upload this and generate a new one and upload again?!


I would suggest just start an upload and just keep sending data. You can also avoid the creation of your 250mb buffer, by using uploadTaskWithStreamedRequest and then create an NSInputStream subclass that just keeps providing more data until you tell it to stop. You can implement URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend: to monitor the progress of your upload (so you can presumably monitor the speed with which data is being sent).

Anyway, to create the upload request:

@interface ViewController () <NSURLSessionDelegate, NSURLSessionTaskDelegate>

@property (nonatomic, strong) CustomStream *inputStream;


@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];

    // I don't know how you want to finish the upload, but I'm just going 
    // to stop it 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 obviously have to implement the 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

- (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];

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
    [self.responseData appendData:data];

And the CustomStream:

static NSInteger const kBufferSize = 32768;

@interface CustomStream : NSInputStream

@property (nonatomic, readonly) NSStreamStatus streamStatus;
@property (nonatomic, getter = isFinished) BOOL finished;


@interface CustomStream ()

@property (nonatomic) NSStreamStatus streamStatus;
@property (nonatomic) void *buffer;


@implementation CustomStream

- (instancetype)init
    self = [super init];
    if (self) {
        _buffer = malloc(kBufferSize);
        NSAssert(_buffer, @"Unable to create buffer");
        memset(_buffer, 0, kBufferSize);
    return self;

- (void)dealloc
    if (_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;


I'd suggest you refer to BJ Homer's article Subclassing NSInputStream for some of the background on a few of the cryptic methods in this NSInputStream subclass.

-(void) updateUserData:(NSDictionary*)data
               success: (void (^) (id responseObject))success
               failure: (void (^)(NSError* error))failure
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"PATCH"
                                                                              constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
                                        [formData appendPartWithFileData:imageToUpload


    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSProgress *progress = nil;

    NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request
                                                              completionHandler:^(NSURLResponse *response, id responseObject, NSError *error)
                                              if (error)
                                                  NSLog(@"Error: %@", error);
                                              } else
                                                  [[NSNotificationCenter defaultCenter] postNotificationName:@"userDataDidUpdated" object:self];

    [uploadTask resume];


Need Your Help

Authentication issue in BLE Bluetooth Low Energy device

android android-bluetooth bluetooth-lowenergy

We are making a IOT device with a BLE interface which uses the HM-11 (http://www.seeedstudio.com/wiki/Bluetooth_V4.0_HM-11_BLE_Module) breakout board hosting the chip CC2541 (http://www.ti.com/prod...