iTunes Scripting Bridge reveal does not work

…衆ロ難τιáo~ 提交于 2019-12-13 03:24:56

问题


The following code should show a certain track in iTunes:

NSString* iTunesPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"com.apple.iTunes"];

iTunesApplication *iTunes = nil;
if ( iTunesPath ) {
 iTunes = [[SBApplication alloc] initWithURL:[NSURL fileURLWithPath:iTunesPath]];
 [iTunes setDelegate:self];
}

iTunesSource *librarySource = nil;
NSArray *sources = [iTunes sources];
for (iTunesSource *source in sources) {
 if ([source kind] == iTunesESrcLibrary) {
  librarySource = source;
  break;
 }
}
SBElementArray *libraryPlaylist = [librarySource libraryPlaylists];
iTunesLibraryPlaylist *iTLibPlaylist = nil;
if ([libraryPlaylist count] > 0) {
 iTLibPlaylist = [libraryPlaylist objectAtIndex:0];
}


SBElementArray *fileTracks = [iTLibPlaylist fileTracks];

iTunesFileTrack *track = [fileTracks objectAtIndex:4];
NSLog(@"Try to reveal track: %@ at path :%@",[track description],[[track location] path]);
[track reveal];

Output:

Try to reveal track: <ITunesFileTrack @0x1364ed20: ITunesFileTrack 4 of ITunesLibraryPlaylist 0 of ITunesSource 0 of application "iTunes" (2474)> at path :/Users/...

But absolutely noting happens. What am I doing wrong? (iTunes Version: 9.0.3)


回答1:


The Library playlist doesn't exist anymore in the UI; it's there in the model, so it shows up in AppleScript, but trying to reveal it or anything in it won't do anything in the UI, as you saw. You can reproduce this in AppleScript as well (reveal track 5 of library playlist 1 of source 1).

The solution is to talk to the Music playlist, not the Library playlist. “Music” is the second playlist—playlist 2 in AppleScript, [[librarySource playlists] objectAtIndex:1] in Cocoa.

If you want to reveal a playing item in whatever playlist it's playing in, use reveal current track (which should be [[iTunes currentTrack] reveal], although I haven't tested that).




回答2:


This helped me solve a related issue. Thanks.

I would recommend against using [[librarySource playlists] objectAtIndex:1] to get the playlist. It feels too much like guessing. You should also avoid iterating through the arrays from Scripting Bridge with a for loop.

This example solves both problems:

iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
iTunesSource *library = [[[[iTunes sources] get] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"kind == %i", iTunesESrcLibrary]] objectAtIndex:0];
iTunesLibraryPlaylist *lp = [[[[library playlists] get] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"specialKind == %i", iTunesESpKMusic]] objectAtIndex:0];

[[library playlists] objectWithName:@"Music"] also works, but I’m not sure if that’s locale dependent (and the name could change in a future update).




回答3:


Just to add to the answer of Rob McBroom, it would be even better to use firstObject instead of objectAtIndex:0. It will prevent an exception in case your query fails and returns an empty array. This will happen when you search for the Internet radio source (kind == iTunesESrcRadioTuner) and the Internet Radio library is disabled in the preferences.

iTunesApplication* iTunesApp = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
iTunesSource* radioTunerSource = [[[[iTunesApp sources] get] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"kind == %i", iTunesESrcRadioTuner]] firstObject];


来源:https://stackoverflow.com/questions/2416285/itunes-scripting-bridge-reveal-does-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!