2

Is there a way to limit the bandwidth used by an NSURLConnection, or I'm forced to use CFNetwork methods?

1 Answers1

1

Yes, but it's not pretty (it works according to this mailing list post):

  • Start NSURLConnection on a background thread (you'll have to set up a run loop).
  • Sleep in -connection:didReceiveData:.
  • Forward your data to the main thread in a thread-safe fashion.

The third bulletpoint is a little tricky to get right if the delegate is a UIViewController, but something like this should work provided delegate is __weak or __unsafe_unretained:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
  [NSThread sleepForTimeInterval:...];
  [self performSelectorOnMainThread:@selector(notifyDelegateDidReceiveData:) withObject:data waitUntilDone:NO];
}

-(void)notifyDelegateDidReceiveData:(NSData*)data
{
  assert([NSThread isMainThread]);
  [delegate myConnectionWrapper:self didReceiveData:data];
}

Calculating how long to sleep for is non-trivial because you may wish to account for TCP/IP overheads, but [data length]+100 may be about right.

If you have multiple connections and you want to throttle the combined bandwidth, put them all on the same background thread/run loop (see -performSelector:onThread:withObject:waitUntilDone:).

For the CFNetwork version, I'm guessing you've read this post on Cocoa with Love.

tc.
  • 33,468
  • 5
  • 78
  • 96
  • Whoa, thank you for the amazing answer! As you said it's not pretty but I will try and see if it works reliably, if not I'm gonna stick with CFNetwork. Thank you again! – Enrico Ghirardi Nov 09 '12 at 20:22
  • @tc The NSURLConnection method doesn't really limit the download rate instead its going to slow down the storing of data in local buffer! we can't limit the data passed to `-connection:didReceiveData:` method. Can we limit the data read from socket, which is passed to `-connection:didReceiveData:` in some way? – bikram990 Sep 20 '13 at 07:23
  • @bikram990 I was hoping that it would do `read()` and `-connection:didReceiveData:` in the same thread. If not, then I'd see if ASIHttpRequest or AFNetworking supported rate-limiting; it might not be difficult to add support for it either. – tc. Oct 20 '13 at 14:29
  • @tc **ASIHttpRequest** can limit the rate as it uses `CFNetwork` directly but **AFNetworking** can't because it uses `NSURLConnection`. I looked into source of **AFNetworking**, it seems that it can limit the upload rate but i couldn't find a public interface for that in their examples. – bikram990 Oct 21 '13 at 03:35
  • @tc I'm a beginner in objective c. May be i missed something but AFAIK `NSURLConnection` can't limit download rate. – bikram990 Oct 21 '13 at 03:43