Re: Best Strategy to Control iTunes
Re: Best Strategy to Control iTunes
- Subject: Re: Best Strategy to Control iTunes
- From: Ammar Ibrahim <email@hidden>
- Date: Wed, 1 Apr 2009 22:15:12 +0300
On Wed, Apr 1, 2009 at 2:25 PM, has <email@hidden> wrote:
> Michael Ash wrote:
>
> On Tue, Mar 31, 2009 at 3:57 PM, Luca C. <email@hidden>
>> wrote:
>>
>>> 2009/3/31 Ammar Ibrahim <email@hidden>
>>>
>>>> If I want to add a track to iTunes, I need to make sure iTunes is
>>>> responsive.
>>>>
>>>> Are you sure it is that important? Actually, if you run an AS script
>>> wich,
>>> say, opens with the Finder some mp3 files whilst iTunes has dialog
>>> windows
>>> opened, the command will be automatically enqueued. Â In other words,
>>> your
>>> tracks will be added after the user closes the dialog window.
>>> Â Run the script in a separate thread so it won't block your
>>> application's
>>> interface in any case.
>>>
>>
>> No, don't do this. AppleScript is not safe to use outside the main
>> thread. If you must run AppleScript asynchronously, either spawn a
>> subprocess to run it or, better yet, don't use AS at all but send
>> Apple Events in some other way, such as with ScriptingBridge.
>>
>
>
> Scripting Bridge apparently isn't thread-safe either:
>
> http://www.dribin.org/dave/blog/archives/2009/02/01/main_thread_apis/
>
> ObjC-appscript is almost entirely thread-safe. You'll need to watch when
> using methods that rely on the Carbon Process Manager (some initializers,
> -isRunning) as the PM APIs don't appear to be thread-safe itself, but the
> main query builder and event dispatch methods should work fine on any thread
> (e.g. I use Python appscript in a background thread without problems).
>
> For example:
>
> tell application "iTunes"
> set newPlaylist to make new playlist with properties
> {name:"Rock-n-Roll", shuffle:true}
> duplicate (every track of library playlist 1 whose artist is "Chuck
> Berry") to newPlaylist
> end tell
>
>
> #import "ITGlue/ITGlue.h"
>
> int main (int argc, const char * argv[]) {
> NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
> int err = 0;
>
> // create a new application object
> ITApplication *itunes = [ITApplication applicationWithBundleID:
> @"com.apple.itunes"];
>
> // create a new playlist
> ITMakeCommand *cmd = [[[itunes make] new_: [ITConstant playlist]]
> withProperties: [NSDictionary
> dictionaryWithObjectsAndKeys:
> ASTrue, [ITConstant
> shuffle],
> @"Rock-n-Roll", [ITConstant
> name],
> nil]];
> ITReference *newPlaylist = [cmd send];
>
> // duplicate all tracks that match the given criteria to the new
> playlist
> ITReference *ref = [[[[itunes libraryPlaylists] at: 1] tracks]
> byTest: [[ITIts artist]
> equals: @"Chuck Berry"]];
>
> NSError *error;
> NSArray *tracks = [[[ref duplicate] to: newPlaylist] sendWithError:
> &error];
> if (!tracks) {
> // check for errors
> NSLog(@"%@", [error localizedDescription]);
> err = [error code];
> } else
> // display result
> NSLog(@"%@", tracks);
>
> [pool drain];
> return err;
> }
>
> The ASDictionary application on the appscript site has options for
> exporting application dictionaries in both human-readable HTML format and as
> ObjC glue files.
>
> Not surprisingly, the ObjC code's a bit more verbose, but straightforward
> enough to construct once you understand the general principles behind Apple
> event-based IPC. Appscript respects the original Apple event semantics and
> doesn't obfuscate them under piles of fake Cocoa-isms, so if you already
> know how to do it in AppleScript then it's pretty much a straight
> translation: there's even a free tool, ASTranslate, that will help you with
> that.
>
> Apple event IPC is kinda weird and very different to Cocoa/OOP (a rough
> analogy would be to using XPath queries over XML-RPC) but is usually
> serviceable once you get your head around it. Apple docs do a lousy job of
> explaining how it all works, but there's an introduction to the basic
> concepts in the appscript manual and links on the appscript site to further
> information.
>
>
> Oh, and as for checking if an application is responsive - I'd suggest just
> sending an event and seeing if it times out (timeouts may be reported as
> either error -609 or -1712, depending on what sort of mood AESendMessage is
> in at the time). The launch event (ascr/noop) is basically a no-op that will
> return error -1708 if 'successfully' handled; handy if you don't want to
> send a 'work' event.
>
> HTH
>
> has
> --
> Control AppleScriptable applications from Python, Ruby and ObjC:
> http://appscript.sourceforge.net
>
>
Thanks for your answer.
I'm afraid I'm new and don't quite understand, do you recommend I use
appscript? If so, what's the difference between the following methods:
1- NSAppleScript
2- Cocoa Scripting Bridge
3- AppScript
4- Command line invocation of osascript
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden