I've a strange problem, I'm working on a project that I've to request from a server, When requesting a URL without parameters using GET method, it works fine and return the desired data, but when using the same code to call the URL and sending a parameters to it, it fail with this error:
error: Error Domain=NSURLErrorDomain Code=-1001 UserInfo=0xed4870 "timed out"
My code is the following:
NSString *param = #"pageNumber=2";
NSURL *url = [NSURL URLWithString:#"http://myWebsite/api/Soccor/"];//When using this, it works fine
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://myWebsite/api/Soccor?%#", param]];//When using this, it gives me the request time out error.
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest addValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[theRequest addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"GET"];
[theRequest setTimeoutInterval:10];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
Any clue why it returns error when sending parameters with the URL?
I would suggest you consider two aspects of the request:
You are not showing us your setting of msgLength, but I would only suggest setting a Content-Length header if you're also using setHTTPBody, in which case you'd set the Content-Length to be the length of the NSData you use as a parameter to setHTTPBody. But this is used with POST requests, not GET requests.
You specify application/json for the Content-Type of the request, but request does not consist of JSON. If you did that because the response is JSON, it should be noted that this header value is for your request, not for the response you expect from the server.
Related
I try to make an authenticate call to the twitter API with the Application only Authentication API
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"Some App Name" forHTTPHeaderField:#"User-Agent"];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
[request setHTTPBody:[#"grant_type=client_credentials" dataUsingEncoding:NSUTF8StringEncoding]];
Interestingly the authValue is not getting set for HTTPHeaderField #"Authorization". Therefor my calls fail of course. All other header fields are set correctly.
I check it by
NSLog(#"Authorization, %#, %#", [request valueForHTTPHeaderField:#"Authorization"], authValue);
which returns #"Authorization, (null), theCorrectStuff
Why is this happening? I should be able to set it right away, or am I missing something?
Thanks for your time and consideration,
Fabian
I had the same issue. Output your authValue, it probably contains new lines. For the application only authentication after you do base64 you need to remove new lines from authValue otherwise the header field won't be set.
Or just use already written Objective-C library for Twitter REST API 1.1 (https://github.com/nst/STTwitter).
I'm trying to send a post request from my iOS app to the server. The request works when using curl:
curl -d "uid=1&type=robbery&x=41.66505&y=-93.73046" http://thawing-ravine-5632.herokuapp.com/sos
And here's the Objective-C code that is making the request:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:[NSURL
URLWithString:#"http://thawing-ravine-5632.herokuapp.com/sos"]];
[request setHTTPMethod:#"POST"];
[request setValue:x
forHTTPHeaderField:#"x"];
[request setValue:y
forHTTPHeaderField:#"y"];
[request setValue:type
forHTTPHeaderField:#"type"];
[request setValue:uid
forHTTPHeaderField:#"uid"];
NSURLConnection * postOutput =[[NSURLConnection alloc]
initWithRequest:request
delegate:self];
Finally, didReceiveData Logs the following:
2013-03-31 20:29:32.248 THST Mobile[14720:11c03] connectionDidReceiveData {"student_found":0,"school_found":0,"officer_found":0,"text_sent":0,"uid":0,"x":0.0,"y":0.0,"type":null}
But logging the variables before the request is made shows that they are indeed instantiated in the app prior to making the request. SSHing into the server shows that they are all just either nil or empty strings when the request is received. So something is wrong with my Objective-C code for making the post request - probably with the way I'm setting the parameters?
You're setting the values as headers, not as request's body.
NSString *params = #"x=1&y=bla&z=foo";
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
I'm trying to create a synchronous REST request to an API. The API uses HTTP Basic authentication, so in addition to sending an Accept: application/json header, I need to specify the Authorization header as well with my Base64-encoded username and password pair. When I use just one header the request executes just fine (either successfully authenticating me, or specifying my content format), but when I use both headers, it seems to ignore the Authorization line and returns "HTTP Basic access denied" (presumably a 401).
So I can't for the life of me figure out whats wrong. I'm 100% sure my credentials are valid, because executing the request via REST client works just fine. I'm pretty new to Objective-C so I think perhaps there could be some kind of design pattern I'm not following. Is it valid to call setValue:forKey on an NSMutableDictionary multiple times like that? I also tried using setValue:forHTTPHeader on the request object with the same results.
Here's the code:
NSURL *url = [NSURL URLWithString:#"http://foo.com/api/v1/bar"];
NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
NSMutableDictionary *headers = [NSMutableDictionary dictionary];
NSURLResponse *urlResponse;
NSError *error;
[headers setValue:#"application/json" forKey:#"Accept"];
[headers setValue:#"Basic ..." forKey:#"Authorization"];
[request setAllHTTPHeaderFields:headers];
NSData *urlData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse
error:&error];
NSString *responseString = [[NSString alloc] initWithData:urlData
encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
The answer is to use:
[request addValue:#"Basic ..." forHTTPHeaderField:#"Authorization"];
Which adds another header into the request instance.
I've got a problem with my objective c code. I have a API-key protected WCF API that I built that takes POST requests and writes them to a Java servlet with C#. Anyway, this works great when testing with Fiddler, not so good from objective C. When I try to run the POST from my objective C, it "acts" like the NSURLMutableRequest is looking for a GET, in that the response only returns some default code I have written in for the GET method. Does anybody know why this is, and, moreover, what I can do to fix it? Here is the code that I use (quite successfully) to make other POST requests in with objective C.
is the problem the fact that I specify the API key in the URL for the NSMutableRequest? That's the only thing I can figure.
Here is the code:
NSString* theMessage = [NSString stringWithFormat:#"<MyRequestObject xmlns='http://schemas.datacontract.org/2004/07/MyService'></MyRequestObject>"];
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:POST_API_URL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:240.0];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
[theRequest setHTTPBody:[theMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSString *msgLength = [NSString stringWithFormat:#"%d", [theMessage length]];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
NSURLResponse* response;
NSError *error;
NSData* result = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
I ended up using ASIHTTPRequest to run the POST request to the WCF REST service, and now everything seems to be running smoothly. This means that there's probably some sort of URL Encoding mechanism for the API key that's going on behind the scenes that was poorly documented for NSMutableURLRequest, who knows. The good thing is, I've got the issue fixed. Here is the code I used:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:POST_API_URL]];
[request appendPostData:[[NSString stringWithFormat:#"<MyRequest xmlns='http://schemas.datacontract.org/2004/07/MyService'>all of my request params in here</MyRequest>"] dataUsingEncoding:NSUTF8StringEncoding]];
[request setRequestMethod:#"POST"];
[request addRequestHeader:#"Content-Type" value:#"text/xml"];
[request startSynchronous];
Did you try setting the Content-Length header? WCF/IIS might be ignoring the body if it doesn't have its length defined in as a header.
i have the next code:
NSURL *url = [NSURL URLWithString:#"http:...."];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [""soapMessage"" length]];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [""soapMessage"" dataUsingEncoding:NSUTF8StringEncoding]];
[theRequest setTimeoutInterval:20];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
[theConnection start];
Then sometimes, when i click a lot of times (Just to try where can fail the app) in my interface in the buttons assigned to start a new connection, the connection doesn't give a reply (I send the request but looks like is blocked after).
I would like to know what is the use of "setTimeoutInterval"? AND if there are some ways to limit the time to wait one response?
Thanks!
How do you know that the request started in the first place? You might be waiting for a response for a request that never started.
It appears you are not testing for theConnection being set to nil. also theRequest and url could also be nil if you run out of memory.