Seems like a good idea that would be useful even outside of HotCocoa. Especially for simple cases, I think if Obj-C had blocks, this would be a good place to use them. For more control, the delegate pattern actually works really well. It's good that you have a way to do both. Does the delegate object also receive messages that would be sent to an NSURLDownload? That might be a nice way to allow easy integration in cases where an object that responds to the delegate methods is defined in Obj-C. Also, regarding multi-threading, couldn't you just use NSURLDownload (which you're probably already using underneath) + NSOperation/NSOperationQueue. Since your #download method already wraps the underlying process, you could should able to generate NSOperations to perform the downloads and add them to a queue. Those classes handle creating threads (which have their own runloops) and performing a task on the thread. That said, maybe this approach would not work with the current IO implementation? Brian 2009/3/30 Matt Aimonetti <mattaimonetti@gmail.com>:
In my free time, I've been working on a http://lighthouseapp.com client app which mixes API calls with webkit views (I'll release the source code later on). The app is 100% HotCocoa (meaning that I didn't use any nib/xibs). For people who are not used to work with delegation, having to deal with file download, URL queries can be a bit challenging if you want to start using the underlying obj-c methods.
That's why I wrote a small HTTP wrapper to clean up my code and make download/queries easier. The library is divided in 2 major parts, a helper and the Query/Response classes.
Here is how the helper looks like so far:
Download helper making file download trivial Pass an url, and a block or a delegator A block takes precedence over a delegator, meaning that you can't pass a delegator and use a block, you have to choose which approach to pick.
==== Parameters url<String>:: url of the resource to download options<Hash>:: optional options used for the query &block<block>:: block which is called when the file is downloaded
==== Options :method<String, Symbol>:: An optional value which represents the HTTP method to use :payload<String>:: - data to pass to a POST, PUT, DELETE query. :delegation<Object>:: - class or instance to call when the file is downloaded. the handle_query_response method will be called on the passed object :save_to<String>:: - path to save the response to :credential<Hash>:: - should contains the :user key and :password key By default the credential will be saved for the entire session
TODO :progress <Proc>:: Proc to call everytime the downloader makes some progress :cache_storage :custom headers Error handling
==== Examples
download("http://www.macruby.org/files/MacRuby%200.4.zip", {:save_to => '~/tmp/macruby.zip'.stringByStandardizingPath}) do |macruby| NSLog("file downloaded!") end
download "http://macruby.org" do |mr| # The response object has 3 accessors: status_code, headers and body NSLog("status: #{mr.status_code}, Headers: #{mr.headers.inspect}") end
path = File.expand_path('~/macruby_tmp.html') window :frame => [100, 100, 500, 500], :title => "HotCocoa" do |win| download("http://macruby.org", {:save_to => path}) do |homepage| win << label(:text => "status code: #{homepage.status_code}", :layout => {:start => false}) win << label(:text => "Headers: #{homepage.headers.inspect}", :layout => {:start => false}) end end
download "http://macruby.org/users/matt", :delegation => @downloaded_file, :method => 'PUT', :payload => {:name => 'matt aimonetti'}
download "http://macruby.org/roadmap.xml", :delegation => self
download "http://localhost:5984/couchrest-test/", :method => 'POST', :payload => '{"user":"mattaimonetti@gmail.com","zip":92129}', :delegation => self
download("http://mysite.com/login", {:credential => {:user => 'me', :password => 's3krit'}}) do |test| NSLog("response received: #{test.headers} #{test.status_code}") end
As you can see from the example list, the method name download isn't always appropriate and maybe I should give it the http_query alias. What do you think? What's nice with this approach, is that on top of being simple, the query and the response handling are async so the rest of your code can be run and you get notified only when the response comes back.
The underlying API looks like that: MacRubyHTTP::Query.new( url, http_method='GET', options={} ) Queries don't run in a custom runloop yet but that's something I want to look at once IO work on the experimental branch will be done.
So, here is my question, do you guys think that this is something that should be part of HotCocoa or it's better if it stays its own separate lib? Also, what do you think about having a default vendor folder for hotcocoa apps and autoload the vendor files if available?
- Matt
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel