Fun with Attributed Strings
- The Foundation AppKit Split
- Semantic Attributes
- Transforming to Presentation
- Generating XML
- Alternatives
NSAttributedString is probably the most underrated class in the whole of Cocoa. Most discussions briefly mention that it's for rich text, and then they move on to other topics.
Saying that the class is for rich text overlooks the fact that "rich text" isn't a particularly well-defined phrase. What is rich text? It's text with…something else. Typically, that "something else" might be font information or colors, but in fact it can be anything. NSAttributedString is exactly what it's name suggestsa string with some attributes. This class is incredibly flexible and powerful, but typically it's used only for very simple purposes.
The Foundation AppKit Split
It's telling that the NSAttributedString class is defined in the Foundation Framework, which doesn't contain anything related to user interfaces or fonts. Then it's extended by a category in the Application Kit Framework, to provide objects for working with RTF, HTML, and so on.
The core functionality of NSAttributedString is in Foundation, which is designed to be used for all kinds of applications, including things like headless web servers. In fact, with OS X, Apple moved the class one layer lower, into CoreFoundation, which is used by system dæmons and so on.
Although attributed strings are most commonly used for drawing text in AppKit, NeXT and Apple both thought that attributed strings should be made available in places where AppKit isn't being used, including on the iPhone, because these strings have a number of uses beyond text drawing.
Anytime you want to attach some metadata to text, you should consider using an NSAttributedString or its mutable subclass. They're designed to provide a mapping between ranges in an NSString and dictionaries. They also provide some convenience methods, splitting the dictionaries as required. For example, if you add an attribute in the middle of the range of an attributed string, the string will automatically generate three attribute runs.