Search code examples
httpasynchronousgrand-central-dispatchrubymotion

Why does my HTTP request (bubble wrap) fail to execute in a Grand Central Dispatch queue?


I am doing this inside my RubyMotion application:

Dispatch::Queue.concurrent('google').async {
  BubbleWrap::HTTP.get("http://google.com") do |response|
    p response.body.to_str
  end
}

This call does not complete.

However if I take the BubbleWrap code outside of the Dispatch queue, it completes fine.


Solution

  • BubbleWrap::HTTP is an abstraction over NSURLConnection, which depends on a RunLoop for its asynchronous processing. Unfortunately RunLoops aren't set up on GCD queues, and I haven’t figured out how to start a runloop on a GCD queue. When I've needed the above, I've resorted to instantiating a new NSThread, and started the run loop manually instead:

    action = lambda do
      runLoop = NSRunLoop.currentRunLoop
    
      BW::HTTP.get("http://www.google.com") do |response|
        NSLog("Fetched Google!")
      end
    
      runLoop.run
    end
    
    thread = NSThread.alloc.initWithTarget action, selector:"call", object:nil
    thread.start
    

    This answer is a rehash of my blogpost on the same topic and Cocoa In The Shell