Extracting Plain Text from an NSAttributedString
Jun 19, 2014 20:01

(Update from September 2014: it turns out simply calling the "string" method on the NSAttributedString works fine. For some reason it wasn't back when I first tried this and had to come up with this alternate approach. The alternate approach mostly works, but fails if you try adding attachments to the AttributedString. So - instead of all of the below, just use [richTextString string] and get on with the rest of your coding.)

I'm working on a major update to Remembary to support iOS7 and beyond. One of the most important new features is having the diary support full rich text and embedded attachments, with iOS7's enhanced use of NSAttributedString. Apple's rich text libraries are powerful, but they're quite complicated and seem to have accumulated a lot of extra cruft over the years.

After digging through the tutorials at raywenderlich.com, and even buying their book and going through the appropriate chapters, I've finally started getting the hang of working with NSAttributedStrings. I could add and remove formatting, and could even embed images.

There was one thing that continued to evade me, though: to ensure quick and easy searching and such, I need to be able to extract just the plain unformatted text from an NSAttributedString. The class has a handy "string" method, but the result includes all of the attribute information as well. I just wanted to get the plain text out.

Searching the internet and Stack Overflow didn't help me at all. People seemed to want to convert plain strings to attributed strings or attributed strings into HTML, but not to plain text. I thought I might be going crazy - surely I can't be the only one who has ever needed to do this?

I finally looked through some advice on turning attributed text into HTML, just to see the approach they used. Turns out it involves calling dataFromRange on an NSAttributedString while specifying a document type of NSHTMLTextDocumentType. I searched the official documentation for the document type values, and discovered it also included NSPlainTextDocumentType!

So after weeks of false starts and messy code and frustrating web searches, the solution turned out to be a mere four lines of code:

This is so simple it's hardly worth even mentioning - but I'm putting this here in case anyone else is similarly stuck. Warning: I just figured this out, so it's possible this doesn't work for everybody in all cases.

Previous:
My Year of "Hits" Part 2: Remembary Rolling
Feb 04, 2014 01:28
Next:
#deployaday, My Big Hairy Plan for 2015
Jan 11, 2015 14:34
Other Blog Posts
The Diary Diaries: Fixing Remembary's Facebook Connection Special Leap Day Edition of "Some Weird Things About Time" What's Up With Remembary Can't get pg_dump To Work Now That Heroku Has Upgraded Postgresql to 9.4? The Best Thing I Ever Did To Promote My App If You Build It, They WON'T Come #deployaday, My Big Hairy Plan for 2015 Extracting Plain Text from an NSAttributedString My Year of "Hits" Part 2: Remembary Rolling My Year of "Hits" Part 1: Remembary Rises (and Stumbles) Handy Little Test Method to Check for Translations in Rails Apps My Suddenly Slow-Waking MacBook Air Indie App PR: Keeping Control of Your Tone A Quick Note on 'clone' in Rails 3.2 My eBook Apps 2: iOS, JavaScript, and Ruby My eBook Apps 1: Introduction Quick Tip: No Sound on Mountain Lion My Upcoming Talk at PodcampHFX 2012: My Year of "Hits" starshipsstarthere.ca: Building at the Speed of Funny Screencast Tips Remembary's Cool New Picture Support Indie App PR 2: Keeping On Top Of User Feedback Indie App PR 1: How to Handle an App Disaster Giles Bowkett Diary Project 2 Remembary Video Congratulations! Welcome to Your Nightmare! How My iPad App Remembary Took Off Why You Should Have an App in the App Store (Even If You Probably Won't Make Any Money) PodCampHFX Remembary Presentation - Part 3 How I Used MailChimp Autoresponders to Promote Remembary PodCampHFX Remembary Presentation Part 2 PodCampHFX Remembary Presentation Part 1 Why AdWords Ads Don't Work for iPad Apps Remembary is Sponsoring PodcampHFX Why Can't I Resize my Views in Interface Builder? Momento and Remembary Concerning Remembary iPad-Friendly eBooks of Gracian's Art of Worldly Wisdom Project Report: PTOS2 A Quick Note on Encryption We're all LUsers Thoughts on HAML Friday Afternoon Hack - Getting Beyond the Basics Halifax Friday Hack and Back to Basics Quote from Wil Shipley FutureRuby Make Web Not War Busy Week I: Toronto Ruby Job Fair Employment.nil - the Toronto Ruby Job Fair Code Count: Ruby on Rails vs. C#/ASP.NET A Brief Note on Twitter The Hub Halifax and Mobile Tech for Social Change Deep Thoughts on Microsoft From The Accordion Guy The Two Kinds of Defensive Programming Presentation - Fixing Careerious: From C#/.NET to Ruby on Rails Enterprise! Presenting at Ruby on Rails Project Night - May 7th New Name and New Look for Careerious/Clearfit FutureRuby and More From Unspace Health Tips for Programmers This tables meme won't die Careerious - Ruby and Rails vs. C#/.NET Yeah I Use Tables For Layout, So Sue Me The Different Kinds of Done Giles Bowkett's RubyFringe presentation OfficeTime: Great Time-Tracking App for OS X Back With A New Look Non-DRY Feed torontorb Keeping Your Sanity With The Command Design Pattern shindigital Is All Grown Up! (according to the spambots) Startup Stars? I'm so bored! The Magic Words for RMagick Jennifer from Operations You see? Naming is HARD Business Software as Process Documentation Deployment note: 'execve failed' Steve Jobs on Market Research Why Canada Is Better for Entrepreneurs "Program first and blog second" Toronto Tech Collage The MacBook Air Is A Roadster RubyFringe! Quote of the Week: Steve Yegge Starting Up: Cards Great design tool: browsershots.org Starting Up: The Logo Quotes Of The Day: Hedge Fund Interview TSOT Ruby / Rails Presentation Night - Part 1 Moneyworks: Accounting Software for Canadians on OS X Starting Up: The Name Nice logo, but why is your site so bland? Welcome to shindigital.com