iTunes Scripting Bridge显示不起作用

时间:2010-03-10 11:04:36

标签: cocoa macos applescript itunes

以下代码应显示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];

输出:

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

但绝对注意到了。我究竟做错了什么? (iTunes版本:9.0.3)

3 个答案:

答案 0 :(得分:3)

图书馆播放列表在UI中不再存在;它存在于模型中,因此它显示在AppleScript中,但是试图在其中显示它或其中任何内容都不会在UI中执行任何操作,如您所见。您也可以在AppleScript中重现这一点(reveal track 5 of library playlist 1 of source 1)。

解决方案是与音乐播放列表对话,而不是图书馆播放列表。 “音乐”是第二个播放列表 - AppleScript中的playlist 2,Cocoa中的[[librarySource playlists] objectAtIndex:1]

如果您想在播放的播放列表中显示播放项目,请使用reveal current track(应为[[iTunes currentTrack] reveal],但我尚未对其进行测试)。

答案 1 :(得分:2)

这有助于我解决related issue。感谢。

我建议不要使用[[librarySource playlists] objectAtIndex:1]来获取播放列表。感觉太像猜测了。您还应该避免使用for循环从Scripting Bridge迭代数组。

这个例子解决了这两个问题:

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"]也有效,但我不确定这是否依赖于区域设置(并且名称可能会在将来的更新中更改)。

答案 2 :(得分:1)

为了补充Rob McBroom的答案,使用firstObject而不是objectAtIndex:0会更好。如果查询失败并返回空数组,它将阻止异常。当您搜索Internet广播源(kind == iTunesESrcRadioTuner)并在首选项中禁用Internet广播库时,会发生这种情况。

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