Easy Markdown Rendering With NSAttributedString on iOS 7

A little known addition to iOS 7 makes rendering markdown to a UITextView really simple. The UIKit Additions to NSAttributedString now includes a document type option called NSHTMLTextDocumentType that does exactly what you’d expect: it allows you to easily render HTML in a UITextView, UILabel, or UITextField. So if we combine the new document type with a markdown parser, we can go from this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
A First Level Header
====================

## A smaller header

**Now** is the time for all *good men* to come to
the aid of their country. This is an `NSAttributedString`.

Brought to you by [Eric Allam](http://twitter.com/eallam)

### Header 3

*   Candy.
*   Gum.
*   Booze.

![eallam twitter profile](https://si0.twimg.com/profile_images/3066111745/97865436e3ef039bc7c2420fe5be366e.png)

To this:

Alt Text

With only a couple of lines of code.

First, you need a markdown parser which will take a markdown formatted string and turn it into HTML. For this example we are going to be using MMMarkdown.

MMMarkdown makes it extremely simple to turn some markdown into HTML. If we had the markdown above in a file called Example.md in our project, you can turn it into HTML like so:

1
2
3
NSString *markdown = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Example" ofType:@"md"]  encoding:NSUTF8StringEncoding error:nil];

NSString *html = [MMMarkdown HTMLStringWithMarkdown:markdown error:nil];

Then, once you have the HTML, just create the NSAttributedString like so:

1
2
3
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};

NSAttributedString *preview = [[NSAttributedString alloc] initWithData:[_html dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:&error];

Now all you have to do is set the attributedText property on a TextKit backed view (e.g. UITextView), like this:

1
2
UITextView *liveView = [[UITextView alloc] init];
liveView.attributedText = preview;

This doesn’t mean the UITextView can display all the HTML you throw at it. Stylesheets have no effect (although certain CSS styles do seem to work, but it’s not documented anywhere what is supported and what is not). If you do want to display a full web page, you could of course always use UIWebView instead.

I’ve uploaded an example project that demonstrating how to put this all together called MarkyMark (the naming of this repo happened to coincide with a viewing of Pain and Gain).