Converting HTML to NSAttributedString, copy to Clipboard

Copying a string to the Clipboard using Objective-C is a simple two-line process. But what if you want to copy from an HTML source and maintain its color and formatting?

Doing this requires creating an NSAttributedString from the HTML, then converting it into an NSData object, and then passing it to the UIPasteboard using a Rich Text (RTF) type.

While solving this problem for a project, I pieced together the following code using a number of articles and Stackoverflow posts. Note the import of MobileCoreServices which allows access to the RTF type when setting the data to the clipboard.

#import "ViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard];
    
    // Sets up the attributes for creating Rich Text.
    NSDictionary *documentAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                        NSRTFTextDocumentType, NSDocumentTypeDocumentAttribute,
                                        NSCharacterEncodingDocumentAttribute, [NSNumber numberWithInt:NSUTF8StringEncoding],
                                        nil];

    // A sample of HTML that makes use of common CSS styles.
    NSString *clipboardText = @"<span style='color:blue;background-color:yellow;'>Blue text with yellow background</span>, and some plain text.";
    
    // Create the attributed string using options to indicate HTML text and UTF8 string as the source.
    NSAttributedString *atr = [[NSAttributedString alloc]
                               initWithData: [clipboardText dataUsingEncoding:NSUTF8StringEncoding]
                               options: @{
                                   NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                   NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
                               }
                               documentAttributes:nil error:nil];
    
    // Generate the Rich Text data using the attributed string and the previously created attributes.
    NSData *rtf = [atr dataFromRange:NSMakeRange(0, [atr length]) documentAttributes:documentAttributes error:nil];
    
    // Set the Rich Text to the clipboard using an RTF Type
    // Note that this requires <MobileCoreServices/MobileCoreServices.h> to be imported
    [pasteBoard setData:rtf forPasteboardType:(NSString*)kUTTypeRTF];
    
}

@end