Convert NSAttributedString to string and back

cocoa, nsattributedstring, nsstring, objective-c

Solution

You said you created your input string from an existing `NSAttributedString` like this:

[NSString stringWithFormat:@"%@", nsattributedstring]

The `%@` format specifier sends the `description` message to the `nsattributedstring` object. The `description` method is not designed to produce a string that can be easily converted back to an `NSAttributedString` object. It is designed to help programmers debug their code.

The process of converting an object to a string, or an array of bytes, so that it can be converted back to an object later, is called serialization. Using `%@` or the `description` method is generally not a good way to perform serialization. If you really want to deserialize the string created by the `description` method, you'll have to write your own parser. As far as I know, there is no API for that.

Instead, Cocoa provides a system designed to serialize and deserialize objects. Objects that can be serialized using this system conform to the `NSCoding` protocol. `NSAttributedString` objects conform to `NSCoding`. So try serializing your original attributed string this way:

NSMutableData *data = [NSKeyedArchiver archivedDataWithRootObject:nsattributedstring];

Save `data` (which is non-human-readable binary, not UTF-8) wherever you need to. When you need to recreate the attributed string, do this:

NSAttributedString *fancyText = [NSKeyedUnarchiver unarchiveObjectWithData:data];

If you are programming for OS X (not iOS), you have an alternative. You can turn an attributed string into RTF (rich text format), which is fairly human-readable, using the `RTFFromRange:documentAttributes:` method (which omits attachments) or the `RTFDFromRange:documentAttributes:` method (which includes attachments). Then you can turn the RTF data back into an attributed string using `initWithRTF:documentAttributes:` or `initWithRTFD:documentAttributes:`. These methods are not available on iOS.

If you are programming for iOS 7.0 or later, you can use `-dataFromRange:documentAttributes:error:` or `fileWrapperFromRange:documentAttributes:error:` to convert the attributed string to RTF/RTFD. You need to set `NSDocumentTypeDocumentAttribute` to `NSRTFTextDocumentType` or `NSRTFDTextDocumentType` in the document attributes. Use `initWithData:options:documentAttributes:error:` or `initWithFileURL:options:documentAttributes:error:` to convert back to an `NSAttributedString`. These methods are part of the NSAttributedString UIKit Additions.

Problem

I have NSString and I need to make NSAttributedString. NSString is something like: ``` bvcx b vcxbcvx bcxvbcxv bvx xbc bcvx bxcv bcxv bcxv bcxv bcvx bcvx bcxvbcvx bvc bcvx bxcv{ NSFont = "\"LucidaGrande 24.00 pt. P [] (0x108768a80) fobj=0x108788880, spc=7.59\""; NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0.05, HeaderLevel 0"; } ``` It's NSAttributedString in UTF-8. Is there any way how to do that?

Original source