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

Reply via email to