0

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.

Jackson
  • 3,555
  • 3
  • 34
  • 50

1 Answers1

1

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.

Firoze Lafeer
  • 17,133
  • 4
  • 54
  • 48
  • Thanks! It won't be as easy as making a connection:didReceiveData1 and connection:didReceiveData2 method, one for each NSUrlConnection because there could be any number of NSUrlConnections going. How would you go about maintaining multiple instances of NSMutableData? Do I need to make an array of NSMutableDatas and have each connection write to it, or something like that? – Jackson Dec 05 '10 at 14:36
  • Also, I found a way to keep track of which NSUrlConnection is ending by using an NSMutableDictionary. At connectionDidFinishLoading I look up in a dictionary I made to see which connection has finished and update the correct view accordingly. Perhaps I can use that code to dictionary to handle the data as well...? Any suggestions on how I would go about that? – Jackson Dec 05 '10 at 14:39
  • Oh, I think I got it. What I did was create another NSMutableDictionary for recievedData NSMutableData *receivedData = [[NSMutableData data] retain]; [dataDictionary setObject:receivedData forKey:[theConnection description]]; That way received data has a corresponding connection that can be identified by the key [theConnection description]. Then in didReceiveData, I say: NSMutableData *receivedData = [dataDictionary objectForKey:[connection description]]; [receivedData appendData:data]; Etc. Does that sound like a reasonable solution? – Jackson Dec 05 '10 at 15:35
  • Yeah, something along those lines would work. Personally, I usually assign a unique lightweight delegate object to each connection. Then that delegate posts a final result (usually on the main op queue) so I can proceed with the final data or failure as needed. But the key is one small object per connection that does all the accumulation of data and has its own NSMutableData instance. Does that make sense? – Firoze Lafeer Dec 06 '10 at 03:19
  • I think so. I think everything is working too so thanks so much for your help. I didn't realize the formatting looked so bad in the comments section on this site, otherwise my last reply would have been more readable. – Jackson Dec 07 '10 at 16:51