NSURLSession takes too much time - objective-c

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

Related

Error 400 uploading Image data to device with NSURLSessionDataTask

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.

Get Api is not working properly

i am working on get api when hit the api in app i am not getting updated response when i remove the app from simulator and device its working fine.guys what i am doing wrong please help me.i have already tried Afnetworking simple Api nsurl session.
NSString *strURL = [NSString stringWithFormat:#"https://mysponsers.com/m/comments/publicpost/674"];
NSURL *url = [NSURL URLWithString:strURL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:url];
[httpClient getPath:strURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
id json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
NSLog(#"RESPONSE--->1%#",json);
} failure:^(AFHTTPRequestOperation* operation, NSError *error) {
//fail!
NSLog(#"Error String is %#", error.localizedDescription);
}];
Here is the code i am using afnetworkikng for hitting the api.
Thank You
You can try with latest version of AFNetworking library or you can simply use this code also.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://mysponsers.com/m/comments/publicpost/674"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(#"%#", httpResponse);
}
}];
[dataTask resume];
You can install or update AFNetworking via cocoapods by adding this (pod 'AFNetworking', '~> 3.1.0') in your pod file.
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
// Change your api content-type here:
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
manager.requestSerializer = requestSerializer;
[manager GET:#"{ Write your url here }"
parameters:nil
progress:nil
success:^(NSURLSessionDataTask *operation, id responseObject) {
NSString *response = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Success response: %#", response);
}
failure:^(NSURLSessionDataTask *operation, NSError *error) {
NSHTTPURLResponse *response = (NSHTTPURLResponse *)operation.response;
NSLog(#"Failure response: %#", response);
}];

Sending params with POST Req in JSON with AFNetworking

I have a small problem with AFNetworking.
I'm not able to send the parameters and the data to my server (php-Skript)
The data (from NSDictionary) have to be JSON.
Ignore the senseless code parts please.
I'm receiving Errors like:
NSLocalizedDescription=Request failed: unacceptable content-type: text/html}
or Error: Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html"
NSDictionary *parameter = [[NSDictionary alloc]init];
parameter = #{#"device-id": #"iOSDeveloper1234567432",#"system": #1,#"token": #"iOS-TestToken",#"mail_enabled": #"false",#"mail": #"NULL", #"movies": #[#"matrix", #"matrix2", #"matrix3"]};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameter options:0 error:nil];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString: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 *stringkey;
stringkey = (#"k=");
stringkey = [stringkey stringByAppendingString:APIKEY];
NSString *strings;
NSString *myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
myString = [myString stringByAppendingString:(#"&k=")];
myString = [myString stringByAppendingString:APIKEY];
NSLog(#"%#",myString);
myString = [myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = [myString dataUsingEncoding:NSSymbolStringEncoding];
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameter options:0 error:&error];
NSLog(#"%#",error.localizedDescription);
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:URL parameters:myString progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];

Objective C Block within Block generates Leak. How can I solve it?

Why does this code generates a leak? How could it be solved?
This is the original call:
NSString * url = #"https://theserverurl/user/login" ;
NSDictionary *parameters = #{#"login":#"the-email#mail.com", #"password":#"encrypted-password"} ;
[[BackEndAPI sharedManager] NSURLSessionOperation: #"POST" url: url parameters: parameters success:^(NSURLRequest *request, NSHTTPURLResponse * response, id responseObject) {
// Success
} failure:^(IDLEngineError *engineError) {
// Failure
}] ;
This is the singleton which handles the NSURL request:
- (NSMutableURLRequest *) NSURLSessionOperation:(NSString *) restOperation
url:(NSString *)url
parameters:(id)parameters
success:(void (^)(NSMutableURLRequest *request, NSHTTPURLResponse * response, id responseObject))success
failure:(void (^)(IDLEngineError *))failure {
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
__weak id weakSelf = self ;
// POST
if ([restOperation isEqualToString:#"POST"]) {
NSError *error;
NSURLSession *session = [NSURLSession sessionWithConfiguration: sessionConfig ];
// Create the request
__block NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: url ] ];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"] ;
request.HTTPMethod = #"POST";
NSData *postData = [NSJSONSerialization dataWithJSONObject: parameters options: 0 error:&error];
[request setHTTPBody:postData];
// Perform operation
NSURLSessionDataTask * task = [session dataTaskWithRequest: request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// This generates a leak!!!!
success(request, nil, nil) ;
}] ;
[task resume] ;
}
return nil ;
}
Please take a look to the leaked app on GitHub:
https://github.com/arkyxperience/myleakedapp
Find also here the report (screenshot) coming from Instruments:
It turns out the leak is with NSURLSessionDataTask. If you isolate the following piece of code, the leak will remain:
NSString * url = #"https://theserverurl/user/login" ;
NSDictionary *parameters = #{#"login":#"the-email#mail.com", #"password":#"encrypted-password"} ;
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSError *error;
NSURLSession *session = [NSURLSession sessionWithConfiguration: sessionConfig ];
// Create the request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: url ] ];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"] ;
request.HTTPMethod = #"POST";
NSData *postData = [NSJSONSerialization dataWithJSONObject: parameters options: 0 error:&error];
[request setHTTPBody:postData];
// Perform operation
NSURLSessionDataTask * task = [session dataTaskWithRequest: request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}] ;
[task resume] ;
Am I doing anything wrong?
OK, i tried your github code, looks like there is no leak. What object is leaking after all? To test this code please add restoration id to your controller. In this code dealloc is being triggered even tho i don't use weak to call controller. So controller is not leaking, complete block does not have a retain loop. Don't see anything that can leak in NSURLSessionOperation:. So what exactly is leaking?
- (void)viewDidLoad {
[super viewDidLoad];
NSString * url = #"https://google.com" ;
NSDictionary *parameters = #{#"login":#"the-email#mail.com", #"password":#"encrypted-password"} ;
[[BackEndAPI sharedManager] NSURLSessionOperation: #"POST" url: url parameters: parameters success:^(NSURLRequest *request, NSHTTPURLResponse * response, id responseObject) {
NSLog(#"finish");
dispatch_async(dispatch_get_main_queue(), ^{
self.view.window.rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
});
} failure:^(NSError * error) {
NSLog(#"fail");
}];
}
- (void)dealloc {
NSLog(#"Did dealloc");
}

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