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 Source Code UIPasteboard System-Defined Uniform Type Identifiers JRNPasteboardMonitor 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 }