inessential by Brent Simmons

April 2008

SliverlightPlugin trying to catch up to Flash in crashiness?

NetNewsWire has a feature where it sends me crash logs (if the user clicks the send button) — so I see a fair amount of Flash crashes.

Stuff like this is not at all uncommon:

Thread 9 Crashed:
0   ???                           	0000000000 0 + 0
1   ...romedia.Flash Player.plugin	0x183c0795 Flash_EnforceLocalSecurity + 98669
2   ...romedia.Flash Player.plugin	0x180dc962 0x18000000 + 903522
3   ...romedia.Flash Player.plugin	0x180dd081 0x18000000 + 905345
4   ...romedia.Flash Player.plugin	0x180dd7b1 0x18000000 + 907185
5   ...romedia.Flash Player.plugin	0x1838f81c 0x18000000 + 3733532
6   libSystem.B.dylib             	0x9061dc55 _pthread_start + 321
7   libSystem.B.dylib             	0x9061db12 thread_start + 34

But lately I’m starting to see Silverlight crashes now too.

Thread 8 Crashed:
0	0x172e2b3b CMediaElement::Buffering(float) + 303
1	0x17625249 0x1729f000 + 3695177
2	0x172ecf25 CMFByteStreamOnStream::BeginRead(unsigned char*, unsigned long, IMFAsyncCallback*, IUnknown*) + 493
3	0x174264c8 CByteStreamCacheReader2::_BeginCacheItemRead(unsigned long long, int) + 286
4	0x174271b9 CByteStreamCacheReader2::BeginCacheRead(IMFAsyncCallback*, IUnknown*) + 297
5	0x173efdb8 CASFBytewiseMediaSource::AsyncReadData() + 216
6	0x173f02c8 CASFBytewiseMediaSource::DoReadPackets(CASFSourceOperation*) + 94
7	0x173f054b CASFBytewiseMediaSource::DispatchOperation(CBaseOperation*) + 83
8	0x1745b991 COpQueue::ProcessMarshalledOperations(IMFAsyncResult*) + 175
9	0x1765a62b COpQueue::ProcessMarshalledOperationsAsyncCallback::Invoke(IMFAsyncResult*) + 27
10	0x17477248 CCompletionPortNT::InvokeCallback(tagMFASYNCRESULT*) + 64
11	0x173dc238 CWorkQueue::CThread::ThreadMain() + 164
12  ...ple.CoreServices.CarbonCore	0x94395beb PrivateMPEntryPoint + 56
13  libSystem.B.dylib             	0x94f92c55 _pthread_start + 321
14  libSystem.B.dylib             	0x94f92b12 thread_start + 34

Etc. (There are a few others.)

I’ve said it before — one of my favorite things about the iPhone is no Flash. I will now add and no SilverlightPlugin.

(I hate when plugins crash my app. The user doesn’t know that it’s something other than my code that’s causing the crash, and it’s cold comfort anyway.)

Two secrets of Mac app design

1. Splitview resizing

Open Mail. Resize the window via the resize-thing at the bottom right corner of the window.

Note that the width of the source list (mailboxes and things) on the left stays at a constant width as you resize the window. (Same is true in iTunes and iPhoto. Colloquy and Coda. Etc.)

Note also that the horizontal splitter stays in the same place — the message view shrinks and grows, but the splitter stays in the same place.

It gives a feeling of physical stability, I think. For a counter-example, try Safari’s bookmarks manager — the source list on the left does not stay at a constant width as you resize the window. And it feels a little weird.

2. Source list x origin

Consider this detail from Mail’s source list:

Mail’s source list

Now consider this from an app made by an independent developer:

______’s source list

Set aside that the second app isn’t using the source list background color or selection gradient — note the extra outline between the selection and the window border.

Here they are blown up, so you can see what I’m talking about:

Mail’s source list blown up

______’s source list blown up

Here’s the secret: the x origin for the source list needs to be -1, not 0, to hide that outline. (Or maybe you can set it not to be bordered, or whatever — as long as that outline doesn’t show.)

libxml2 + xmlTextReader on Macs

I’ve used a few different XML parsers on Mac OS X—including CoreFoundation’s XML parser and NSXMLDocument.

But recently, for technical reasons, I couldn’t use any of the XML parsers I was already using. And, furthermore, I had reason to want to use a stream-based parser rather than a parser that builds a tree. (For better performance and lower memory use.)

I figured that probably meant using a SAX-ish API. (SAX == Simple API for XML) But I’ve never wanted to deal with SAX because it meant writing a bunch of code to deal with state, and that’s just a pain. (Honestly. No matter what Gus says.)

So I found my way to libxml2 and its SAX2 module. Eh, okay, I’ll do this, I guess. Maybe it’ll even be fun! (Really thinking, probably not fun.)

Then somehow I ran across the xmlreader module. It turns out to be exactly what I wanted—stream-based and fast—without being a big pain like SAX.

(It’s a clone of the xmlReader .NET interface. It’s possible that it’s very commonly-used in the Windows world.)

xmlTextReader works like this:

loop until done

Right. No callback functions (as in SAX). Just loop through the XML until you’re done.

See the Libxml2 XmlTextReader Interface Tutorial.

And here’s a demo project (BSTweetParser) that downloads the Twitter public timeline and parses it into Cocoa objects, an array of dictionaries. (Twitter stuff makes for great sample code.)