NSURLConnection returning zero length data - objective-c

I had async NSURLConnections working just fine when I was using my viewController as the delegate, have all sorts of connections now and I want to do them all through a singleton Connection object. So I'm having Connection create a new delegate object for each connection it makes. Connection is instantiated in the app delegate, but the +(void)send:(Message *) function probably terminates.
My feeling about how this works is that the delegate listeners get put in the run loop (I'm not totally clear on this but I think they're not in separate threads. Shouldn't matter because the delegates allocate their own responseData memory.) and the connectionDidFinishLoading executes just fine, but with an empty responseData. By that I mean I find myself in connectionDidFinishLoading but responseData has zero bytes.
Code creating the app delegate (in the send method) is:
ConnectionDelegate *delegate = [[ConnectionDelegate alloc] init];
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:delegate];
So my question is two folded:
Is the problem that the send method terminates? The delegate pointer has local scope.
If that's the problem, what can I do to keep the delegate alive?

You should double check your delegate's implementation of connection:didReceiveData:
Remember that you are responsible for collecting the incoming data segments there.
Please read Apple's doc(, especially URL loading system programming guide) and sample code again if any doubt.

Related

NSOperationQueue callback before an operation is started?

Is there a way I can find out if/when an operation is about to start/execute on an NSOperationQueue?
I am using NSURLConnection's setDelegateQueue: and I need to know when it fires.
In your NSOperation subclass add a copy property for a willStartBlock. At the beginning of main - before any other actions - call this block if it is set.
This way you can set up the actions to perform when the operation starts at the same time when you create the operation and before you put it into the operation queue.
The problem in your specific question is that you don't create the operations that are created on your queue. You can try to subclass NSOperationQueue and override the three public addOperation* methods. If you're lucky then one of these is the one that the NSURLConnection uses to append the callback operation to your queue.
May i know what exactly you want to do.
I am not sure what you want to achieve as it is not clear from your question but you can do something like that:
currentConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
if (self.operationQueue) {
[currentConnection setDelegateQueue:self.operationQueue];
}
[currentConnection start];
NSURLConnection gets invoked once start method gets called.
You can also subclass NSOperation and override start method.

In iOS does either NSURL or NSXML span a new thread?

I have a program that progresses as follows. I call a method called getCharacteristics. This method connects to a remote server via a NSURL connection (all networking code done in another file) and when it receives a response it makes a method call back to the original class. This original class then parses the data (xml) and stores its contents as a map.
The problem I'm having is that it appears that somewhere in this transaction another thread is being spawned off.
Here is sample code showing what I'm doing:
#property map
- (void) aMethod
{
[[WebService getSingleton] callWebService: andReportBackTo: self]
Print "Ready to Return"
return map;
}
- (void) methodThatIsReportedBackToAfterWebServiceRecievesResponse
{
//Parse data and store in map
Print "Done Parsing"
}
The problem that I am running into is that map is being returned before it can be fully created. Additionally, "Ready to Return" is being printed before "Done parsing" which suggests to me that there are multiple threads at work. Am I right? If so, would a simple lock be the best way to make it work?
NSURLConnection will execute in another thread if you tell it to execute asynchronously.
In my opinion the best way to deal with this would be to write your own delegate protocol, and use delegation to return your map when the you have downloaded and parsed your data.
You could retrieve your data synchronously using NSURLConnection, but you may force the user to wait for an extended period of time especially if a connection timeout occurs. I would avoid this approach.

Objective-C wait for asynchronous HTTP-Request to finish

I use the following code to execute a HTTP-Request:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
After that I want to use the received data. My problem is that i can't do this in connectionDidFinishLoading, but have to do this on another position in my code. As this is an asynchronous task, how can I verify that I don't start to use the received data before the task is completely done?
Thanks in advance,
Edit: My main problem is that the delegates are called after the code which uses the received data.
you just have to keep the received data in an ivar an use it whenever you want. if you really want to be sure, you can also use a BOOL set to YES in
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
don't forget that since iOS 5, the NSURLConnectionDelegate (and DownloadDelegate) have changed.
Download the AFNetworking library and use it for your connections. It has blocks methods, which (to me) are much 'cleaner' to use instead of delegate methods. AFNetworking is available on iOS 4 and higher.
https://github.com/AFNetworking/AFNetworking
Read this post on some basics of AFNetworking:
http://engineering.gowalla.com/2011/10/24/afnetworking/

simultaneous NSURLConnection by using unique delegates for each NSURLConnection

