2

I'm trying to script iTunes from NSAppleScript in my Cocoa app in order to add a file to the library.

In my entitlements file, I added the following:

<key>com.apple.security.scripting-targets</key>
    <dict>
        <key>com.apple.itunes</key>
        <array>
            <string>com.apple.itunes.library.read-write</string>
        </array>
    </dict>

I then call the AppleScript like this:

var error: NSDictionary? = nil
let appleScript = NSAppleScript(source: "tell application \"iTunes\" to add (POSIX file \"\(path)\") to library playlist 1")
let result = appleScript?.executeAndReturnError(&error)

but it fails with an error -10004: iTunes got an error: A privilege violation occurred.

I tried capitalizing iTunes both ways (itunes and iTunes) but nothing seems to work. I also tried adding, on top of the read-write entitlement, the read entitlement. Finally, I tried adding read and write access to the user's Music folder (where the iTunes library is stored) and this didn't help either.

Is there another required entitlement that I'm not aware of in order to script iTunes?

I found this link in my search for a solution (link) but it requires the user to select a specific folder in his Library folder to give the application user-selected file access and then it requires the script to be in a separate file which is 2 things too many for what I want to do. I don't trust the user regarding the management of the script files and I don't need a file for 1 line of AppleScript code. Another disadvantage, as I understand NSUserAppleScriptTask is that you can't persist a script's state across multiple calls, which is not a problem in my case but could be for someone else.

Thanks

beeb
  • 1,187
  • 11
  • 32
  • I guess the privilege error comes from the location on disk rather than from the Apple Event sent to iTunes. In a sandbox environment `NSUserAppleScriptTask` and `Application Scripts` folder is the preferable way to execute scripts. – vadian Dec 09 '15 at 08:21
  • I should have mentioned that I also tried adding to the entitlements full read and write access to the Music folder and it didn't help. I'm editing now. Also, why would iTunes and other scriptable apps have scripting entitlements if I can't use them in my application? – beeb Dec 09 '15 at 10:55
  • I just tried adding the `com.apple.security.temporary-exception.apple-events` entitlement with a key `com.apple.itunes` and now the script works, but I am wondering if this is the way to go? **Temporary** means what it means right? Since iTunes is scriptable and has permissions sets I should not need it. – beeb Dec 09 '15 at 11:05
  • I assumed that you did that anyway. A temporary exception is required to talk to an application. Nevertheless `NSUserAppleScriptTask` is more convenient because you don't need any Apple Event entitlements at all. – vadian Dec 09 '15 at 11:17
  • It is convenient for me but not for the user, who has to choose the Application Scripts folder to grant access to it inside the sandbox. Anyway I should not need that: "Your app cannot, however, send Apple events to other apps unless you request a scripting-targets entitlement **or** an apple-events temporary exception entitlement." - https://developer.apple.com/library/mac/qa/qa1888/_index.html – beeb Dec 09 '15 at 11:33

1 Answers1

5

After contacting the Developer Technical Support of Apple, I was able to solve this problem, which is actually 2 problems in one.

First, the entitlements need to have the bundle identifiers properly cased. For iTunes, the entitlements must be like this (note the capital T in iTunes):

<key>com.apple.security.scripting-targets</key>
<dict>
    <key>com.apple.iTunes</key>
    <array>
        <string>com.apple.iTunes.library.read-write</string>
    </array>
</dict>

Then, the privilege violation will occur unless the AppleScript code includes of source 1 at the end like this :

tell application "iTunes" to add (POSIX file "your/path/to/mp3.mp3") to library playlist 1 of source 1

There you go!

beeb
  • 1,187
  • 11
  • 32