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 (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com