NSUrlRequest Not Working Objective C - objective-c

I am trying to use the code below to 'trigger' the web address. The web server doesn't return any data. But the NSURLConnection is being established.
NSString *serverAddressTest = #"http://domain.com";
NSString *fullWebAddress = [NSString stringWithFormat:#"%#?CustomerName=%#&ContactNo=%#&Products=%#",serverAddressTest,customer,contactnumber,allProductsInString];
NSURL *url = [NSURL URLWithString:fullWebAddress];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:url];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
NSMutableData *webData = [NSMutableData data];
NSLog(#"%#",webData);
}
else {
NSMutableData *webData = [NSMutableData data];
NSLog(#"%#",webData);
}

When you write:
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest
delegate:self];
you are starting an asynchronous url connection.
Then immediately after that you are testing whether the connection was successful or not and creating an instance of NSMutableData with local scope. Your NSURLConnectionDelegate methods (which you haven't posted) will not have access to this locally-scoped NSMutableData variable.
Have you indeed implemented the methods of the NSURLConnectionDelegate protocol?

Try to send synchronous request to localise the problem:
NSError *error;
NSData *returnData = [NSURLConnection sendSynchronousRequest: theRequest
returningResponse: nil
error: &error];
NSLog(#"error = %#, \ndata = %#", error, returnData);

You also need to also implement the delegate Protocols. ( As NSBum says)
Using Apples example
shown here is the data is returned when the parts are put together.:
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.apple.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [NSMutableData dataWithCapacity: 0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (!theConnection) {
// Release the receivedData object.
receivedData = nil;
NSLog(#"FAIL " );
// Inform the user that the connection failed.
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#" response %#", response);
// This method is called when the server has determined that it
// has enough information to create the NSURLResponse object.
// 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)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
// receivedData is an instance variable declared elsewhere.
[receivedData appendData:data];
NSLog(#" receivedData %#", receivedData);
}
receivedData is not local but declared elsewhere. (NSMutableData* receivedData;)
I do not use this much so cannot expand further without reading the docs fully myself; which is what you need to do. :-)

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];

Cannot call method in objective c

I'm having difficulty understanding how to call a method. Here's the code:
- (void)beachJSON
{
// Build the string to call Beach API
NSString *urlString = [NSString stringWithFormat:#"http://nrw-bwq-dev-api.azurewebsites.net/api/Pull"];
// Create NSURL string from formatted string
NSURL *url = [NSURL URLWithString:urlString];
// Setup and start async download
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Store incoming data into a string
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
results = [jsonString JSONValue];
}
- (NSArray *)getBeachList {
[self beachJSON];
return results;
}
I call getBeachList from another class to populate 'results', beachJSON is called fine but I need to call
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
Within
- (NSArray *)getBeachList
i.e. right here
- (NSArray *)getBeachList {
[self beachJSON];
//This is where I want to call it to populate results before it is returned
return results;
}
Calling getBeachList will call beachJSON but the connection method will be skipped over leaving 'results' nil
If i try simply putting
[self connection:(NSURLConnection *)connection didReceiveData:(NSData *)data]
I get a expected expression error on that line.
I'm pretty new to objective c so any help would be great.
You don't need to call this method.
It's a delegate method of NSURLConnection.
What you need is to set a delegate for connection and method will be called by connection when it downloads any data.
You should not call connection:didReceiveData: by yourself. This is an event which is only supposed to be fired by the NSURLConnection instance. As far as I can see the only thing you are missing is the start call, which actually makes the NSURLConnection perform the request.
Try this:
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
Then you should see that your NSURLConnection instance will call your implementation of connection:didReceiveData:.
If you want to be sure that your data is fully loaded you should be using this event instead:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
The connection:didReceiveData: will be called multiple times if your data size is large enough. Every time the NSURLConnection receives data it will invoke connection:didReceiveData:. connectionDidFinishLoading: will only be called once when all your data is ready.

NSURLConnection GET and POST not working

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

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];

Objective-C Asynchronous Web Request with Cookies

I am writing a program in Objective-C and I need to make web requests to web server, but asynchronously and I am fairly new on mac, I am very good at windows technologies, but I need to know that if I use NSOperation (introduced in 10.5, i am assuming that it will not run in 10.4 MAC?), or if it was implemented such that it utilizes system threading which will be available on 10.4?
Or I should create a new thread and create a new runloop, also how to use cookies etc, if anyone can give me one small example, that will be of great help. I want this sample to run on mac 10.4 too if possible.
There's a good example of using NSURLRequest and NSHTTPCookies to do a full web application example of logging into a website, storing the SessionID cookie and resubmitting it in future requests.
NSURLConnection, NSHTTPCookie
By logix812:
NSHTTPURLResponse * response;
NSError * error;
NSMutableURLRequest * request;
request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://temp/gomh/authenticate.py?setCookie=1"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60] autorelease];
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"RESPONSE HEADERS: \n%#", [response allHeaderFields]);
// If you want to get all of the cookies:
NSArray * all = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[NSURL URLWithString:#"http://temp"]];
NSLog(#"How many Cookies: %d", all.count);
// Store the cookies:
// NSHTTPCookieStorage is a Singleton.
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:all forURL:[NSURL URLWithString:#"http://temp"] mainDocumentURL:nil];
// Now we can print all of the cookies we have:
for (NSHTTPCookie *cookie in all)
NSLog(#"Name: %# : Value: %#, Expires: %#", cookie.name, cookie.value, cookie.expiresDate);
// Now lets go back the other way. We want the server to know we have some cookies available:
// this availableCookies array is going to be the same as the 'all' array above. We could
// have just used the 'all' array, but this shows you how to get the cookies back from the singleton.
NSArray * availableCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:#"http://temp"]];
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:availableCookies];
// we are just recycling the original request
[request setAllHTTPHeaderFields:headers];
request.URL = [NSURL URLWithString:#"http://temp/gomh/authenticate.py"];
error = nil;
response = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"The server saw:\n%#", [[[NSString alloc] initWithData:data encoding: NSASCIIStringEncoding] autorelease]);
For asynchronous requests, you need to use NSURLConnection.
For cookies, see NSHTTPCookie and NSHTTPCookieStorage.
UPDATE:
The code below is real, working code from one of my applications. responseData is defined as NSMutableData* in the class interface.
- (void)load {
NSURL *myURL = [NSURL URLWithString:#"http://stackoverflow.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:myURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (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];
[connection release];
// Show error message
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// Use responseData
[responseData release];
[connection release];
}
I am able to fetch cookie in such way:
NSArray* arr = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString: #"http://google.com" ]];
This one works fine for asynchronous request as well.