connection:willCacheResponse will never get called - iphone

I'm working on an iPhone App which involves downloading data from a web server. All things are working fine except the method connection:willCacheResponse: will never get called. But others like connection:didReceiveResponse:, connection:didReceiveData:, connection:didFailWithError:, connectionDidFinishLoading: all working fine. I made the connection like following:
- (void)makeConnection
{
NSURL *url = [NSURL URLWithString:#"http://www.abc.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"%#", string];
[request setValue:[NSString stringWithFormat:#"%d", [postString length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
NSCachedURLResponse *newCachedResponse = cachedResponse;
NSDictionary *newCachedResponseUserInfo = [NSDictionary dictionaryWithObject:[NSDate date] forKey:#"Cached Date"];
newCachedResponse = [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response] data:[cachedResponse data] userInfo:newCachedResponseUserInfo storagePolicy:[cachedResponse storagePolicy]];
return newCachedResponse;
}
I also try to change the policy to NSURLRequestUseProtocolCachePolicy, but nothing help. Also tried to put a break point in
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
but nothing happened.
Am I missing something? Thank you in advance.

connection:willCacheResponse: is only called if the response contains a Cache-Control header, according to Appleā€™s documentation:
The delegate receives connection:willCacheResponse: messages only for protocols that support caching.

Related

Http Post Request With Parameters

I have a simple asp.net web service which returns json format data. I want to send http post request with parameter for getting json data. How can I send request and get data ?
post request:
POST /JsonWS.asmx/FirmaGetir HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: length
firID=string
answer:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">string</string>
I'm trying some codes but they didn't work.
NSString *firmadi =#"";
NSMutableData *response;
-(IBAction)buttonClick:(id)sender
{
NSString *firid = [NSString stringWithFormat:#"800"];
response = [[NSMutableData data] retain];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://192.168.1.23/testService/JsonWS.asmx?op=FirmaGetir"]];
NSString *params = [[NSString alloc] initWithFormat:#"firID=%#",firid];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(theConnection)
{
response = [[NSMutableData data] retain];
}
else
{
NSLog(#"theConnection is null");
}
}
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)responsed
{
[response setLength:0];
NSURLResponse * httpResponse;
httpResponse = (NSURLResponse *) responsed;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data
{
[response appendData:data];
//NSLog(#"webdata: %#", data);
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error
{
NSLog(#"error with the connection");
[connection release];
[response release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
response = [[NSMutableData data] retain];
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
}
What are you doing here:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
This line returns a NSURLConnection but you are not storing it. This is doing nothing for you.
You are clearing your data before you read it:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
response = [[NSMutableData data] retain]; // This line is clearing your data get rid of it
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
}
Edit
-(IBAction)buttonClick:(id)sender {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://192.168.1.23/testService/JsonWS.asmx?op=FirmaGetir"]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:15];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[#"firID=800" dataUsingEncoding:NSUTF8StringEncoding]];
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[self.connection start];
}
#pragma NSURLConnection Delegates
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if (!self.receivedData){
self.receivedData = [NSMutableData data];
}
[self.receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
}
I suffered this problem this morning and I just figure it out now. I guess the key to your question is How to use POST method with parameter. Actually, it is quite simple.
(1) First, you should make sure your file is ready to send. Here we say it is an NSString called stringReady. We use it as a parameter in our method called postRequest (Here is not the HTTP POST parameter we want to talk about. Don't worry).
// Send JSON to server
- (void) postRequest:(NSString *)stringReady{
// Create a new NSMutableURLRequest
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.xxxxxx.io/addcpd.php"]];
[req setHTTPMethod:#"POST"];
(2) Now, we say it the parameter that the server wants to get is called "data", this is the way how to insert your parameter to the HTTP body.
// Add the [data] parameter
NSString *bodyWithPara = [NSString stringWithFormat:#"data=%#",stringReady];
See, it's how you add a parameter when using POST method. You just simply put the parameter before the file that you want to send. If you aleary konw what your parameter then you may better to check this website:
https://www.hurl.it/
This will help you to test if you are sending files properly and it will show the response at the bottom of the website.
(3) Third, we pack our NSString to NSData and sent it to server.
// Convert the String to NSData
NSData *postData = [bodyWithPara dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Set the content length and http body
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[req addValue:postLength forHTTPHeaderField:#"Content-Length"];
[req setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[req setHTTPBody:postData];
// Create an NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:req
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Do something with response data here - convert to JSON, check if error exists, etc....
if (!data) {
NSLog(#"No data returned from the sever, error occured: %#", error);
return;
}
NSLog(#"got the NSData fine. here it is...\n%#\n", data);
NSLog(#"next step, deserialising");
NSError *deserr;
NSDictionary *responseDict = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&deserr];
NSLog(#"so, here's the responseDict\n\n\n%#\n\n\n", responseDict);
}];
[task resume];}
Hope this can help somebody who gets stuck at here.

iOS Forms Authentication

I need to:
1) Authenticate against a forms authentication service
2) Save off cookie
3) Call web service with cookie
And I'm having a hell of a time trying to get this working. Has anyone had any luck with this? It seems like a very common operation.
Here's my code:
Hit auth URL and get the cookie:
- (IBAction)buttonGetCookieTap:(id)sender {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.cookieURL];
[request setHTTPShouldHandleCookies:YES];
[request setHTTPMethod:#"POST"];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- ( void )connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response
{
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
NSDictionary *fields = [HTTPResponse allHeaderFields];
self.cookie = [fields valueForKey:#"Set-Cookie"];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"blah"
password:#"blah"
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
Now call auth service with the cookie:
- (IBAction)buttonCallServiceTap:(id)sender {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.dataURL];
[request addValue:self.cookie forHTTPHeaderField:#"Cookie"];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
Edit: Sorry, the problem I have is that I'm getting a barebones cookie back with just the session id but on the server end the cookie looks fine. Can anyone verify that there's nothing wrong with my cookie grabbing code? I've tried many variations of this and have the same problem. Thanks!
I wrote an answer to a Stack Overflow question here, which provides sample code for examining your application's cookies. Someone else in that thread provided additional code for getting app-side cookie details. You might start there, to help troubleshoot authentication.
I figured out how to do this, I had to build a soap message for the HTTP Body.
NSString *soapFormat = [NSString stringWithFormat:#"<?xml version='1.0' encoding='UTF-8'?>\n"
"<soap:Envelope\n"
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n"
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
"<Login xmlns=\"http://asp.net/ApplicationServices/v200\">\n"
"<username>myusername</username>\n"
"<password>mypassword</password>\n"
"</Login>\n"
"</soap:Body>\n"
"</soap:Envelope>\n"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:self.authURL];
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"http://asp.net/ApplicationServices/v200/AuthenticationService/Login" forHTTPHeaderField:#"SOAPAction"];
[request addValue:[NSString stringWithFormat:#"%d",[soapFormat length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[soapFormat dataUsingEncoding:NSUTF8StringEncoding]];
self.authConnection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
I can grab the cookie from didReceiveResponse
- ( void )connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response
{
if (self.currentCookies == nil) {
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
self.currentCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[HTTPResponse allHeaderFields] forURL:[NSURL URLWithString:#""]];
NSLog(#"COOKIE: %#",((NSHTTPCookie*)[self.currentCookies objectAtIndex:1]).value);
}
}
Then I use the cookie to get JSON data from the webservice.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.dataURL];
[request setHTTPMethod: #"GET"];
NSString *cook = [NSString stringWithFormat:#".ASPXAUTH=%#",((NSHTTPCookie*)[self.currentCookies objectAtIndex:1]).value];
[request addValue:cook forHTTPHeaderField:#"Cookie"];
[request setHTTPShouldHandleCookies:NO];
self.dataConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
I hope this helps someone who has a similar authentication system.

iPhone - Http Post : send a value to a web xml

i know there are a lot of questions about this but none seems to work for what I want to do. I want to change the value of a tag so let's say i have this file :
</Courbe>
<tempset>140</tempset>
</Courbe>
I want my http post request to change this value. How do I do this?
I have already tried something like that :
- (IBAction)changeTemp:(id)sender
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://207.134.145.16:50001/Courbe.xml"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Content-type"];
NSString *xmlString = #"<tempset>137</tempset>";
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
Is it something like this? Thanks for your help!
Url encode the xmlString, then:
NSData *postData = [xmlString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[request setHTTPBody:postData];
[request setValue:[NSString stringWithFormat:#"%d", [postData length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
To send, use something like this:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {}];
Prior to iOS5, you can send asynchronously this way:
// make the request and an NSURLConnection with a delegate
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
// create a property to hold the response data, then implement the delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[responseData release];
[textView setString:#"Unable to fetch data"];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[[NSString alloc] initWithData:responseData encoding: NSASCIIStringEncoding] autorelease];
}

"Operation couldn't be completed. Connection reset by peer." with NSURLConnection on iOS

I'm struggling sending POST data to a server and receiving the correct response. I started by using setHTTPBody but moved to setHTTPBodyStream when I wasn't getting the correct server response for certain POST data and I read setHTTPBody has a memory leak on earlier iOS versions. The problem is setHTTPBodyStream causes the error - "Operation couldn't be completed. Connection reset by peer".
Here's the code:
NSMutableURLRequest * request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"secret but correct url goes here"] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0];
[request setHTTPMethod: #"POST"];
[request setHTTPBodyStream: [NSInputStream inputStreamWithData: [[NSString stringWithFormat:#"username=%#&password=%#&score=%i",[(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)ogl_view->username, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8) autorelease],[(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)text_field.text, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8) autorelease],ogl_view->score[0]] dataUsingEncoding:NSUnicodeStringEncoding]]];
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest: request delegate:self];
if (connection){
received_data = [[NSMutableData data] retain];
ogl_view->section = CURLING_PROCESS_CREDENTIALS;
}else{
ogl_view->section = CURLING_LOGIN_OR_REGISTER;
UIAlertView *connection_alert = [[UIAlertView alloc] initWithTitle:#"Error" message: #"Can't connect to server" delegate:self cancelButtonTitle:#"Close" otherButtonTitles: nil];
[connection_alert show];
[connection_alert release];
}
I can verify the server is fine and it works when I try a web-browser.
Can somebody get me on the right track to sending data with HTTP and the POST method correctly?
Thank you for any help.
Try using this (with your own values):
NSString* post = #"username=myUser&password=myPass&score=20"; //customize this
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSURL *url = [NSURL URLWithString:#"http://my.request.com"]; //customize this
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[request setTimeoutInterval:timeout];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
You'll then need to implement the NSURLConnectionDelegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)remoteData;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
In the end, remember to release the NSURLConnection.
Edit: Didn't see that you wrote that setHTTPBody leaks... never seen that happening. Anyway, here is some code that should work...

get return result after post to server (from iphone)

I make iphone application, post parametes to JSP (test.jsp in server) from iphone. The following is my codes:
NSData *postData = [#"&test=123&field=456" dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
// Init and set fields of the URLRequest
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"POST"];
[request setURL:[NSURL URLWithString:[NSString stringWithString:#"http://mydomain.com/test.jsp"]]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
// Return data of the request
NSData *receivedData = [[NSMutableData data] retain];
}
[request release];
But my problem is: I can not get return result from JSP server.
How I can setup in JSP to get return result in iPhone? and in iPhone too?
Thank all
Do you implement this in your delegate:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
Data won't just magically appear in your receivedData instance. You need to implement the delegate methods for NSURLConnection. Take a look at Apple's documentation on how to this all properly.