NSURLConnection GET and POST not working - objective-c

I am not getting the correct output from the server. The response I get back everytime is:
Gone
/prod/bwckgens.p_proc_term_datehas been permanently removed from this server.
This is usually recieved when you just direct the web browser to the page here instead of going through this page first. This makes me come to the conclusion that a cookie isn't being saved, but I read in the documentation that this is all handled by the NSURLConnection object. Is there something I am doing wrong here?
#import "PCFViewController.h"
#interface PCFViewController ()
#end
NSMutableData *mutData;
#implementation PCFViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)queryServer {
NSURL *url = [NSURL URLWithString:#"https://selfservice.mypurdue.purdue.edu/prod/bwckschd.p_disp_dyn_sched"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageAllowed timeoutInterval:3.0];
//the reason I perform a GET here is just to get a cookie and communicate like a normal web browser, since directly doing a POST to the proper address isn't working
[request setHTTPMethod:#"GET"];
[request setValue:#"text/html; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
mutData = [NSMutableData data];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[mutData length]);
NSString *str = [[NSString alloc] initWithData:mutData encoding:NSUTF8StringEncoding];
//just to see the contents(for debugging)
NSLog(#"%#", str);
[self handleConnection:connection];
}
-(void)handleConnection:(NSURLConnection *)connection
{
//this is the first step
if ([#"/prod/bwckschd.p_disp_dyn_sched" isEqualToString:[[[connection originalRequest] URL] path]]) {
//first request
//POST
NSURL *url = [NSURL URLWithString:#"https://selfservice.mypurdue.purdue.edu/prod/bwckgens.p_proc_term_date"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageAllowed timeoutInterval:3.0];
[request setHTTPMethod:#"POST"];
NSString *args = #"p_calling_proc=bwckschd.p_disp_dyn_sched&p_term=201320";
NSData *requestBody = [args dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:requestBody];
connection = [connection initWithRequest:request delegate:self];
[connection start];
if (connection) {
mutData = [NSMutableData data];
}
//second step. Here I send the list of classes(COMPUTER SCIENCE) I want to display as well as the term SPRING2013
}else if([#"/prod/bwckgens.p_proc_term_date" isEqualToString:[[[connection currentRequest] URL] path]]) {
NSURL *url = [NSURL URLWithString:#"https://selfservice.mypurdue.purdue.edu/prod/bwckschd.p_get_crse_unsec"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageAllowed
timeoutInterval:3.0];
[request setHTTPMethod:#"POST"];
NSString *args = #"term_in=201320&sel_subj=dummy&sel_day=dummy&sel_schd=dummy&sel_insm=dummy&sel_camp=dummy&sel_levl=dummy&sel_sess=dummy&sel_instr=dummy&sel_ptrm=dummy&sel_attr=dummy&sel_subj=CS&sel_crse=dummy&sel_title=dummy&sel_schd=%25&sel_from_cred=&sel_to_cred=&sel_camp=%25&sel_ptrm=%25&sel_instr=%25&sel_sess=%25&sel_attr=%25&begin_hh=0&begin_mi=0&begin_ap=a&end_hh=0&end_mi=0&end_ap=a";
NSData *requestBody = [args dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:requestBody];
connection = [connection initWithRequest:request delegate:self];
[connection start];
if (connection) {
mutData = [NSMutableData data];
}
//the courses should be shown now I have to parse the data
}else if([#"/prod/bwckschd.p_get_crse_unsec" isEqualToString:[[[connection currentRequest] URL] path]]) {
}
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"%#\n", error.description);
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[mutData setLength:0];
NSLog(#"%#\n", response.description);
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutData appendData:data];
}
#end

You cannot change the Request Object with the same URL Connection once it is started. Read the documentation of NSURLConnection. it says:
The URL request to load. The request object is deep-copied as part of
the initialization process. Changes made to request after this method
returns do not affect the request that is used for the loading
process.
So if you want to hit another URL, you have to create a new URLRequest and new URLConnection object. regarding your question about saving cookies. you can set the cache policy of the URLRequest using the following method
- (void)setCachePolicy:(NSURLRequestCachePolicy)policy

Related

unable to load data from webservice into id type of variable

I am trying to load data from server into id result variable, my url is working perfectly i can see data on the browser, but the data loading process is very slow(15 secs ) and the result getting Output data id result is nil
Class: MyWebservices :-
-(id)getResponseFromServer:(NSString*)requestString
{
id result;
NSError *error;
NSURLResponse *response = nil;
NSURL *url = [NSURL URLWithString:[requestString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSData * resultData= [[NSData alloc]init];
resultData = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
Class: WebserviceCallingClass
- (void)viewDidLoad
{
id result = [AppDelegate.MyWebservices getResponseFromServer:urlString] ;
}
Use asynchronous request.
1) Use NSURLConnectionDelegate and declares
in your interface class a:
NSMutableData *_responseData;
2)Send your asynchronous request and set in timeout interval a time major than 15 seconds
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://uri"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20];
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[conn start];
3) Implement your delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
_responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
[_responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
//NSLog(#"cache");
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
}
}
or in synchronous request try to edit your NSMutableURLRequest
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.f];

Cocoa: POST headers/parameters lost when accessing protected resources in a Django site using NSURLConnection

I am trying to access protected resources on a Django site using NSURLConnection , OAuth2 Bearer token and HTTPS. I receive a token, which I then attach either to a GET parameter, POST parameter or header. I can access those URL:s which respond to GET parameter. But when I try to access urls using POST, the server returns me a 403 with a custom error message saying there is no header/post parameter containing the token. I have tried several solutions and HTTP libraries. This method uses AFNetworking, I tried it. We even changed the authorization to accept an alternative header due to warnings that apple does not like the modifying of "Authorization" header. My current code looks like this: (scheme == #"https")
-(void) logOut {
NSString *pget = #"/api/logout/";
NSString *path = [pget stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *absolutePath = [NSString stringWithFormat:#"%#://%#%#", scheme, host, path];
NSURL *url = [NSURL URLWithString:absolutePath];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
NSString *authValue = [NSString stringWithFormat:#"Bearer %#", accessToken];
[urlRequest setValue:authValue forHTTPHeaderField:#"Authorization_Extra"];
[urlRequest setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"content-type"];
[urlRequest setHTTPMethod: #"POST"];
/*
NSString *post = [NSString stringWithFormat:#"access_token_extra=%#", accessToken];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
[urlRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[urlRequest setHTTPBody:postData];
*/
NSDictionary* headers = [urlRequest allHTTPHeaderFields];
NSLog(#"headers: %#",headers);
_originalRequest = urlRequest;
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:NO];
[connection start];
}
#pragma mark NSURLConnection Delegate Methods
- (NSURLRequest *)connection: (NSURLConnection *)connection
willSendRequest: (NSURLRequest *)request
redirectResponse: (NSURLResponse *)redirectResponse;
{
if (redirectResponse) {
// we don't use the new request built for us, except for the URL
NSURL *newURL = [request URL];
NSMutableURLRequest *newRequest = [_originalRequest mutableCopy];
[newRequest setURL: newURL];
NSLog(#"New Request headers: %#", [newRequest allHTTPHeaderFields]);
return newRequest;
} else {
return request;
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
NSLog(#"Received response statuscode: %ld", (long)[response statusCode]);
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"connection finished:");
[_delegate handleData:responseData];
}
The _Delegate handleData parses the response, and the custom response is always that I am lacking either the header or post parameter needed for the Bearer token.
It seems that even though I am replacing the request with a mutable copy of the original on every redirect, the headers/parameters still get stripped by NSURLConnection. But why, and how, since I'm sending a copy of the original request every time and I verify by logging that they are there?

how to send data to url with POST Method in Xcode

I want to send one data with POST method to one url and received answer from that url.
I write this code for send data ("a") to this url ("http://www.test.com/test/msht")
this is my code but not working please guide me how to send data and give answer from url.
-(IBAction)btn_post_clicked:(id)sender{
//if there is a connection going on just cancel it.
[self.connection cancel];
//initialize new mutable data
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData = data;
[data release];
//initialize url that is going to be fetched.
NSURL *url = [NSURL URLWithString:#"http://www.test.com/test/msht"];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
//set http method
[request setHTTPMethod:#"POST"];
//initialize a post data
NSString *postData = [[NSString alloc] initWithString:#"a"];
//set request content type we MUST set this value.
[request setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
//set post data of request
[request setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
//initialize a connection from request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = connection;
[connection release];
//start the connection
[connection start];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.receivedData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"%#" , error);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//initialize convert the received data to string with UTF8 encoding
NSString *htmlSTR = [[NSString alloc] initWithData:self.receivedData
encoding:NSUTF8StringEncoding];
NSLog(#"%#" , htmlSTR);
}
My friend your code is wrong!!! you should determine name of post value in post NSString....
you don't send a value only.
you should write this code if get post method name in server is user :
NSString *post = [NSString stringWithFormat:#"user=a"];

Objective C NSURLConnection dosen't get response data

I am creating this application, it communicates with a PHP script on my web-server.
Last night it was working perfectly. But today two of the connections does not get response.
I've tried the NSURL link in my browser, it works fine. Also one of the connections work, but as i said two connections does not work?
- (void) getVitsTitelByID:(int)id {
NSString *url = [NSString stringWithFormat:#"http://webserver.com /ivitserdk.php?function=gettitelbyid&id=%d", id];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1.0];
connectionTitelByID = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
connectionDidReciveData:
if(connection == connectionTitelByID){
responseTitel = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
connectionDidFinishLoading:
if(connection == connectionTitelByID){
titelLabel.text = responseTitel;
}
I've tried and debugging it.
responseTitel seems to be (null).
Help would be apriceated :)
didReceiveData may be called N (several) times. save the data to a mutably data buffer (queue it up) and in didFinish read it into a string
mock code:
- (void) getVitsTitelByID:(int)identifier {
NSString *url = [NSString stringWithFormat:#"http://webserver.com/ivitserdk.php?function=gettitelbyid&id=%d", identifier];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1.0];
connectionTitelByID = [[NSURLConnection alloc] initWithRequest:request delegate:self];
dataForConnectionTitelByID = [NSMutableData data];
[connectionTitelByID start];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if(!data.length) return;
if(connection == connectionTitelByID)
[dataForConnectionTitelByID appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if(connection == connectionTitelByID) {
id str = [[NSString alloc] initWithData:dataForConnectionTitelByID encoding:NSUTF8StringEncoding];
NSLog(#"%#",str);
dataForConnectionTitelByID = nil;
connectionTitelByID = nil;
}
}

How to use the NSUrlConnection for getting the data from web?

In my application I want to use the NSURLConnection class. So please tell me how to use this one? This contain the lot of delegate methods, please tell me how to use them?
Initiate the connection using
self.responseData = [NSMutableData data];
NSURL *url = [NSURL URLWithString:#"http://sampleurl/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection autorelease];
and you can catch the response in the connectionDidFinishLoading delegate method
#pragma mark - NSURLConnection Delegate Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Connection failed: %#", [error description]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Getting your response string
NSString *responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
}
For your memory leak problem
Declare the response data in interface file
NSMutableData *_responseData;
with property as below
#property (nonatomic, retain) NSMutableData *responseData;
and synthesize it
#synthesize responseData = _responseData;
Dont release it anywhere (We have used convenient constructors for allocation). We have already set it to nil in connectionDidFinishLoading method.
In iOS 5 and OS X 10.7 or later you can load data asynchronously using the following:
NSURL *url = [NSURL URLWithString:#"http://sampleurl/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue]
completionHandler: ^(NSURLResponse * response, NSData * data, NSError * error) {
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse*)response;
if(httpResponse.statusCode == 200) {
//your code to handle the data
}
}
];
Or if you want to do it synchronously (not recommended if you are loading large data as it will hang the application) (available in OS X 10.2+ and iOS 2.0+)
NSURL *url = [NSURL URLWithString:#"http://sampleurl/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLResponse * response;
NSError * error;
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];