Using WebView in a Modal Dialog

| No Comments | 1 TrackBack

I’m not sure whether this is relevant to Leopard (a quick test just now suggested it might be) but it was certainly the case on Tiger: you can’t use a WebView in a modal dialog. At least you can’t if you want it to load the HTML for you. Why is that? Well the problem is with NSURLConnection. The way it works is that it uses the run loop on whatever thread you issue requests on to post notifications, and the problem with that is that when you’re running a modal dialog, the run-loop runs in a different mode which doesn’t handle NSURLConnection events.

It’s probably not the most elegant or simple solution, but I thought I’d try and get round the problem by creating some proxy objects and running NSURLConnection in its own thread (and therefore not suffer any issues with the run-loop not being in the right mode). I did this more as an intellectual exercise (some time ago) and didn’t really intend to use it, although I did use it in the end.

OK, so you might thing that this sounds like something we could use Distributed Objects for: it can set up proxy objects for you and do all the necessary work for us. That’s what I thought initially but then I stumbled on a couple of problems:

  1. The modal event loop, in addition to not handling NSURLConnection events, also doesn’t handle events for Distributed Objects so any delegate events that occur don’t make it to the main thread. We could fix that by using performSelectorOnMainThread: to run a method that runs the run-loop in a suitable mode (e.g. NSConnectionReplyMode) but there’s a more serious problem:

  2. There are some strange interactions between NSURLConnection and the run-loop. If you try and set up an NSURLConnection via Distributed Objects, you’ll find it won’t schedule itself in the run-loop correctly and you’ll never see any delegate methods called.

One way round this is to roll our own mechanism for marshalling methods between the main thread and the worker thread. This sounds difficult but in fact it’s quite easy since we don’t actually have to worry about encoding NSInvocation objects like Distributed Objects does: we’re just passing them to another thread.

Anyway, here’s the code (ZIP) available under an MIT style license. If you want to just look at the code, it’s here. If you use this, bear in mind that things may break in future since using using a WebView in a modal dialog is not officially supported by Apple.

1 TrackBack

Chris, who has been working with me at Coriolis for some time now has recently set up a weblog (something which I think is long overdue, frankly), and has posted a short piece about using WebView in a modal dialog,... Read More

Leave a comment