Return custom NSURLResponse class - iphone

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.

Related

NSURLConnection error not working

I am trying to detect if there is an error in my request using the if statement on theConnection. It enters the first part if successful fine but does not enter the else if there is an error. I am not sure why.
- (void)vehicleSearchRequest:(NSData *)postBodyData
{
NSString *address = [NSString stringWithFormat:#"http://%#", serverAddress];
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithFormat:#"%#", address];
NSURL *url = [NSURL URLWithString:databaseURL];
NSString *postLength = [NSString stringWithFormat:#"%d", [postBodyData length]];
//SynchronousRequest to grab the data, also setting up the cachePolicy
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //if request dose not finish happen within 60 second timeout.
// Set up request
[request setHTTPMethod: #"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/octet-stream" forHTTPHeaderField:#"content-type"];
[request setHTTPBody:postBodyData];
[request setTimeoutInterval:180];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (theConnection) {
// do animation thankyou here
NSLog(#"Sucsess!");
[self submitSuccessful];
} else {
// Inform the user that the connection failed from the connection:didFailWithError method
NSLog(#"Connectin ERROR!!!");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection error, Please try again" message:nil delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
Your code checks to see whether it was able to instantiate an NSURLConnection or not. This is a useful safety check, but will only fail in practice if you pass it a URL that the system does not support.
The connection itself is asynchronous, and so will take a little while to tell you if there was a problem or not. Implement its delegate methods to hear back from the server.

Getting error in connection class while sending url having lots of parameters

Hello Friends i am getting a problem in connection class i am using the same connection class for my different methods .Every where its working fine but on making this particular connection i m getting error ie:.. Connection did fail with error.
I am posting my entire code please help me.
Code for sending my url and making connection:-
NSString *strURl=[NSString stringWithFormat:#"http://xxxyyy.com/API/index.php?action=listIt&login=%#&pwd=%#&name=%#&catID=%d&listID=&addr1=%#&addr2=%#&locName=&city=%#&state=%#&zip=&startDate=%#&startHours=%#&startMin=%#&startMeridiem=%#&endDate=%#&endHours=%#&endMin=%#&endMeridiem=%#&contactName=&contactPhone=&contactEmail=&contactWebsite=&cost=%d&description=%#",appDelegate.strUserName,appDelegate.strPassword,strTitle,self.subCat_ID,[txtAddress1.text urlEncodeUsingEncoding:NSUTF8StringEncoding],[txtAdress2.text urlEncodeUsingEncoding:NSUTF8StringEncoding],lblCity.text,lblState.text,strBeginDate,startHr,startMin,startMeridiem,strEndDate,strEndHr,strEndMin,strEndMeridiem,cost,[txtdDscription.text urlEncodeUsingEncoding:NSUTF8StringEncoding]];
//strURl=[strURl urlEncodeUsingEncoding:NSUTF8StringEncoding];
// NSString *strEncode=[strURl stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// strEncode=[strEncode stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSLog(#" strListItURl =%#",strURl);
ConnectionClass *connection=[[ConnectionClass alloc]init];
[connection getResponseData:strURl];
connection.delegate=self;
[connection release];
NSLog(#" strListItURl =%#",strURl); this is the url with method and parameter i am sending.
strListItURl http://xxxyyy.com/API/index.php?action=listIt&login=sawanth&pwd=sawanth&name=Hello One&catID=4&listID=&addr1=One%20tow&addr2=next%20one&locName=&city=Anchorage&state=Alaska&zip=&startDate=11/8/2012&startHours=11&startMin=33&startMeridiem=AM&endDate=11/10/2012&endHours=11&endMin=33&endMeridiem=AM&contactName=&contactPhone=&contactEmail=&contactWebsite=&cost=3&description=%20Hello
Note:-when i am pasting the "strListItURl" directly on browser i am getting success.
Now after making connection i am entering in connection class
-(void)getResponseData:(NSString*)strURL
{
NSLog(#"strURL =%#",strURL);
// NSString *str1 = [NSString stringWithFormat:#"%#",strURL];
NSURL *url=[NSURL URLWithString:strURL];
NSLog(#"url is =%#",strURL);
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0];
//Initialize the connection for NSURL Connection
theConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];
if(theConnection)
{
//Initialize the data and retain the data
receiveData = [[NSMutableData data] retain];
}
else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Warning" message:#"Please check internet connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
here when i m printing urlRequest i am finding
Printing description of urlRequest: NSURLRequest (null)
And finaly controls goes to
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
please tell me where i am doing wrong:)
You havent alloc the NSURLRequest. But it is strange it is printing null instead of nil.
Try:
NSURLRequest *urlRequest = [[NSURLRequest alloc] requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0];
I got the answer.
Actually when i was passing the strURL
NSString *strURl=[NSString stringWithFormat:#"http://xxxyyy.com/API/index.php?action=listIt&login=%#&pwd=%#&name=%#&catID=%d&listID=&addr1=%#&addr2=%#&locName=&city=%#&state=%#&zip=&startDate=%#&startHours=%#&startMin=%#&startMeridiem=%#&endDate=%#&endHours=%#&endMin=%#&endMeridiem=%#&contactName=&contactPhone=&contactEmail=&contactWebsite=&cost=%d&description=%#",appDelegate.strUserName,appDelegate.strPassword,strTitle,self.subCat_ID,[txtAddress1.text urlEncodeUsingEncoding:NSUTF8StringEncoding],[txtAdress2.text urlEncodeUsingEncoding:NSUTF8StringEncoding],lblCity.text,lblState.text,strBeginDate,startHr,startMin,startMeridiem,strEndDate,strEndHr,strEndMin,strEndMeridiem,cost,[txtdDscription.text urlEncodeUsingEncoding:NSUTF8StringEncoding]];
its taking blank space from somewhere ,and due to this my connection just fail with error.
so i trimmed the blank spaces
strURl = [strURl stringByReplacingOccurrencesOfString:#" " withString:#""];
and its start working fine.

NSURLConnection doesn't receive data

I have implemented an NSURLConnection that sends a request to a server and receives some data back which is stored in an NSMutableData object. These are the methods that I implemented as part of NSURLConnectionDelegate:
-(void)upLoadBook:(NSMutableDictionary *)theOptions{
NSMutableString *theURL = [[NSMutableString alloc] initWithString:#"theURL"];
[theURL appendFormat:#"&Title=%#&Author=%#&Price=%#", [theOptions objectForKey:#"bookTitle"],
[theOptions objectForKey:#"bookAuthor"],
[theOptions objectForKey:#"bookPrice"]];
[theURL appendFormat:#"&Edition=%#&Condition=%#&Owner=%#", [theOptions objectForKey:#"bookEdition"],
[theOptions objectForKey:#"bookCondition"],
_appDel.userID];
NSLog(#"%#\n", theURL);
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:theURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [NSMutableData data];
}
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
*)response
{
// This method is called when the server has determined that it
// has enough information to create the NSURLResponse.
// It can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is an instance variable declared elsewhere.
[receivedData setLength:0];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
//Receives a response after book has been uploaded (Preferably a Book ID...)
responseString = [[NSString alloc] initWithData:receivedData
encoding:NSUTF8StringEncoding];
NSLog(#"Response String: %#", responseString);
[_options setValue:responseString forKey:#"bookID"];
[self performSegueWithIdentifier:#"UploadSuccessSegue" sender:self];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Whoops." message:#" No internet
connection.\n Please make sure you have a connection to the internet."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
The function uploadBook seems to be called,however, I never get to didFinishLoading and didReceiveData never receives any data. What could be a possible problem. Any hints or clues would be much appreciated.
You need to add your NSURLConnection to the current run loop or a separate one (such as one you set up in a separate thread). The delegate methods do need to get CPU time, after all.
Looking at this related question's accepted answer, it can also be done via Grand Central Dispatch:
dispatch_async(dispatch_get_main_queue(), ^{
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
[conn start];
});
One thing for sure is that you should %-escape your list of parameter before trying to send the request.
You can use stringByAddingPercentEscapesUsingEncoding for that purpose:
NSMutableString *theURL = [[NSMutableString alloc] initWithString:#""];
[theURL appendFormat:#"&Title=%#&Author=%#&Price=%#", [theOptions objectForKey:#"bookTitle"],
[theOptions objectForKey:#"bookAuthor"],
[theOptions objectForKey:#"bookPrice"]];
[theURL appendFormat:#"&Edition=%#&Condition=%#&Owner=%#", [theOptions objectForKey:#"bookEdition"],
[theOptions objectForKey:#"bookCondition"],
_appDel.userID];
theURL = [NSStringWithFormat:#"YOUR_URL_HERE?",[theURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
Please, note that I refactored your code with the minimum number of changes to get the result. You can find better refactorizations for sure.
Here is a sample that works from one of my projects:
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.brayden.me/analytics/device.php"]];
[urlRequest setHTTPMethod:#"POST"];
NSMutableString *postParams = [NSMutableString string];
[postParams appendFormat:#"session=%#&", analyticsSession];
[postParams appendFormat:#"device=%#&", device];
[postParams appendFormat:#"system=%#&", csystem];
[postParams appendFormat:#"version=%#&", version];
[postParams appendFormat:#"launch=%f&", totalLaunchTime];
if([Analytics_Location location].latitude && [Analytics_Location location].longitude) {
[postParams appendFormat:#"latitude=%#&", [Analytics_Location location].latitude];
[postParams appendFormat:#"longitude=%#&", [Analytics_Location location].longitude];
}
[urlRequest setHTTPBody:[postParams dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:YES];
[connection start];
Make sure your header method also uses . The code of mine should at least show you how to properly format the request, as I can verify this does receive data from a PHP call of mine.

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
}

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.