iPhone: Using NSMutableURLRequest with NSTimer to handle connection timeout - iphone

"Forced" to use sendSynchronousRequest (POST) for our application. Checking if "response" is nil (below) will catch a few of the connection errors that may occur, but I'd like to invoke a timer as well to cancel the request after about 20 s. Not sure on how to do that and how to "wait" for time out. Any suggestions? Thanks in advance.
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if(response == nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Connection error"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
[alert resignFirstResponder];
[alert release];
} ...

try this:
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];

Related

How to send POST value to website?

I need to submit value from my application via UITextField and I want this value to show on website that i sent request to. I use ASIHTTPRequest to send request to website. i tried something like this:
NSURL *url = [NSURL URLWithString:#"http://www.project4hire.com/freelance_job_16265.html"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:#"POST"];
//
[request setPostValue:priceField forKey:#"bid"];
[request setPostValue:dayField forKey:#"days2c"];
[request setPostValue:commentField forKey:#"comment"];
[request setPostValue:#"1" forKey:#"notify"];
[request setPostValue:#"placebid" forKey:#"Place Bid >>"];
[request setPostValue:#"e6fb12104854e6e9" forKey:#"suid"];
[request setPostValue:#"placebid" forKey:#"a"];
[request setPostValue:#"16265" forKey:#"pid"];
[request setDelegate:self];
[request setDidFailSelector:#selector(requestBidFailed:)];
[request setDidFinishSelector:#selector(requestBidFinished:)];
[request startAsynchronous];
}
- (void)requestBidFailed:(ASIHTTPRequest *)request
{
//notify user
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Error sending request to the server" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
- (void)requestBidFinished:(ASIHTTPRequest *)request
{
NSLog(#"Status: %d", request.responseStatusCode);
NSLog(#"string: %#",request.responseString);
}
Here are the Bid Form:BidForm
Here are request and response header:Header
I got response 200, but the value that i sent not show on the website. Can anyone advice me?
Thanks
I noticed you are posting to a HTML file. Unless you have some special setup to allow The HTML files to be executable, the html file will not process the data you posted to it. Is it that only one value is not showing or are all values not showing. If all values are missing, then what I stated initially is correct and you will need to use something like PHP, CF, Perl or whatever language you want to receive the data you are posting from your app.
I had the same problem, but mine was working on simulator but it was not working on device then I read an article that it shows the founders of the ASIHTTPRequest API no longer update their library (I dont know if that article was reliable or not), so I decided to use an updated library which is RestKit. You can download and set it up from this website: restkit.org, if you have any problem for installing you can ask me to help you. here are the simple code for posting on restkit library:
- (void)post
{
[RKClient clientWithBaseURLString:#"http://www.project4hire.com"];
NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
priceField, #"bid",
dayField, #"days2c", nil];
[[RKClient sharedClient] post:#"/freelance_job_16265.html" params:params delegate:self];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
NSRange range = [[error localizedDescription] rangeOfString:#"-1012"];
if (range.length > 0){
//Do whatever here to handle authentication failures
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Error sending request to the server" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
RKLogError(#"Hit error: %#", error);
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
{
if ([request isGET]) {
// Handling GET /foo.xml
if ([response isOK]) {
// Success! Let's take a look at the data
NSLog(#"Retrieved XML: %#", [response bodyAsString]);
}
} else if ([request isPOST]) {
// Handling POST /other.json
if ([response isJSON]) {
NSLog(#"Got a JSON response back from our POST!");
}
} else if ([request isDELETE]) {
// Handling DELETE /missing_resource.txt
if ([response isNotFound]) {
NSLog(#"The resource path '%#' was not found.", [request resourcePath]);
}
}
NSLog(#"HTTP status code: %d", response.statusCode);
NSLog(#"HTTP status message: %#", [response localizedStatusCodeString]);
NSLog(#"Header fields: %#", response.allHeaderFields);
NSLog(#"Body: %#", response.bodyAsString);
}

Return custom NSURLResponse class

I try to return an object of a subclass of NSURLResponse in my custom NSURLProtocol, but it seems the returned response is always exchanged by a normal NSURLResponse.
This is the part of the NSURLProtocol where I return my custom TestURLResponse:
TestURLResponse* response = [[[TestURLResponse alloc] initWithURL: [[self request] URL]
MIMEType: #"text/plain"
expectedContentLength: 4
textEncodingName:#"UTF-8"]
autorelease];
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[self.client URLProtocol:self didLoadData: [#"Test" dataUsingEncoding:NSUTF8StringEncoding]];
[self.client URLProtocolDidFinishLoading: self];
When I read something with this protocol I expect to get the response of type TestURLResponse, but in the following code I always get a NSURLResponse:
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"test://test"]];
NSURLResponse* response;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *className = NSStringFromClass([response class]);
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:className message:className delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
The whole test project can be downloaded at
http://ul.to/9yylk65s
Right now I have no idea if I'm doing something wrong or if there is something broken. The documentation of NSURLProtocol states
A protocol implementor may wish to create a custom, mutable NSURLResponse class to provide protocol specific information.
but it seems to me, this isn't working at all.

login to a website in iphone

i am developing one app which will login to vonage website and do some functions like call froward etc . For that purpose first i am trying to login to vonage website
i did these steps
1) Found the login url of vonage
https://secure.vonage.com/vonage-web/public/login.htm
2) used livehttpheader addon to capture outgoing post request data when i clicked sigin
the data i found is
username=myusername&password=mypassword&redirectingURL=%2Fwebaccount%2Fdashboard%2Fchoose.htm&frontDoorLogin=&goToSelection=callforwarding&loginsubmit=Sign+In
after i got my data i started coding in xcode , i dont know what is best way to do it but i searched for sometime then i tried like this
-(IBAction) buttonpressed {
NSURL *url = [NSURL URLWithString:#"https://secure.vonage.com/vonage-web/public/login.htm"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setValue:#"myuser" forKey:#"username"];
[request setValue:#"mypass" forKey:#"password"];
[request setValue:#"/webaccount/dashboard/choose.htm" forKey:#"redirectingURL"];
[request setValue:#"" forKey:#"frontDoorLogin"];
[request setValue:#"callforwarding" forKey:#"goToSelection"];
[request setValue:#"Sign+In" forKey:#"loginsubmit"];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIFormDataRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
UIAlertView *alert= [[UIAlertView alloc] initWithTitle:#"Hmm" message:#"http works" delegate:self cancelButtonTitle:#"okay" otherButtonTitles:nil];
[alert show];
[alert release];
NSLog(#"Output = %#",responseString);
}
- (void)requestFailed:(ASIFormDataRequest *)request
{
NSError *error = [request error];
UIAlertView *alert= [[UIAlertView alloc] initWithTitle:#"fail" message:#"http fails" delegate:self cancelButtonTitle:#"okay" otherButtonTitles:nil];
[alert show];
[alert release];
}
but when i ran app in my simulator it crashed .
am i doing correct way in posting data ? and is there any other way to do this ?
can any one help me in this issue
i am using asihttprequest library
thanks in advance
regards
Edit : My blind mistake i types setvalue instead of setpostvalue ,this will solve this issue :)
look at the section titled Sending a form POST with ASIFormDataRequest
// using post value
[request setPostValue:#"myuser" forKey:#"first_name"];
also I usually do my alerts with an autorelease, not sure if that is your problem but you might want to try that changes also
UIAlertView *alert= [[[UIAlertView alloc] initWithTitle:#"Hmm" message:#"http works"
delegate:self cancelButtonTitle:#"okay" otherButtonTitles:nil] autorelease];
[alert show];
UIAlertView Delegate Code
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:
(NSInteger)buttonIndex {
// do your thing
}

set network timeout and exception in iPhone

I am developing an iPhone application in which I am loading lots of data from another server via web-services .
I want have read somewhere in the apple guides that for network aware applications you have to set the network time out and after that you have alert the user for the same that "The network is not available".
How can I do so ?
Here is the sample code to call Web Service with setup of request-timeout = 20. If it will not respond within time 20 then it will stop connecting and we get a nil data.
NSString* str = [NSString stringWithFormat:#"http://ws.geonames.org/findNearbyPostalCodes?lat=%f&lng=%f",curr_latitude,curr_longitude];
NSMutableURLRequest* request2=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:str]];
[request2 setHTTPMethod:#"POST"];
[request2 setTimeoutInterval:20];
NSURLResponse *response=nil;
NSError *err=nil;
NSData *data1=[[NSURLConnection sendSynchronousRequest:request2 returningResponse:&response error:&err] retain];
if(data1 == nil)
{
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"The network is not available.\n Please check the Internet connection." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
// It will store all data to data1
// Here you can proceed with data1
}

Does UIAlert need some sort of delay?

Trying to alert user when internet is unavailable (and retry when they dismiss message). The screen slightly dims (in preparation for alert), but the alert never displays.
Is the while loop interfering with the alert?
-(NSArray*)getResponse:(NSString*)page {
NSError *error;
NSURLResponse *response;
NSData *dataReply;
NSString *stringReply;
NSString *legalAddressURL;
NSArray *separatedData;
legalAddressURL = [NSString stringWithFormat:#"%#%#", SERVER,
[page stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: legalAddressURL]];
[request setHTTPMethod: #"GET"];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
while ([error code]){
if (isNetAvailable){
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Internet Connection"
message:#"Server is down" delegate:self cancelButtonTitle:#"Try again"
otherButtonTitles:nil] autorelease];
[alert show];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
} else {
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Internet Connection"
message:#"No access to net" delegate:self cancelButtonTitle:#"Try again"
otherButtonTitles:nil] autorelease];
[alert show];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
}
}
stringReply = [[NSString alloc] initWithData:dataReply encoding:NSUTF8StringEncoding];
separatedData = [stringReply componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#","]];
return separatedData;
}
After showing the alert using [alert show], you should exit the getResponse method, because the internal message loop should continue.
You can't simply continue looping and showing alerts.
I could be wrong, but I'm pretty sure that's the reason.