Error 400 uploading Image data to device with NSURLSessionDataTask - objective-c

I am attempting to upload a PNG file to a device, using NSURLDataTask and a "POST" request.
However my attempts always conclude with the device returning a 400 HTTP error code in the response.
My Upload code looks like this:
-(void)uploadMedia:(NSData*)mediaData withName:(NSString*)name andID:(NSString*)mediaID
{
NSString *urlString;
NSString *appToken [self retrieveAppToken];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
appToken, #"km-device-auth",
#"application/octet-stream", #"Content-Type",
nil];
sessionConfiguration.HTTPAdditionalHeaders = dict;
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
urlString = [NSString stringWithFormat:#"https://%#:7788/Media?name=%#&id=%#",_strIP,name,mediaID];
NSLog(#"Attemptive Upload URL:%#",urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = #"POST";
request.HTTPBody = mediaData;
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"My respone:%#:%#",response,data);
}];
[postDataTask resume];
}

SOLVED
My headers also required a value for "Content-MD5" which was missing.

Related

NSURLSessionConfiguration and NSData always returning nil

I am new to Mac application development and i am working on fixing the deprecation issues present in the application. I am using XCode 11.3 in Mojave MacOS 10.14 and Our application contains the following line of code
[NSURLConnection sendSynchronousRequest:request returningResonse:response error:Error]
A warning message getting displayed as sendSynchronousRequest is deprecated and it is suggesting to use [NSURLSession dataTaskWithRequest:completionHandler:] .
so i have implemented the following code
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSURL * url = [NSURL URLWithString:#"MyURLHere"];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
if(error == nil)
{
NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
}
}];
[dataTask resume];
i found that data is being returned as nil always. When i debugged the code, i found that even [NSURLSessionConfiguration defaultSessionConfiguration] is being returned as nil. Can you please suggest what needs to be done in order to fix these issues?

How to find the actual "Content_Type" of the NSURLRequest before downloading it

I want to know the content_type of the NSURLRequest before it is downloaded.
As much as I searched I found the below code as solution :
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *httpRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
[httpRequest setHTTPMethod:#"HEAD"];
[httpRequest addValue:#"identity" forHTTPHeaderField:#"Accept-Encoding"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:httpRequest
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPResponse *httpResponse = (NSHTTPResponse*)response;
NSDictionary *dictionary = [httpResponse allHeaderFields];
NSLog([dictionary[#"Content_Type"] description]);
}];
[task resume];
But i am always getting the content_type as text/HTML, even if the URL points to an image.
So it might be the content_type of the header which send because of HEAD set at setHTTPMethod:#"HEAD".
Please help me to find the actual Content_Type of the NSURLRequest before downloading it.

NSURLSession not working on tvOS?

I have this method to get the contents of an URL on TV:
-(void)placeGetRequestForDeveloperID:(NSString *)developerID andRunOnCompletion:(void (^)(NSData *data, NSURLResponse *response, NSError *error))ourBlock {
NSString *urlString = [NSString stringWithFormat:#"https://itunes.apple.com/lookup?id=%#&entity=software", developerID];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
[session dataTaskWithRequest:request completionHandler:ourBlock];
}
The completion block is never called.
NSURLSession is allowed on tvOS. Is there something I have to set on the project, like entitlements or something on the Info.plist to make this work? Is this code OK?
Thanks!
By default, when you create the task, it's suspended. You have to start the task by calling resume.
[[session dataTaskWithRequest:request completionHandler:ourBlock] resume]
You have to resume the task to start the API call.
You can try the API call as like below too.
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *apiCall = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
}];
[apiCall resume];

AFHTTPSessionManager post request

I want to post a request to server. It is working fine if I am using NSURLSessionDataTask. But underneath I need to use AFNetworking as my whole application is using it. But when I am trying to hit the same service in AFHTTPSessionManager with POST method, It is giving me request time out.
Below are both the codes.
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:nil delegateQueue:nil];
NSURL *url = [NSURL URLWithString:#"BASE URL"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSString *postString = #"1";
NSData *data = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
[postDataTask resume];
AFNetworking kit version :-
AFHTTPSessionManager *client = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:#"BASE URL"]];
NSDictionary *request = #{#"Content-Type":#"application/json",
#"Accept":#"application/json",
};
NSString *postString = #"1";
NSData *data = [postString dataUsingEncoding:NSUTF8StringEncoding];
[client POST:#"" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithHeaders:request body:data];
} success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#",responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#",error);
}];
Please help me in implementing it in right way.
I solved this problem by creating my own request and give its configuration to AFURLSessionManager and then holding my own NSURLSessionUploadTask object.
Thanks

NSURLSession takes too much time

I'm using NSURLSession to post a request. Although I'm setting queue to main queue still it takes too much time to respond
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:LOGIN_SERVICE]];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:#"POST"];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
There is a similar question but it has only one answer which is similar to what I'm doing. Anything that I'm missing ?
As you update question with code required, I will say nothing apparently here which make your request slow, few things as this is Network request, it will depend on different things like network speed, server response time. It would be worth while testing on different networks devices.
You can use AFNetworking. If your response like this
{
"my_response": {"name": "XXX","area": "XXX","num": "XXX"
},
"other_response": {"message": "Hello","status": "success","flag_value": "1"
}
}
Stpe 1 :- And set time interval also.
- (void)yourMethod{
NSString *urlString = [NSString stringWithFormat:#"%#", your_service_url];
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
your_parameters_list,
nil];
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:#"POST"
path:urlString
parameters:params];
[jsonRequest setTimeoutInterval:120];
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#" Success %#", JSON);
NSDictionary *jsonDictionary1 = [JSON valueForKey:#"my_response"];
NSDictionary *jsonDictionary2 = [JSON valueForKey:#"other_response"];
NSString* name = [jsonDictionary1 valueForKey:#“name”];
NSString* area = [jsonDictionary1 valueForKey:#"name"];
NSString* num = [jsonDictionary1 valueForKey:#"num"];
} failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Fail %#", [error userInfo]);
NSLog(#“Error %#", [error localizedRecoverySuggestion]);
}];
[operation start];
}