0

I'm finding my way around AppleScriptObjC and have found Shane Stanley's Everyday AppleScriptObjC helpful. But I'm still having a hard time knowing where to start with NSPasteboard.

Here's what I have so far:

use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions

on readClipboard(theClipboard)
    set theClipboard to current application's NSPasteboard
    return theClipboard as text
end readClipboard

set theContents to missing value
its readClipboard(theContents)

Of course this doesn't work. But it does seem to be doing something.

It returns:

error "Can’t make «class ocid» id «data optr000000002852F974FF7F0000» into type text." number -1700 from «class ocid» id «data optr000000002852F974FF7F0000» to text

Any pointers would be greatly appreciated.

tdnelson2
  • 555
  • 1
  • 4
  • 13
  • Any reason for not just using Standard Additions' `the clipboard` command? – foo Mar 25 '15 at 07:41
  • I should have framed the question around retrieving program specific data from the clipboard and reading it as text. `the clipboard` doesn't do that. – tdnelson2 Mar 25 '15 at 18:26

2 Answers2

0

The NSPasteboard is a container which is able to hold many different items of different kinds. There are a few standard pasteboards defined like NSGeneralPboard, NSRulerPboard or NSDragPboard. For copy and paste actions the general pasteboard is used.
The item stored inside the general pasteboard may differ also. It's possible to store public.rtf, public.jpeg etc. inside a pasteboard.

Putting it all together we get this solution:

    set theClipboard to current application's NSPasteboard's generalPasteboard's stringForType:(current application's NSPasteboardTypeString)

Have fun, Michael / Hamburg

ShooTerKo
  • 2,242
  • 1
  • 13
  • 18
  • Nice. That is tremendously helpful. What if there is an application specific item on the clipboard such as `com.apple.flexo.proFFPasteboardUTI`? How do I specify that UTI and how do I read it as text? Would that somehow involve the `readingOptionsForType` method? – tdnelson2 Mar 25 '15 at 15:57
  • It depends on how the data is written to the clipboard. Most command-c actions writes more than one appearances of the data into the clipboard. Example: If you select a file inside the Finder, the file itself is copied as well as the file path. If you paste it inside the Finder, it uses the file, if you paste it in Outlook, it pastes the file path. I could imagine that your app fills the string value too! – ShooTerKo Mar 25 '15 at 16:01
  • This is data from Final Cut Pro X and as far as I can see from using [ClipboardViewer](https://developer.apple.com/library/mac/samplecode/ClipboardViewer/Introduction/Intro.html) there is only one item on the clipboard. It appears to be mostly xml. – tdnelson2 Mar 25 '15 at 16:39
0

It can depend on what type of data is in the clipboard. But, you can (usually) check which types of data are in the clipboard by using the AppleScript command clipboard info. That will give you a list of the available types. So, for example, if you copy some styled text from TextEdit and run clipboard info, you will see something like this:

{{«class RTF », 615}, {«class utf8», 220}, {«class ut16», 442}, {string, 220}, {Unicode text, 440}}

Then, you can get a specific type of data like this: get the clipboard as «class utf8»

Now, on to the more complicated part of your question, where the app putting objects into the clipboard is using a non-text format. I don't have Final Cut Pro available to see what it puts in the clipboard, but the app FileMaker Pro can copy various objects, and it puts them into the clipboard as data that can be converted to XML. One way to convert such a data object into simple text XML is like this:

set dataObject to get the clipboard as «class XMSS» -- FileMaker script steps
set tempDataPath to ((path to temporary items) as string) & "tempfile.data"
set someHandle to open for access file tempDataPath with write permission
tell application "System Events"
    write dataObject to someHandle
end tell
try
    close access file tempDataPath
end try
tell application "System Events"
    set dataAsXML to read file tempDataPath as «class utf8»
end tell
return dataAsXML

Now, to figure out what to use with get the clipboard as… you would need to copy the object you want, then run clipboard info to see what the data type is (in my example, XMSS). AND, note that you might get lucky and only need that single line of AppleScript, if the result is in plain text (in your case, possibly plain text XML). But, if you get a result like «data CODE…bunch_of_hexadecimal», then "CODE" is the data type you would use in the get the clipboard as «class CODE» command, and you would need to convert that hexadecimal into text. This sample is a boiled-down version of what I built in FmClipTools, in the dataObjectToUTF8 function of fmObjectTranslator, found at: https://github.com/DanShockley/FmClipTools/blob/master/Scripts/fmObjectTranslator.applescript You can look there if you want to see the kind of error-trapping and more complicated options that might be useful. Final caveat: Every now and then, I've run into clipboard data types that cannot be read this way.