NSURLConnection problems - objective-c

Hello my problem is that the delegates methods of my NSURLConnection are not being called, I read other post with the same problem but I can't fix this.
#implementation firstViewController
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[sendData sendValues];
});
end
other class
#interface SendInformation //this class extend NSObject<NSURLConnectionDataDelegate>
-(void)sendValues{
.......
NSURLConnection *conn = [[NSURLConnection alloc] init];
(void)[conn initWithRequest:request delegate:self];
}
end
The connection is working (I have all the delegate methods inside SendInformation.m) the problem is I never get a response, I read that you need to run the connection in the main thread, but if I do that, the interface will be freeze until the connection is done also I want the NSURLConnection in a different class.

Your code for creating the connection is strange. You want:
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
And of course self must implement all of the appropriate NSURLConnectionDelegate methods.

Related

Using data from delegate after NSURLConnection has finished

I've made an NSURLConnection, and made a seperate class to be used as a delegate, but I can't make use of the delegates data after the connection has finished. The data writes to console from within the delegate class, but not outside.
In the ServerCommunicationDelegate-class (the delegate), in method "connectionDidFinishLoading":
self.errorLog = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
NSLog(self.errorLog); // Prints the data to console
In the class where the connection takes place:
ServerCommunicationDelegate *del = [[ServerCommunicationDelegate alloc] init];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:del];
NSLog(#"Errorlog %#", del.errorLog); // Returns null
"errorLog" is a property of "ServerCommunicationDelegate".
Is there something I misunderstood about the delegation-paradigm here, or is it maybe something else I've missed?
Either way, thanks in advance.
NSURLConnection works asynchronously. The line
NSLog(#"Errorlog %#", del.errorLog); // Returns null
is executed before the connection has finished loading (probably before it even started
loading).

ios - Passing on data to another method - same viewController

Please see this code as an example:
-(void)generateConnection
{
NSString *urlString = #"";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"%#", connection);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *partialData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[_jsonContentForText appendString:partialData];
NSLog(#"%#", partialData);
}
Really for lack knowing what it is called, but after searching - a lot - I am unable to out what this process is called.
I need to know how -(void)connection: gets the information it needs from the previous method. I don't know if this is called passing on methods to another method, but I need to create another one, so I need to know where I can learn this.
Please spare me the lines like: You need to read up on objective-c and the general stuff, because those answers do not cover the specific need I have.
I do not mind reading up on it, as long as I know what I am reading explains this. However if in any kind hearts it is easy to explain, I will not reject that offer:-)
You need to read up on Delegates and Protocols. When you create the NSURLConnection and set self as the delegate, your new NSURLConnection object is told to query self (the object that created it) to do things like find out if authentication is supported, or what to do when it receives some data. For the NSURLConnectionDelegate specifically, if your delegate implements the methods defined in NSURLConnectionDelegate Protocol, they'll be called.
Some good sources to read up on Delegates and Protocols are:
Working with Protocols(Apple)
Delegates and Data Sources(Apple)
The Basics of Protocols and Delegates(Mobile Developer Tips)

Asynchronous NSURLConnection call

I am making a Asynchronous NSURLConnection call and downloading the data, how can I know when this thread is completed?
I am making this call from viewDidLoad, and obviously NSURLConnection is intuitively running in separate thread. So how would I know if the thread is completed and second wait until the thread gets completed to get the data pulled to the viewcontroller.
You will need to assign a delegate to the NSURLConnection that handles the processing and what-not of the data. Check out the documentation, it's pretty straightforward!
code speaks for itself
-(void) startRequest {
NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://stackoverflow.com"]];
[[NSURLConnection alloc] initWithRequest:req delegate:self];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
}

How to handle different requests using connectionDidFinishLoading in the same delegate?

Whenever I do a curl call using the below code:
NSURL *url = [NSURL URLWithString:requestURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:30];
if (connectionInProgress) {
[connectionInProgress cancel];
}
connectionInProgress = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
connectionDidFinishLoading is my final destination where I can manipulate the response data and call my next methods to continue with the app . If I hard-code some specific tasks like
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];
[parser setDelegate:self];
[parser parse];
[someLabel setText:parsedTextFromXMLData];
}
If I need to do another curl call to a different address, wouldn't someLabel setText always get re-set again? Is there a way to make this delegate function behave differently on each curl call? (btw, is connectionDidFinishLoading usually the right place to put the next step of codes?) If so then wouldn't it always get called again by the next curl call?
Have a look at this S.O. post for a recipe concerning NSURLConnection and multiple requests.The suggestion is doing something like this:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (connection == firstConnection) {
// do something
}
else if (connection == secondConnection) {
// do something else
}
}
EDIT: the idea here is that connectionDidFinishLoading is a method of your own delegate (so you write it). In the delegate, you store the address of each connection you create; then, when the connection comes back with the data, you tell which connection it is by comparing its address to the one you stored in the delegate. -END EDIT
Another option you have is using the ASIHTTPRequest framework, which offers a request-based (as opposed to connection-based) delegation mechanism, so each request has got a delegate object to handle the result; or, in other words, the delegate receives a reference to the request, so you can easily tell which request result you are handling.
ASIHTTPRequest offers a bunch of advantages over NSURLConnection. You can read about them in this S.O. post.
There're 2 options to do this:
you can implement a separate class, that will be responsible for handling NSURLConnection delegate stuff and create a separate instance for each request
you can use NSObject key-value methods on NSURLConnection instance for setting up some tag, that will be checked in connectionDidFinishLoading: method
For me, option 1 will be a better approach

Why release the NSURLConnection instance in this statement?

I read this in a book.
-(IBAction) updateTweets
{
tweetsView.text = #"";
[tweetsData release];
tweetsData = [[NSMutableData alloc] init];
NSURL *url = [NSURL URLWithString:#"http://twitter.com/statuses/public_timeline.xml" ];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
[activityIndicator startAnimating];
}
In this statement,is that correct to release the "connection" instance at that time? After releasing it which means this NSURLConnection instance will be destroyed since it's reference count is 0 ,how are we going to make this connection operation work after release this instance? THANKS.
I thought we should release it in one of the following callback methods,right?
connectionDidFinishLoading:
connection:didFailWithError:
It's actually fine to release it there, once the connection is sent out via initWithRequest, the only thing that matters is that the delegate exists or I believe the response will just be silently lost.
From what I can tell, the only reason to not release it there is if you want to call [connection cancel] at some point in one of the delegate functions, in which case it would be best to do what you suggest and release it in BOTH connectionDidFinishLoading and didFailWithError since only one of them will be called (right?).
Edit: For a more thorough answer, NSURLConnection initWithRequest is an asynchronous request. So it actually spawns it's own thread (but calls the delegate functions on the thread that called initWithRequest). So basically, on the thread that calls initWithRequest you are actually done with the connection object and you can release it. All the while it's doing stuff on some other thread that you don't need to be concerned with.
Also I should note that if you do release it there, make sure you DON'T release it in the finish/fail methods, because it won't be a valid object.