Skip to main content

Pukka beta: Leopard reliability

Posted in

I've been hard at work trying to tackle some lingering Leopard stability issues with Pukka and believe that I have a solution. I'm releasing this fix as a prerelease (i.e. not advertised in the auto-update mechanism and not posted to the download sites -- please do not post it for me!) since the problems don't affect everyone and I'd like to have some feedback from those who are affected before making this version live.

Cut to the chase: download the prerelease version 1.6.6-pre2 for Tiger or Leopard. If you have any questions or concerns with this build, please contact me here.

(You may note that I'm using the same link for both OS versions -- I'm just trying to get some rudimentary usage stats by separating out the download URLs ;-)

If you're interested in some more technical info, read on.

It seems that Leopard has some lingering crash issues when using NSURLConnection, particularly when behind a proxy and/or using HTTPS and/or using authentication. Of particular concern are the last two conditions, as all Pukka traffic through del.icio.us, Ma.gnolia, and most alternative sites is over HTTPS with authentication. I have rarely been able to reproduce these crashes myself (which is the main reason I did not catch them in prerelease versions of Leopard), but I have received crash logs from issues with severity ranging from occasional problems to repeated crashing, including crashing on launch. Needless to say, this has been very frustrating.

Any other Cocoa programmers who use NSURLConnection will note that it is pretty much the way to do asynchronous downloads to memory (i.e. not to a file as NSURLDownload does) while easily working with requirements such as the ability to cancel, authentication, transparent proxy support, and cache management. I've been in a bit of a bind for a workaround, but after some discussions with (extremely helpful!) fellow Mac developers such as Daniel Jalkut, Jon Wight, and Fraser Speirs, I've settled on the solution of using CURLHandle routines in a dynamically loaded bundle when on Leopard for the time being, linking them against a Leopard-targeted CURLHandle framework to bypass cross-development issues with the framework. This required a fair amount of re-architecting since CURLHandle is not intended to be a drop-in replacement for NSURLConnection (in fact, it's a subclass of the Tiger-deprecated NSURLHandle class). It's a stable and reliable fix for Leopard until this bug is resolved, if not super-ideal for me as a developer. But them's the breaks!

For the reference of the Cocoa developers reading this, you can check out some bookmarks I've gathered (and will continue to gather) about issues with NSURLConnection over the years here and I've reported the Apple Radar bug and it resolves to the original at rdar://problem/5575834.

Update: I just released 1.6.6-pre2 to fix an issue that a couple people have noticed with double encoding of text when posting. The links have been updated above.

Trackback URL for this post:

https://codesorcery.net/trackback/96

That's funny, I just spent the weekend dealing with problems with NSURLConnection. Only in my case, it was with uploads, for which it's woefully inadequate. I couldn't quite wrap my head around whether CURLHandle was the right thing or not, so I dropped down into the HTTP stuff CFNetwork provides.

I've done a tiny bit with uploads, but using Web Services instead. You can check it out here. Not sure if that helps.

Um, why not just make your own MyURLConnection class that responds to all the selectors you need from NSURLConnection but is actually implemented using CURLHandle under the hood? Seems like that would be easier than "re-architecting" to use CURLHandle everywhere, and also easier to go back to NSURLConnection when Apple fixes the bug(s).

@David: This is more or less what I did -- I guess I didn't word it the best way. Although they differ in a couple ways (authentication is pre-set in CURLHandle vs. provided by a delegate method in NSURLConnection, for one), I basically masked this behavior by re-architecting CURLHandle to behave as NSURLConnection. Their delegate methods (although technically CURLHandle doesn't follow the delegate model, but rather a "client" model) are similar enough that this was doable. I still had to load the CURLHandle routines dynamically because they are linked against CURLHandle.framework and this was tricky to get working on both Tiger and Leopard as a universal binary while also linking properly based on different versions of libcurl. All in all, it was a lot more complicated because of this Leopard bug.

Hi Justin,

I think this release is totally broken, just sent you a link with a screenshot.

Greetings

@Patrick: I just uploaded 1.6.6-pre2, which should fix the encoding issue that you saw. You can re-download it at the link above. Sorry again for any inconvenience.

Seems to work now.

Hey Everyone,

You can add me to the list of people tearing their hair out over NSURLConnection. I'm trying to make an iPhoto plugin, which I didn't think would be ridiculously hard, but I'm running into all sorts of problems due to the plugin being in a panel and not in the main application thread. The delegates only seem to fire after the plugin panel is closed. I'm not using Leopard yet, and probably should, but I just don't understand why such a crucial set of tools is so poorly documented and broken. Seriously, googling NSURLConnection barely turns up any related info except the apple dev page, which I've re-read about four hundred times now.
Sigh.

@Greg: If you are using a sheet, make sure that you are using runModalSession: and not runModalForWindow: as the latter does not do any background processing while the application is modal. This would include delegate methods not being fired.

According to the docs for runModalForWindow::

Use this method in cases where you do not need to do any additional background processing while the modal loop runs. This method consumes only enough CPU time to process events and dispatch them to the action methods associated with the modal window. If you want to perform additional background processing, use runModalSession: together with an NSModalSession object instead.

@Justin,

Thanks, that's a really good lead. I don't understand however where runModalForWindow: would be called -- if it's iphoto that calls it to launch the export-plugin-window, then I don't really have any control over whether it's that or runModalSession, do I? Would breaking the URLConnection calls off into a separate thread avoid that problem alltogether, or would the delegates still get called from within the modal window?

Sorry everyone, I know this has gotten slightly off topic, but no other forums seem to know anything whatsoever about NSURLConnection.

Hmm, now you've got me -- I haven't really done anything with in-app plugins. I don't believe you'd have any control over the type of modal session that way. I'm not sure if NSURLConnection is thread safe, either -- see this:

http://lists.apple.com/archives/Cocoa-dev/2007/Mar/msg00179.html

Sorry I don't have any better info than that. In general, I've grown to like NSURLConnection, but it's just that Leopard has made it a real pain lately.

>> but it’s just that Leopard has made it a real pain lately.

Something to look forward to ;)

I'm keeping notes on what I'm finding out regarding NSURLConnections within plugins -- I figure sommeone might benefit and not have to go through the same struggles. If I do figure it out, I'll keep you all posted.

Thanks again for your time!

I had been using CURLHandle for ssl client certificates, now with leopard I am trying to fix what was working in tiger. Can you provide specifics on what you did to get CURLHandle to work under leopard. This is the only place that I have found that mentions CURLHandle working with leopard.

Thanks

@Jim: I did have to build the framework myself in Xcode 3 on Leopard, but I didn't really run into any problems that I can recall while doing that. Feel free to email me (see here) with any specifics and I'll try to help.