The Curious Case of HTML with NSAttributedString

Why You Should Read Official Documentation And StackOverflow Together

Joseph Quigley
Quigs.blog
3 min readAug 2, 2016

--

Maybe it’s because I’ve tinkered with libraries and projects that have little-to-no documentation. Or perhaps it’s because StackOverflow is easier to search and read because the documentation wording doesn’t lend itself to searches with questions in them.

Precondition

At any rate, I found myself needing to convert basic HTML to an NSAttributedString with no idea how to do it, and having to write it from scratch (no libraries or copied code). A quick Google search on “NSAttributedString html” limited to http://developer.apple.com revealed a hit, but when I visited the page, I couldn’t find anything related to HTML on the page because the relevant constructor description was collapsed.

No results on this page.

Since I know tons of apps probably use HTML to mark up their content across platforms, I knew that StackOverflow would help me get an answer. And it quickly did:

Plenty of results on StackOverflow, even semi-recent ones.

Sadly, I was not wise enough to go back to the Apple docs to read up on the NSAttributedString with NSData constructor. This caused me to miss out on some important information once I ran my app. To make matters worse, I needed to tweak some formatting after the HTML importer finished, so I switched to NSMutableAttributedString which really reduced the matching search terms when I ran into The Problem.

The rich text content I was displaying was going in a UITableViewCell and it looked and worked great until I scrolled the content off screen, then scrolled back, and the cell got recycled. Boom. Insta-EXC_BAD_ACCESS. Since I had switched to NSMutableAttributedString the majority of my web searches weren’t turning up anything useful (to me).

I finally kept digging (after tweaking my code for a cumulative of a couple hours) and eventually found this StackOverflow thread which linked back to an Apple class reference that said that you need to make sure you’re not running the importer on a background thread. The HTML importer uses a non-thread-safe WebKit importer and expects to be on the main thread. I didn’t think I was running anything on a background thread, but lo and behold, deep in the bowels of the app I was doing some threading to NSOperationQueue up adding cells to my data source and insert them into the table view after other events.

Postcondition

I’m not entirely sure why I was getting this error, as I was doing all my cellForRowAtIndexPath configuration and initialization for the cell on the main thread, but somewhere in some abstraction layers I was moving stuff between threads right when the importer needed to be on the main thread during the draw call.

At a coworker’s suggestion we moved the NSMutableAttributedString allocation to the model layer which ran on the main thread and everything started working like magic.

What happens when you’re debugging in a multithreaded environment without realizing it.

The moral of this story is, even though API documentation doesn’t always get indexed the way you wrote out your search query, always refer back to the documentation if you do find an answer on a Q&A website. Chances are you are missing something rather important, especially when threads are concerned!

What tricks or gotchas have you encountered when dealing with NSAttributedString or NSMutableAttributedString?

--

--