Reputation: 2912
Hi guys this will be my first post and am pretty new to Objective-C though not entirely new to coding. I've been doing a lot of reading and a lot of Googling and a lot of my answers have come from this site. So now I'm really stuck I figured it was about time I asked the experts.
I'm basically trying to get the raw HTML data from a given URL so that I can parse it for information. I have all the parsing sorted, and can retrieve the raw HTML however I'm struggling to understand how to get the program to stop while the data arrives from NSURLConnection
so I can use it. Currently my program whizzes past the connection and the holding String gets left as empty, until shortly after when its filled by the request. I believe I need to use a "Syncronous" connection but this is frowned upon because it freezes the UI while its processing the request. I'm trying to call it like this ....
urlData = [getURLClass getURL: @"http://www.google.co.uk"];
Hoping to get raw HTML in to the String urlData
so I can parse it.My current code from my class is below....
//Create the request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
//Open NSURLConnection with 'request'
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
//If we receive something
if (data) {
//Pass and decode to string
receivedData = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"Received HTML: %@", receivedData);
}
//Something went wrong
else {
// ToDO: Sort out any errors
}
}];
return receivedData;
When this is run the log shows "Received HTML: nil" and the return value is also blank, but if I wait a moment then call the class again its been filled with data from the previous request. I did try another method which the data was retrieved in to
-(void) connectionDidFinishLoading
But this leaves me the problem that I cannot "return" the data from the Method that was called. As I said I'm very new to Objective-C. I'm aware there are discontinued wrappers like ASIHTTPRequest
, but I'm sure there is a simpler answer to this than using someone else's class. It will also help me to learn if I can find an answer, I simply need to get the program to wait while the data is received before the class return it. I may be trying to run before I can walk with Obj-C, but my program is useless unless I can interact with the web.
Thanks in advance. Plasma
Upvotes: 0
Views: 4960
Reputation: 9346
You should be able to do what you want with the NSString function initWithContentsOfURL:
NSError* error;
NSString* htmlData = [[NSString alloc] initWithContentsOfURL:myURL encoding:NSUTF8StringEncoding error:&error];
It might also be NSASCIIStringEncoding for the encoding ... but in any case it gives you the string synchronously.
EDIT:
Corrected Spelling initWithContent*s*OfURL, added alloc
Upvotes: 2
Reputation: 912
I wrote a class file for this type of situation.
CAURLDownload.h:
http://localhostr.com/file/vGtIIpO/CAURLDownload.h
CAURLDownload.m:
http://localhostr.com/file/TAieiAE/CAURLDownload.m
Basically, you want to call
[CAURLDownload downloadURL:URL target:self selector:@selector(finishedSelector: connection:) failSelector:@selector(failureSelector:) userInfo:userInfo];
URL is an NSURL and userInfo is an NSDictionary.
Basically, you call that method with the appropriate parameters and execute your parsing in finishedSelector. Example:
[CAURLDownload downloadURL:[NSURL URLWithString:@"http://couleeapps.hostei.com"]
target:self
selector:@selector(downloadFinished:connection:)
failSelector:@selector(downloadFailed:)
userInfo:nil];
And for the methods:
- (void)downloadFinished:(NSData *)recievedData conneciton:(CAURLDownload *)connection {
//Parse recievedData
NSString *recievedString = [[[NSString alloc] initWithData:recievedData] autorelease];
//Etc.
}
- (void)downloadFailed:(CAURLDownload *)connection {
NSLog(@"Download Failed!");
//Do something
}
This has both the upsides of not locking the UI, being memory-friendly, and callable without a pointer required (singleton).
Upvotes: 1
Reputation: 7693
Unfortunately the SDK as supplied by Apple doesn't have any convenience functions to make this super simple. You have to do it all yourself using NSURLConnection. What I do is make a wrapper class that executes the NSURLConnection and then when the data is completely received it calls a completion block that you provide.
Upvotes: 0