Episode #235

Working with the Pasteboard

17 minutes
Published on September 12, 2016

This video is only available to subscribers. Get access to this video and 582 others.

In this episode we take a look at UIPasteboard, allowing us to inspect, copy, and paste content on the system pasteboard as well as your own custom pasteboards. We'll also look at adding multiple representations of the same item to be a better OS citizen, for instance by copying rich text alongside plain text.

Episode Links

Get the System Pasteboard

let pasteboard = UIPasteboard.generalPasteboard()

Simple Copy/Paste with a String Value

let value = pasteboard.string
pasteboard.string = "new value"

Reading an Image from the Pasteboard

let imageTypes = UIPasteboardTypeListImage as! [String]
if pasteboard.containsPasteboardTypes(imageTypes) {
    for imageType in imageTypes {
        if let data = pasteboard.dataForPasteboardType(imageType) {
            if let image = UIImage(data: data) {
                // found image
                break
            }
        }
    }
}

Saving an Image to the Pasteboard

let image = imageView.image!
if let data = UIImagePNGRepresentation(image) {
    UIPasteboard.generalPasteboard().setData(data,
        forPasteboardType: kUTTypePNG as String)
}

Saving Multiple Versions of Text

let range = NSMakeRange(0, stringLabel.attributedText!.length)
let rtfData = try! stringLabel.attributedText!.dataFromRange(range,
    documentAttributes: [ NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType])

UIPasteboard.generalPasteboard().items = [
    [ kUTTypePlainText as String : stringLabel.text! ],
    [ kUTTypeRTF as String : rtfData ]
]

Reading When Multiple Items Exist

The methods containsPasteboardTypes: dataForPasteboardType: both only work with the first item in the pasteboard. If the pasteboard contains multiple items, we need to inspect all of them. Instead we'll use the variant of these methods that take an itemSet: parameter. We can pass nil to have it operate on all items.


// start first looking for RTF
if pasteboard.containsPasteboardTypes([kUTTypeRTF as String], inItemSet: nil) {
    if let data = pasteboard.dataForPasteboardType(kUTTypeRTF as String, inItemSet: nil)?.first as? NSData {
        let attributedString = try! NSAttributedString(data: data, options: [:], documentAttributes: nil)
        buildPasteLabel().attributedText = attributedString
    }
} 
// fall back to plain-text
else if pasteboard.containsPasteboardTypes([kUTTypePlainText as String], inItemSet: nil) {
    let string = pasteboard.valuesForPasteboardType(
        kUTTypePlainText as String, inItemSet: nil)?.first! as! String
    buildPasteLabel().text = string           
}

This episode uses Xcode 7.3, Swift 2.3.