Search code examples
iosobjective-ccocoaonedrive

How to send PUT request with HTTP HEADERS and a FILE with Objective-C?


I am a newbie to Objective-C and please let me elaborate what I am doing...

I am trying to upload a file to OneDrive using PUT request.

PUT request must contain

Http Headers

One Drive Documentation

content-length 7919

content-range bytes 0-7918/7919

and with these headers a file will be uploaded

PUT https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337
Content-Length: 7919
Content-Range: bytes 0-7918/7919

<bytes 0-7918 of the file>

Given below are the screen shots of whole PUT request using Chrome POSTMAN

I am trying to make a PUT request with given below headers:

enter image description here

and a file

enter image description here

Could you please guide me how can I do the above using Objective-C

PROBLEM

Everything is working fine with POSTMAN but when I am trying to do it with Objective-C, the file is not getting uploaded and I am getting the given below result:

{"error":{"code":"invalidRequest","message":"Declared fragment length does not match the provided number of bytes"}}

Objective C code

-(void)uploadFile:(NSString*)uploadUrl
{
    NSString *urlString = uploadUrl;

    NSData* file =  [NSData dataWithContentsOfFile: [@"/Users/username/Desktop/s.sql" stringByExpandingTildeInPath]];

    NSString* fileName = @"s.sql";


//

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"PUT"];


    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    [request addValue:@"7919" forHTTPHeaderField: @"Content-Length"];
    [request addValue:@"bytes 0-7918/7919" forHTTPHeaderField: @"Content-Range"];


    NSMutableData *putData = [NSMutableData data];
    [putData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    // Append the file
    [putData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [putData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"fileupload\"; filename=\"%@\"\r\n", fileName]dataUsingEncoding:NSUTF8StringEncoding]];
    [putData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [putData appendData:[NSData dataWithData:file]];



    // Close
    [putData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    // Append
    [request setHTTPBody:putData];


    NSError *err;
    NSURLResponse *response;

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];

    NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];


}

Solution

  • Thanks to God Finally I found a way. Given below is the edited and working code:

    -(void)uploadFile:(NSString*)uploadUrl
    {
        NSString *urlString = uploadUrl;
    
        NSData* file =  [NSData dataWithContentsOfFile: [@"/Users/username/Desktop/s.sql" stringByExpandingTildeInPath]];
    
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:urlString]];
        [request setHTTPMethod:@"PUT"];
    
    
        [request addValue:@"7919" forHTTPHeaderField: @"Content-Length"];
        [request addValue:@"bytes 0-7918/7919" forHTTPHeaderField: @"Content-Range"];
    
    
        NSMutableData *putData = [NSMutableData data];
        [putData appendData:[NSData dataWithData:file]];
    
    
        // Append
        [request setHTTPBody:putData];
    
    
        NSError *err;
        NSURLResponse *response;
    
        NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
    
        NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
        NSLog(resSrt);
    }