Jens Alfke wrote:
> On Jan 26, 2010, at 9:41 AM, Paul Sanders wrote:
>
>> I use Cocoa's NSAppleScript class. This seems to work fine on Tiger, Leopard
>> and Snow Leopard.
>
> Yup, it just has the limitation that you have to run the script
> synchronously, which sucks since many iTunes commands can take a long time.
> There's no workaround to this that I've been able to find, since
> NSAppleScript is not thread-safe.
AppleScript and NSAppleScript are thread-safe in 10.6.
As for slowness, iTunes may not be a speed demon when it has many tens of
thousands of tracks to wade through, but in a lot of cases the performance
problems are primarily due to inefficient design in your own code. The Apple
Event Object Model was optimized for System 7, where IPC was extremely
expensive, so generally works best if you can use a few complex commands rather
than lots of simple commands.
e.g. This is dog slow because it sends 3*N+1 Apple events (where N is the
number of tracks), each of which takes time for iTunes to process:
set the_result to {}
tell application "iTunes"
repeat with track_ref in every track of library playlist 1
set end of the_result to {name, album, artist} of track_ref
end repeat
end tell
the_result
whereas this returns the same data (albeit in a different arrangement) using
just 3 Apple events, so is blazing fast by comparison:
tell application "iTunes"
set the_result to {name, album, artist} of every track of playlist 1
end tell
Apple event IPC is based on RPC + first-class queries, not OOP as most folks
assume (a rough analogy would be XPath queries over XML-RPC). If you try to
apply OO idioms to it when moving large numbers of values between processes,
performance will suck even by IPC standards.
Similarly, if you want to filter for specific tracks, you'll get much better
performance if you can formulate a more complex query for iTunes to resolve
rather than pull out all of the data and search it yourself:
tell application "iTunes"
make new user playlist with properties {name:"Post"}
duplicate (every track of library playlist 1 whose album = "Post" and
artist = "Björk") to playlist "Post"
end tell
If you're curious, running that through ASTranslate formats each Apple event in
objc-appscript syntax (which is handy as a starting point for developing your
own ObjC code, and avoiding off-topic moderation:):
#import "ITGlue/ITGlue.h"
ITApplication *itunes = [ITApplication applicationWithName: @"iTunes"];
ITMakeCommand *cmd = [[[itunes make] new_: [ITConstant userPlaylist]]
withProperties: [NSDictionary dictionaryWithObject:
@"Post" forKey: [ITConstant name]]];
id result = [cmd send];
#import "ITGlue/ITGlue.h"
ITApplication *itunes = [ITApplication applicationWithName: @"iTunes"];
ITReference *ref = [[[[itunes libraryPlaylists] at: 1] tracks] byTest:
[[[ITIts album] equals: @"Post"] AND:
[[ITIts artist] equals: @"Björk"]]];
ITDuplicateCommand *cmd = [[ref duplicate] to:
[[itunes playlists] byName: @"Post"]];
id result = [cmd send];
HTH
has
--
Control AppleScriptable applications from Python, Ruby and ObjC:
http://appscript.sourceforge.net
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]