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.
Related
I'm writing a standard NSURLConnection class for the App I'm working on right now which I will hopefully be able to use subsequent apps as well.
The idea is to able to pass a URL and a parameters array to a method in this class that will start the connection and then have it return the result when it is done.
-(NSData*)go :(NSString*)url :(NSArray)params
Since I'm calling this from another class I'd like to be able to set the result to a variable in that calling class.
NSData *result = [[connect alloc]go:testurl :testparams];
The problem is that the result doesn't arrive right away so when I return the NSData I have set in the "go" method it is blank.
I've tried a few things like NSCondition and running a while loop on another thread in the go method to check if it was finished.
Unfortunately, and I did not know this beforehand, the asynchronous connections form NSURLConnections run on the same thread as my NSCondition in the "go" method ran on. Because of this when I locked up that method so it didn't return early, I also locked up my connection so it never reached it's completion callback.
How can I effectively pause my "go" method long enough for my connection to finish so I can return the data to anywhere in my app.
There's a chance I'm going about this the completely wrong way so please let me know if that is the case. It does need to work kind of like this though because multiple requests will be going out at the same time and I'd like different instances of this connection class to be able to control them all.
I am creating an iOS app that consumes web services.
I have a class that makes the connections and stores the response in a variable. It also has a status variable where 1 indicates successful connection.
I have set up an NStimer and a function to check when the connection and download is done and if it was successful.
My question is:
Is this a proper way to manage the connection and its outcome?
any suggestions?
Here is the programming guide from Apple Developer website and it describes how to use NSURLConnection delegate. You can manage the received data in connectionDidFinishLoading: method. Notice that using these delegate methods will load data asynchronously. If you want to handle data synchronously, please try sendSynchronousRequest:returningResponse:error:, but this function should never be call in the main thread.
Which NSURLConnection wrapper handles GET and POST equally well ?
For GET method, I prefer google's GTMHTTPFetcher over ASIHTTPRequest. ASIHTTPRequest uses delegate, which probably the idea you will come up with normally. But that's the exactly reason I chose not to use it because when you have several connections(many connections in my case), then each connection has its own delegate and you end up with too many object. Or you can have just 1 delegate but you have find a way to find out which response is for which connection.
GTMHTTPFetcher handle this way much better in my opinion. It uses 1 SEL for 1 connection, sorta like target-action model. The code is much cleaner than delegate model.
But for POST method, ASIHTTPRequest has ASIFormDataRequest. I did not find an easy way to do POST with GTMHTTPFetcher. It does have setPostData method to set post data. But you have to set post body and those mime parameters by yourselves(from what I have see) And that's the headache. I find it has another class called GTMHTTPUploadFetcher. But I can't really figure out how to use it (I keep getting the NSAssert "need upload location hdr").
So for POST, I guess ASIHTTPRequest is easier.
I did not get a chance to use facebook-ios-sdk. And would like to hear other opinion about it.
So is there NSURLConnection wrapper handle both GET and POST well ? And any idea how to use GTMHTTPUploadFetcher?
The GTMMIMEDocument class is used to create a stream for uploading via GTMHTTPFetcher (or via anything else that takes an NSInputStream.) An example is here.
GTMMIMEDocument keeps a sparse list of the data parts to be uploaded, avoiding duplicating the data in memory.
I'm wondering if I'm able to time a thread to be executed repeatedly (like when using the scheduledTimerWithTimeInterval method in NSTimer).. I have a view controller, where there is a method I want it to be executed either manually (by clicking a button), or automatically (by timing the method execution). The problem is that, this method will connect with a remote server, and it will update the result on the view, so I don't want it to block the main thread (the view controller thread).
I don't know what to use, so if there's anyone knows how, please let me know :)
Thanks in advance..
It sounds like you might be using an NSURLConnection, and if that's the case, then as joshpaul noted, it will act asynchronously by default. That is to say, when you start the connection, the NSURLConnection object will create a new thread, do its work on that thread, and return results to you on the original thread via the delegate methods, cleaning up the second thread afterwards. This means that the original thread, main or not, will not be blocked while the connection does its work. All you have to do, then, is have your timer's action create and run the connection.
In other cases, you have a couple of options. It's easy enough to set up a timer method that will call another method to be performed in the background:
- (void)periodicMethodTimerFire:(NSTimer *)tim {
[self performSelectorInBackground:#selector(myPeriodicMethod:)
withObject:myPeriodicArgument];
}
This can make it difficult to get results back from the other thread (because you need to pass a reference to the original thread to the method). However, since you seem to be on the main thread to begin with, you can use performSelectorOnMainThread:withObject:waitUntilDone: passing NO for the wait argument to get back.
The more complicated option is to set up your own background thread with a timer running on it, but I'd be surprised if that was really necessary.
If you're using NSURLConnection, it's asynchronous. That'll likely work for your needs.
I have written an iOS app that calls NSUrlConnection multiple times to download image data from the web. Sometimes, one NSUrlConnection has not finished before the other starts. I am seeing corrupt jpeg data and I think it is because my didReceiveData delegate is saving data from two separate NSUrlConnections and munging the two jpeg data streams together into one data variable, hence causing the corruption.
My question is: what is the best way to avoid this? There doesn't seem to be a way to make each NSUrlConnection instance save to a separate data variable, or make each instance wait until the previous instance is done before saving.
My code basically follows Apple's example here except I call a loadData function multiple times which creates the NSURLRequest and NSURLConnection. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
Thanks in advance for any help.
When your delegate's connection:didReceiveData: method is called, you'll have the connection instance as the first parameter. So you'll need to use that to keep track of which connection just received data.
Apple's sample maintains one instance of NSMutableData. Your code will require several instances, one for each active connection.
Or, of course, you could have a separate delegate object (an individual instance) for each connection. That may be easier.