I want to make a PUT request to a URL, but when the output shows status code as 405, which means the request to the URL is something other than put.
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSURL * url = [NSURL URLWithString:#"http://httpbin.org/put"];
NSMutableURLRequest *request =[[NSMutableURLRequest alloc]initWithURL:url];
NSData *postbody = [#"name=testname&suggestion=testing123" dataUsingEncoding:NSUTF8StringEncoding];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
request.HTTPMethod = #"PUT";
[request setHTTPBody:postbody];
NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error == nil)
{
[request setHTTPBody:data];
NSLog(#"Response = %#",response);
}
}];
[dataTask resume];
Can someone point out where i am going wrong, i have been reading a lot about this issue since the last couple of hours, but i am not able to figure it out. Kindly do not mark this as duplicate since the previous op did not add body which is not the case with my code. Also the URL mentioned accepts any data as body, so i guess what i set the data to is irrelevant.
EDIT (ANSWER):
After banging my head from yesterday, one of my senior helped me solve the issue, hope this will help someone. The data task needs to be supplied with the request object and not with the URL, this was the reason it always showed 'GET' in Charles web debugging tool. The code should be as follows:
NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// code
}];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = #"PUT";
Related
How to make HTTP Post request with JSON body in Swift like in this there are not using frameworks like this i need xml posting can any one help me...
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:#"Your SERVER"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:#"application/xml" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
NSString *xmlString = #"<?xml version=\"1.0\"?>\n<yourdata></yourdata>";
[request setHTTPBody:[xmlString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// handel response & error
}];
[postDataTask resume];
Use the above code to achieve what you want
I'm trying to send a simple POST request in iOS to test a server I've written. My code is as follows:
NSURL *url = [NSURL URLWithString:#"http://localhost:8888/createUser"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSString *bodyData = #"username=johndoe";
request.HTTPMethod = #"POST";
request.HTTPBody = [bodyData dataUsingEncoding:NSUTF8StringEncoding];
request.timeoutInterval = 5;
[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"resp: %#, err: %#", response, error);
}];
I've been trying to debug this and am very confused. The code inside the completionHandler is never run, the request never times out, and the server never sees anything. Nothing seems to happen at all. I was able to do a request using the old NSURLConnection but would like to avoid that since it's deprecated. What's the issue here?
In addition to setting up your code to do a GET when you say you want to do a POST (as josemando points out in his comment), you're not starting your task.
You need to change your last line like this:
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest: request
completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error)
{
NSLog(#"resp: %#, err: %#", response, error);
}];
[task resume];
(dataTaskWithRequest creates and returns a data task object which you then have to submit for execution with the resume method.)
Since ASIHTTPRequest is deprecated, I am migrating my code to use NSURLSession based server communication. Currently, I am using NSDictionary "userInfo" property of ASIHTTPRequest to send additional user information. The description of "userInfo" in ASIHTTPRequest documentation is "Custom user information associated with the request (not sent to the server)".
After the request is processed, I re-fetch this "userInfo" object from the request object and take action accordingly.
My ASIHTTPRequest code example is
Request:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:#"http://www.google.com"];
[request setDelegate:self];
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:#"requestCount"];
[request setUserInfo:userInfo];
I want to achieve same functionality through NSURLSession, how can I do this?
NSURLSession code example:
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: self.queue];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setTimeoutInterval:timeOutSeconds];
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];
NSLog(#"Data = %#",text);
}
}
}];
[dataTask resume];
Because you are using completion handler so you can use block variable, try below code:
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: self.queue];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setTimeoutInterval:timeOutSeconds];
__block NSDictionary *userInfo = [NSDictionary dictionaryWithObjectAndKeys...........];**
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
NSLog(#"UserInfo: %#", userInfo);
if(error == nil)
{
NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"Data = %#",text);
}
}
}];
[dataTask resume];
The cleanest way to go is to subclass NSURLRequest and add the desired property - be it tag, or userInfo and use it the same way you are used to with ASIHTTP framework.
I must be missing something basic because I am unable to get any NSURLSession examples using POST to work at all. I have my server set up to print out (to a file that I tail) all the received POST parameters and nothing I put in the POST body shows up. I've tried the solutions from Send POST request using NSURLSession as well as online tutorials such as the Ray Wenderlich Cookbook for using NSURLSession.
Here, for example, is the code almost directly from the Stackoverflow thread, mentioned above, with only the URL and the post arguments changed:
-(void)postTest {
NSString *textContent = #"XXXXX";
NSString *noteDataString = [NSString stringWithFormat:#"x=%#", textContent];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = #{
#"a" : #"YYYYY"
};
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURL *url = [NSURL URLWithString:#"[MY URL with PHP script]"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPMethod = #"POST";
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
outputLabel.text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
[postDataTask resume];
}
The PHP script shows the "XXXXX" parameter was properly received - but it's not part of the POST body; rather, it is part of the URL itself. The only parameter in the POST body is the "YYYYY" parameter but it doesn't show up at all.
The Ray Wenderlich example didn't work either: nothing showed up for the PHP script.
-(void)testPost {
NSURL *url = [NSURL URLWithString:#"[MY URL with PHP script]"];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = #"POST";
NSDictionary *dictionary = #{#"a": #"YYYYY"};
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:&error];
if (!error) {
NSURLSessionUploadTask *uploadTask =
[session uploadTaskWithRequest:request
fromData:data completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {
}];
[uploadTask resume];
}
}
Is there something I'm not setting somewhere? I hadn't expected the shift to NSURLSession would have such subtle boobytraps and I'm wondering if it's something silly I'm doing wrong or missing. Thanks for any help!
Apple Documentation about the request parameter on uploadTaskWithRequest:fromData:completionHandler:
An NSURLRequest object that provides the URL, cache policy, request
type, and so on. The body stream and body data in this request object
are ignored.
I'm facing a very strange issue when using NSURLSessionDataTask to post a JSON request to the server.
The first request goes through and I receive the correct JSON response, when I do a second request I'm getting always back the old response and the server never receives the request. Even if I turn on airplane mode the NSURLSessionDataTask does work an I get back the old response again.
That's the code I'm using:
- (void)getJSONFromURL:(NSURL*)url identifierCode:(NSInteger)code
{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request addValue:[DataController sharedInstance].currentUser.userToken forHTTPHeaderField:#"User-Token"];
[request setHTTPMethod:#"GET"];
if (![SVProgressHUD isVisible])
[SVProgressHUD show];
NSURLSessionDataTask *postTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self handleResponse:httpResponse withJSON:json identifierCode:code];
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
}];
[postTask resume];
}
I've found the issue, I don't know why this has changed, because I never had to set that property before. Anyway I set configuration.URLCache = NULL; and now everthing works fine again.
you can set
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
to disable it per request