Just wondering about this code below... when I turn off my internet connection and run it, I expected I would get "Connection failed" in my console log. Can anyone explain why I'm not? Thanks.
NSString *urlString = [NSString stringWithFormat:#"http://www.myurl.com/RSS/feed.xml"];
NSURL *serviceURL = [NSURL URLWithString:urlString];
//Create the request
NSURLRequest *request = [NSURLRequest requestWithURL:serviceURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
//Create the connection and send the request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//Make sure the connection is good
if (connection) {
//instantiate the responseData structure to store the response
self.responseData = [NSMutableData data];
}
else {
NSLog(#"Connection failed");
}
You haven't actually attempted to make the request yet. if (connection) doesn't test if the request was successful, it only tests whether or not you were able to create the object representing the connection. You still need to call one of the methods on it to make the request. See the documentation for details.
You're wanting to check to see if the connection itself failed, not the creation of the connection object, use the delegate, like so:
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog("Oh noes D=");
}
Related
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. :-)
I am developing a very simple application which accesses a written url. So i am wondering what is the difference between access by nsurlconnection and access by just using browser. cause some sites respond but they don`t send data when i used the nsurlconnection.
- (void)getWikiData:(NSString *)keyword{
NSString* tmpURL = #"http://wikipedia.simpleapi.net/api?keyword=";
NSString* encodedString;
CFStringRef strRef = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)keyword, NULL, (CFStringRef)#"!*'();:#&=+$,/?%#[]~", kCFStringEncodingUTF8);
encodedString = [NSString stringWithString:(NSString *)strRef];
CFRelease(strRef);
[tmpURL stringByAppendingString:encodedString];
[tmpURL stringByAppendingString:#"&output=html"];
NSURL *url = [NSURL URLWithString:tmpURL];
NSString *userAgent = #"Custom User Agent";
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
[request setValue:userAgent forHTTPHeaderField:#"User-Agent"];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response{
NSLog(#"Receive Response");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"Receive Data");
}
Thanks in advance.
The difference is in the user agent string of the resulting application. MobileSafari reports itself as "Safari, iOS like Mac OS X", however, a plain NSURLConnection sends a CFNetwork description, which is not very useful for most sites to do 'browser' (rather 'client') detection, that's why they may refuse to send data to an unrecognized user agent.
A quick question. I have the following code which gets the mod date of a file on a server:
- (void) sendRequestForLastModifiedHeaders
{
/* send a request for file modification date */
NSURLRequest *modReq = [NSURLRequest requestWithURL:[NSURL URLWithString:URLInput.text]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0f];
[[NSURLConnection alloc] initWithRequest:modReq delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
/* convert response into an NSHTTPURLResponse,
call the allHeaderFields property, then get the
Last-Modified key.
*/
NSHTTPURLResponse *foo = [(NSHTTPURLResponse *)response allHeaderFields];
NSString * last_modified = [NSString stringWithFormat:#"%#",
[[(NSHTTPURLResponse *)response allHeaderFields] objectForKey:#"Last-Modified"]];
NSLog(#"Last-Modified: %#", last_modified );
}
My main question is the following:
Does this call only send over the header? If the file is big I do not want the whole file being downloaded. That is why I'm checking the header.
+++++++++++++++++++++++++++++++++++++++
After the update this works...
Thanks now looks like:
NSMutableURLRequest *modReq = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: URLInput.text]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0f];
[modReq setHTTPMethod:#"HEAD"];
As you have it now, you're probably downloading the whole file. The key is the http method used for the http request. By default, it's a GET request. What you want is a HEAD request. You don't want the file, you just want the server to return the response that you would get if you did, right?
To do that, you want to use a NSMutableURLRequest and setHTTPMethod: to construct a request with a method of HEAD, instead of GET.
I am new to Objective C, so I'm not really even sure what this message means:
EXC_BAD_ACCESS
When executing the following code:
-(void)HelloWorld
{
NSURL *url = [NSURL URLWithString:#"http://example.com/service.asmx/HelloWorld"];
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL: url];
//do post request for parameter passing
[request setHTTPMethod:#"POST"];
//set the content type to JSON
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
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];
}
I'm attempting to integrate with the Json Framework.
I call HelloWorld, which executes an async request to my service. What's strange, is that it worked one time, and now I get this EXC_BAD_ACCESS message every subsequent time. Any ideas what would be causing this?
You shouldn't be releasing the request. It's already autoreleased.
EXC_BAD_ACCESS means you have a bad pointer. In your case, it's because you are releasing the request when it's already autoreleased.
There's also another problem with your code (unrelated to the crash). You create an NSURLConnection and immediately release the connection after creation. When creating an asynchronous connection, you should release the connection in the delegate methods (if connection fails or if connection did finish loading).
Hey, I have a program that needs to tell if an online image exists, but the only way that I've gotten this to work is by loading the image in a NSData pointer and checking if the pointer exists.
- (BOOL)exists {
NSString *filePath = #"http://couleeapps.hostei.com/BottomBox.png";
NSURL *url = [NSURL URLWithString:filePath];
NSData *imageData = [NSData dataWithContentsOfURL:url];
if (imageData) {
return YES;
}
return NO;
}
This has worked for me, but my problem is that I have a very slow connection, and it takes forever to download the image. So my question is: is there a way to put checking if a image (say "http://couleeapps.hostei.com/BottomBox.png") is available without having to download it in a Boolean reporter method?
Help is much appreciated
HiGuy
Create an NSURLConnection to fetch the url. Set the HTTPMethod of the NSURLRequest to "HEAD" instead of "GET". In the delegate method connection:didReceiveResponse: check the statusCode of the NSHTTPURLResponse for 200 or other success response.
-(void) queryResponseForURL:(NSURL *)inURL {
NSMutableURLRequest request = [NSMutableURLRequest requestWithURL:inURL];
[request setHTTPMethod:#"HEAD"];
NSURLConnection connection = [NSURLConnection connectionWithRequest:request delegate:self];
// connection starts automatically
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if ( [(NSHTTPURLResponse *)response statusCode] == 200 ) {
// url exists
}
}
There could be other status codes that you would treat as success, like 301.
Part of the HTTP protocol is setting the request method. GET and POST are the two most common, but there are several others including HEAD. HEAD says send the same response you would send for GET, but do not send the body. In your case the body is the image data. So if HEAD succeeds, you can assume that GET would also succeed in the same way, at least in the case of looking up a static resource.
connectionWithRequest is depreciated. So you have to use dataTaskWithRequest:
-(void) queryResponseForURL:(NSURL *)inURL {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:inurl
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setHTTPMethod:#"HEAD"];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSUInteger respCode=[(NSHTTPURLResponse *)response statusCode];
if ( !error&&respCode == 200 ) {
// url exists
} else {
// url does not exist
}
}];
[postDataTask resume];
}