1

I'm trying to write an application that interacts with iTunes via ScriptingBridge. I works well so far, but the options of this method seem to be very limited.

I want to play song with a given name, but it looks like there's no way to do this. I haven't found anything similar in iTunes.h…

In AppleScript it's just three lines of code:

tell application "iTunes"
    play (some file track whose name is "Yesterday")
end tell

And then iTunes starts to play a classic Beatles song. Is there any was I can do this with ScriptingBridge or do I have to run this AppleScript from my app?

hqt
  • 29,632
  • 51
  • 171
  • 250
Chris
  • 15
  • 5

1 Answers1

4

It's not as simple as the AppleScript version, but it's certainly possible.

Method one

Get a pointer to the iTunes library:

iTunesApplication *iTunesApp = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
SBElementArray *iTunesSources = [iTunesApp sources];
iTunesSource *library;
for (iTunesSource *thisSource in iTunesSources) {
    if ([thisSource kind] == iTunesESrcLibrary) {
        library = thisSource;
        break;
    }
}

Get an array containing all the audio file tracks in the library:

SBElementArray *libraryPlaylists = [library libraryPlaylists];
iTunesLibraryPlaylist *libraryPlaylist = [libraryPlaylists objectAtIndex:0];
SBElementArray *musicTracks = [self.libraryPlaylist fileTracks];    

Then filter the array to find tracks with the title you're looking for.

NSArray *tracksWithOurTitle = [musicTracks filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%K == %@", @"name", @"Yesterday"]];   
// Remember, there might be several tracks with that title; you need to figure out how to find the one you want. 
iTunesTrack *rightTrack = [tracksWithOurTitle objectAtIndex:0];
[rightTrack playOnce:YES];

Method two

Get a pointer to the iTunes library as above. Then use the Scripting Bridge searchFor: only: method:

SBElementArray *tracksWithOurTitle = [library searchFor:@"Yesterday" only:kSrS];
// This returns every song whose title *contains* "Yesterday" ...
// You'll need a better way to than this to pick the one you want.
iTunesTrack *rightTrack = [tracksWithOurTitle objectAtIndex:0];
[rightTrack playOnce:YES];

Caveat to method two: The iTunes.h file incorrectly claims that the searchFor: only: method returns an iTunesTrack*, when in fact (for obvious reasons) it returns an SBElementArray*. You can edit the header file to get rid of the resulting compiler warning.

Gabriel Roth
  • 1,030
  • 1
  • 12
  • 31
  • Yeah right, it's not as simple as the AppleScript version, but it works great! Thanks! – Chris Feb 23 '12 at 18:51
  • Note for those following method two that (at least with my iTunes.h) library should be libraryPlayList, and that kSrS should be in single quotes, or even better use the itunes.h defined enum: iTunesESrASongs – mackworth May 26 '13 at 18:24