I am try to handle multiple NSURLConnection at the same time by using a different delegate for each connection, for each NSURLConnection I create, I create a new delegate object, but for some reason only one NSURLConnection works at a time, any NSURLConnection I try to start whilst one is already running simply do not start, my delegate does not receive any of the method calls connection:didReceiveResponse:, connection:didReceiveData:, connectionDidFinishLoading: or connection:didFailWithError:. Am I misunderstanding something about how NSURLConnection and its delegate works. Reading other posts most people seem to have a single delegate for all there connections and then use some kind of dictionary to get the right object to handle the right connection. Is that the way you have to do it.
What you are describing should work fine. You can have multiple NSURLConnections in flight at once, each with its own delegate.
If you want to know why your case isn't working, you'll probably need to show your code in your question.
I hope that at least answers the general question.

centralizing my objective C app's networking code

I am trying to centralize my app's networking code. Basically, in any of the various places that need information from a server, I create an object serverRequest of my class ServerRequest to get the information. When ServerRequest is done, it needs to send the information back to the calling object. Of course it should work asynchronously -- I don't want my app to grind to a halt while it is waiting.
This return of the information is the tricky part. It seems my options are delegation and notification. As far as I can tell, they both have their issues:
DELEGATION:
I pass myself off as a delegate to the serverRequest object. The problem is that if I am deallocated before the request completes, serverRequest will be messaging a deallocated object and my program will crash. To prevent this, I would have to keep track of all my server requests (there might be more than one) and let them all know in my dealloc method so that I don't get any more messages. All of this is possible, but it sure seems like a pain.
NOTIFICATION:
Seems like a lot of work to pass the information around. I have to add myself as an observer to the notification center, then remove myself when I deallocate. Furthermore, I have to pass into ServerRequest the information of what kind of notification to post when it is done. And I ServerRequest has to shove the received data into an NSDictionary, which I then get it back out of after it is passed.
Both methods ought to work, but they both seem like an awful lot of effort just to have ServerRequest wake up the calling code and pass it an object. I am thinking notification is a bit more flexible, a bit less of a pain, and a bit less likely to cause a crash, but I'm not really happy with either approach. Any feedback would be appreciated. Thanks.
I would go with the list approach. Just have a requestController containing an NSMutableArray that keeps track of all the requests. The advantage of this is that, when your controller gets deallocated, you can do something like [requests makeObjectsPerformSelector: #selector(cancelRequest)] to stop all those requests from hogging the network. It also helps in debugging, because you can actually ask each object what requests it has pending, gauge the performance impact of many pending requests etc. When a request finishes, the request controller can be informed and can remove it from its list with a simple removeObject.
Also, someone has to own your objects. In manually managed memory, ObjC objects can retain themselves, but if you ever want to move to GC, having an array is a much cleaner solution than CFRetaining free-floating objects.
You should not be retaining your delegates. see Checking for a valid delegate object before sending it a message
you can retain the delegate passed in and you would then not be de-allocated until the server request is also finished.
e.g.
#interface ServerRequest : NSObject
{
id delegate;
}
#property (retain) id delegate;
#end
#implementation ServerRequest
#synthesize delegate;
#end
But then you need to avoid releasing the ServerRequest from the other end, or you can make the initiator of the ServerRequest release it when it is itself released and that would take away the problem. To do that
#interface SomeObject : NSObject
{
ServerRequest getsomedata;
}
#property (retain) ServerRequest getsomedata;
#end
- (void)f()
{
[self setGetsomedata:[[ServerRequest alloc] init]];
[[self getsomedata] release]; // take away the refcount from allocating, setting the property will retain
}
I encountered similar problems in the past, but chose a slightly different design (similar to what #uliwitness suggested.
I choose to separate the request (i.e. the actual content) from the delivery system. In your case that would mean the serverRequest holds the content of the request (URL, data, etc.) but doesn't do the actual communication with the server. The delegate for the server request would be a singleton CommLayer class which will actually take care of sending the request, receiving it and notifying delegates about request completion.
So to send a serverRequest you would do call something like [CommLayer sendRequest:serverRequest withDelegate:myDelegate].
Now the CommLayer is the actual class that holds the delegate not the serverRequest, and you can always notify the CommLayer that your class is not valid anymore using something like [CommLayer removeDelegate:myDelegate]
Sure it's more work, but you really get a lot of benefits from this design, to name a few:
Real management of network traffic. You can decide how many open connection you want at once and queue requests.
You can cancel unneeded requests