Scripting Bridge confusion

Note that this is not about scripting "Bridge", the Adobe product, but rather the Mac OS X technology "Scripting Bridge"...*that* has made googling for an answer quite difficult!
Anyway, I'm trying to use Mac's Scripting Bridge technology to do a little bit of control of Photoshop from my Cocoa app.  All I'm really trying to do at this point is to save all files currently open in PS (CS3) as JPEGs with quality = 12.
I've run the 'sdef ... | sdp ...' tool to generate the header for Scripting Bridge.  I get a handle to the application, get all the open documents, and start looping over them using this code:
AdobePhotoshopCS3Application *psApp = [SBApplication applicationWithBundleIdentifier:@"com.adobe.Photoshop"];
SBElementArray *docs = [psApp documents];
NSUInteger index ;
AdobePhotoshopCS3Document *doc, *savedDoc = nil;
AdobePhotoshopCS3JPEGSaveOptions *options = [[[psApp classForScriptingClass:@"JPEG save options"]
                                             alloc] init];
for (index = 0; index < [docs count]; index++) {
  doc = [[docs objectAtIndex:index] get];
I now wish to add in a call to -saveIn:as:copying:appending:withOptions: with options.quality=12;,  but am confused on how to use the options object.  I can create the it just fine, but  I can't set the quality property.  The docs say "Immediately after creating the object, insert it in the appropriate element array. The object is not “viable” in the application until it has been added to its container. Consequently, you cannot set or access its properties until it’s been added."  Add it to what?  Isn't it just a parameter to the -saveIn: method?
Can anyone clear up my confusion on this?
Thanks!
randy

I'm bumping this because I've been looking into this myself.  I've been trying to simply open a file using Scripting Bridge. What it boils down to is that Photoshop really isn't Scripting Bridge-savvy. Here's the deal...
Apple's docs really spell it out like it is. Most classes have a container, which is a mutable array, that they need to be added to before they can be acted upon, as shown in the generated header...
@interface photoshopCS4Application : SBApplication
- (SBElementArray *) documents;
- (SBElementArray *) fonts;
- (SBElementArray *) notifiers;
...and that is the complete list of top-level containers available to us. Because we don't have an array made available to us to store the newly created photoshopCS4OpenOptions object, we can't use the object and by extension can't make a document. Therefore, we can't use the open command in Scripting Bridge. The punchline here is that the same can be said of all the commands that require some kind of options object. Now I'm going to investigate the possibility of just sending an AppleEvent of some kind and bypass Scripting Bridge entirely, but my hopes are dim and I'll have to revert back to Applescript for individual commands.
If I'm wrong (and I'm praying someone will have a way to prove me exactly that), then I will be happy to edit or amend my answer here. And if I could find where to submit a bug report or feature request to Adobe in their voluminous website, I would.

Similar Messages

  • Getting Safari document title/location via Scripting Bridge fails

    I'm trying to get the URL and document title from the topmost Safari document/tab. I have an AppleScript and an objective-c version using the Scripting Bridge framework.
    Both versions work fine for most web pages, however when I open a Youtube video in full-screen mode, the Scripting Bridge based version fails (error below). The Apple Script works fine for "normal" and full-screen Safari windows.
    Can anyone see what is wrong with the Scripting Bridge code below to cause it to fail for full-screen Safari windows?
    Here the code (I omitted error checking for brevity):
    AppleScript:
    tell application "Safari"
    # Give us some time to open video in full-screen mode
    delay 10
    do JavaScript "document.title" in document 0
    end tell
    Scripting Bridge:
    SafariApplication* safari = [SBApplication applicationWithBundleIdentifier:@"com.apple.Safari"];
    SBElementArray* windows = [safari windows];
    SafariTab* currentTab = [[windows objectAtIndex: 0] currentTab];
    // This fails when in full-screen mode:
    id result = [safari doJavaScript: @"document.title" in: currentTab];
    NSLog(@"title: %@", result);
    Scripting Bridge error (with added line breaks):
    Apple event returned an error. Event = 'sfri'\'dojs'{
    '----':'utxt'("document.title"),
    'dcnm':'obj '{ 'want':'prop',
    'from':'obj '{ 'want':'cwin',
    'from':'null'(),
    'form':'indx',
    'seld':1 },
    'form':'prop',
    'seld':'cTab' }
    Error info = {
    ErrorNumber = -1728;
    ErrorOffendingObject = <SBObject @0x175c2de0:
    currentTab of SafariWindow 0 of application "Safari" (238)>;
    I could not find details about the given error code. It complains about 'currentTab' which shows that the JavaScript event at least made it all the way to Safari. I assume that the current tab receives the event, but refuses to run the JS code, because it is in full-screen mode. However, why does this work for an AppleScript? Don't they use the same code path eventually?
    Thanks!
    Rico

    1) I have not yet looked into Apple events, but have read elsewhere that it is not the most fun thing to deal with. I might give it a shot after having tried 2 + 3
    Not really, but your command isn't too complicated so it'd be quite doable using the AEBuild* functions/NSAppleEventDescriptor and AESendMessage. If you go the AEBuild* route, you can use AEDebug to sniff Apple events sent from AppleScript for clues - the AEPrint syntax is similar to that used by AEBuild* functions. Mostly it's just tedious; first learning to use the lower-level APIs, then writing the code for them.
    2) Using NSAppleScript was actually my first approach, but having to compile each script before I run it seems a waste. Maybe I can try a pre-compiled script and hand in the JavaScript as a parameter.
    That's the safe and efficient way to parameterize AppleScripts. Although unless you're doing this to support user-supplied scripts, by the time you've packed what you need into an NSAppleEventDescriptor, a bit more code and you could probably send it directly to Safari yourself.
    3) I had tried ASTranslate in the past. I have not actually compiled the generated code, but seeing this makes me wonder about the difference between the Apple Script and Scripting Bridge.
    I've written about that in various places, e.g.:
    http://stackoverflow.com/questions/1309958/avoiding-applescript-through-ruby-rb- appscript-or-rubyosa/1316563#1316563
    Basically, Apple event IPC is RPC plus first-class queries, not OO as a lot of folks assume. AppleScript's OO-like syntax is a bit of a red herring, and the AS interpreter uses various tricks (e.g. implict gets) to further this illusion. So it looks and feels like OO, but only up to a point, and beyond that folks get totally confused when it does something decidedly un-OO. Hence AppleScript's reputation amongst professional programmers as being confusing and unpredictable. (It's actually reasonably straightforward and predictable one you know how it really works; it's just that figuring it out for yourself takes a lot of time and effort, since it's completely messed with your preconceptions by then. Ugh.)
    Apple had an opportunity to learn their lessons from AS's approach, but whether due to politics, hubris or naivety they decided to dress up SB to look even more Cocoa-/OO-like. Which just means there's a bigger impedance mismatch between the SB API and the AE API hidden beneath the surface. So the abstractions are thicker and leakier, and the obfuscations more impenetrable when you do run into problems. By comparison, objc-appscript minimizes the syntactic sugar and wears much of Apple events' inherent weirdness on its sleeve. So while it takes a bit of getting used to if you're from an OO background, once you do get the hang of it it (nearly always) just works.

  • Scripting Bridge & iTunes?

    Hi, has anyone gotten very far into using Scripting Bridge on Leopard with Python and iTunes? I tried, but got stuck pretty fast. I'm trying to iterate over tracks and (among other things) find out what their file names are.
    from ScriptingBridge import *
    itunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
    lib = itunes.sources()[0].playlists()[0]
    tracks = lib.tracks()
    print tracks[0].location
    This works up until the last line, but then complains "AttributeError: 'ITunesTrack' object has no attribute 'location'". So I thought I would try to ask for a list of "file tracks" instead of "tracks", because that's how appscript seems to work, but no luck.
    from ScriptingBridge import *
    itunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
    lib = itunes.sources()[0].playlists()[0]
    tracks = lib.file_tracks()
    print tracks[0].location
    produces "AttributeError: 'ITunesPlaylist' object has no attribute 'file_tracks'". And then, although I really want to embrace Scripting Bridge, I thought I'd try a last resort and go back to using appscript (that's what I used on Tiger). But that doesn't seem to work on Leopard... while retrieving the list of tracks, it works for a while and then says
    Traceback (most recent call last):
    File "/Library/Python/2.5/site-packages/appscript-0.17.2-py2.5-macosx-10.5-i386.egg/apps
    cript/reference.py", line 372, in _call_
    if e.number in [-600, -609] and self.AS_appdata.path: # event was sent to a local app
    for which we no longer have a valid address (i.e. the application has quit since this aem.
    Application object was made).
    AttributeError: AppData instance has no attribute 'path'
    even though iTunes hasn't quit. Any suggestions? I know I could read & write XML, but I want this to work while iTunes.app is running. This seems like it ought to be a really basic task, but I'm out of ideas. Thanks in advance.
    Message was edited by: dormouse310

    The problem here is that Scripting Bridge is just a bit too arrogant and nit-picky for its own (or its users') good.
    i.e. Unlike appscript, which carefully mimics the way that AppleScript works in order to ensure maximum compatibility with existing applications - all of which have for the last 14 years been designed and tested against AppleScript - Scripting Bridge tries to impose its own particular ideas of how application scripting should operate. The result is that applications which work fine with AppleScript but don't precisely behave in the way that Scripting Bridge thinks they should behave can end up being partially or even completely inaccessible to Scripting Bridge users (at least not without resorting to klunky low-level workarounds).
    (Incidentally, I did caution Apple a year ago about the compatibility problems that the Scripting Bridge-style approach would cause - I made some of the same mistakes myself in early versions of appscript - but unfortunately they went ahead and did it anyway.)
    In this case, it's Scripting Bridge's insistence on enforcing the object model structure defined in iTunes' dictionary that's causing the problem, since iTunes' dictionary is rather inconsistent in declaring the types of elements each class supports. For example, if you look up the 'playlist' class's definition, you'll see that it forgets to list 'file track' as an element. This doesn't bother AppleScript (or appscript), but it trips up the rather less tolerant Scripting Bridge, as you can see here:
    from ScriptingBridge import *
    itunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
    lib = itunes.sources()[0].playlists()[0]
    filetracks = lib.fileTracks() # this line raises an AttributeError: 'ITunesPlaylist' object has no attribute 'fileTracks'
    print filetracks[0].location()
    Not that this excuses the iTunes developers for their sloppy documentation, mind (and you should definitely file a bug report on it), but it isn't much consolation to users who just want to do things that they know worked fine in AppleScript or appscript.
    Anyway, it is possible to work around this particular limitation in Scripting Bridge by resorting to raw AE codes; in this case:
    import struct
    from ScriptingBridge import *
    itunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
    lib = itunes.sources()[0].playlists()[0]
    filetracks = lib.elementArrayWithCode_(struct.unpack('>L', 'cFlT')[0]) # filetracks = lib.fileTracks()
    print filetracks[0].location()
    To obtain the raw codes, use ASDictionary's plain text export option, Smile's 'copy translate' feature, Script Debugger's advanced dictionary viewer, or save the dictionary as an sdef file in Script Editor. And don't forget to take account of endianness issues when converting four-char-code strings to ints as shown above.
    As for the error you're getting with appscript:
    Appscript identifies local applications by their process numbers, so if you quit and relaunch an application after you've created an 'app' object for it and then use that app object to send the application another command, appscript will deliberately raise an error (-609) to tell you the process number used by that app object is no longer valid. (Note: you should actually get a CommandError, not AttributeError, here - the error message you're actually seeing is caused by a bug in 0.17.2's error handling/reporting code that's since been fixed - but the general explanation still holds.)
    In your case, however, it sounds as if iTunes is running throughout, so that isn't what's causing appscript to error. I suspect the actual cause is a timeout error; unfortunately this gets wrongly reported in appscript as error -609 instead of -1712 (timeout error) as it should be. Obviously, getting the wrong error message when an error occurs is rather confusing for users, and fixing this problem is on my TODO list for the next release, although I've yet to figure out why the Apple Event Manager should be giving appscript the wrong error number in the first place. In the meantime, you should be able to confirm that it's a timeout error by running the equivalent command in AppleScript within a 60 second timeout block (which is, IIRC, the default timeout used by appscript 0.17.2).
    As to why it can take so long to get file tracks in iTunes - I'm not an iTunes guru, but you could try asking on the AppleScript-users mailing list to see if anyone there has any suggestions. As for avoiding timeout errors in the first place, you can increase the timeout delay for your appscript command via its 'timeout' argument (this is equivalent to AS's 'with timeout' block, except that it only affects the command it's used in) - see ch.11 of the appscript manual for details.
    HTH
    has
    (p.s. If you've any questions or problems with Python appscript, best place to post them is the PythonMac-SIG mailing list at python.org, or mail me directly if you prefer.)

  • How to use AS's "make new" command in Scripting Bridge?

    Anybody know how to rewrite this line of Applescript in Cocoa using the Scripting Bridge?
    tell application "iTunes" to make new playlist with properties {name:"Some Name"}
    I'd hate to have to embed AS into my app just for this thing.
    Is there maybe some page in the documentation on Applescript object allocation in Scripting Bridge that I'm missing?
    Thanks in advance.

    If you have the Time Capsule setup in Bridge Mode as you indicate, the ethernet ports are all equal and they will behave just like a normal ethernet "switch".
    If you've double checked to make sure that you have a good ethernet cable and you don't have a connection at the WAN port, but do on the other LAN ports, unfortunately the WAN port is defective.

  • Scripting Bridge equivalent to AppleScript "every"

    Hi
    What is the Scripting Bridge equivalent in Ruby to the following AppleScript:
    tell application "Microsoft Entourage" to set allContacts to every contact in anAddressBook
    Thanks
    Praful

    Praful wrote:
    Having browsed various group, I concluded that rb-appscript was my best bet. However, I've had an issue with it, which I've posted to the rb-appscript mailing list.
    Hmm, doesn't seem to have appeared there yet. (I posted a message to it on Sat. and it hasn't appeared either - could be an issue with the RubyForge mailing lists, or an overzealous spam filter somewhere inbetween.)
    This works in rb-appscript with a small address book but not with a large one:
    addressbook.contacts.get.findall do |c|
    p "#{c.first_name.get} #{c.last_name.get}"
    end
    The error message is:
    OSERROR: -1708
    MS applications' scripting support can be rather cranky, and prone to compatibility problems with Apple event bridges other than AppleScript's. My first guess is that Entourage may not like one of appscript's extra performance optimisations, as I've already heard of it causing some problems with Excel. Fortunately, appscript's very open and flexible by design, so can generally be tweaked to work with awkward applications. Try adding the following patch to your script and let me know if that fixes it:
    require 'appscript'
    include Appscript
    class AppData # disable caching feature
    def unpackobjectspecifier(desc)
    return Reference.new(self, @referencecodecs.fully_unpack_objectspecifier(desc))
    end
    end
    Entourage = app('Microsoft Entourage')
    (I'd test it here, but I've only got Office X and the version of En'rage that comes with that seems to be buggy as it's not returning any contacts at all.)
    Running address_book.contacts.get as you suggested returns successfully for a small address book but not a large one (>5000 contacts). The error message is:
    /Library/Ruby/Gems/1.8/gems/rb-appscript-0.5.1/lib/appscript.rb:540:in `sendcommand': CommandError (Appscript::CommandError)
    OSERROR: -609
    MESSAGE: Connection is invalid.
    COMMAND: app("/Applications/Microsoft Office 2004/Microsoft Entourage").address_books.ID(403).contacts.get()
    from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.5.1/lib/appscript.rb:642:in `method_missing'
    Perhaps it's timing out?
    Could be; either that or Entourage is crashing. (Error -609 normally means it's crashed, but there's a glitch in Apple's APIs that cause timeouts to sometimes raise error -609 instead of the usual -1712.) It's odd that the equivalent AppleScript seems to work - appscript is designed to mimic AppleScript as closely as possible for compatibility's sake - but you could try increasing the timeout delay to see if that helps, e.g.:
    app("/Applications/Microsoft Office 2004/Microsoft Entourage").address_books.ID(403).contacts.get(:timeout => 10000)

  • Problem Running App with Scripting Bridge on MAC OS X TIger

    Hi,
    I have an application which link with Scripting Bridge Frame work, use XCODE 3.0 and SDK 10.5. I use Scripting Bridge, to control some functionality of ITune from Objective-C. This Application run fine on Leopard and behave as expected. When I Run this application on Tiger this does not load.
    Considering that scripting Bridge was first released om Leopard.
    Can my Above Application Run on Tiger. If not how do I interface ITune from Objective-C, on both Tiger and Leopard? IS there update which suppose to fix this?
    Thanks
    Akhilesh

    webdevcda wrote:
    Considering that scripting Bridge was first released om Leopard.
    Can my Above Application Run on Tiger.
    No.
    If not how do I interface ITune from Objective-C, on both Tiger and Leopard? IS there update which suppose to fix this?
    There will be no update for old products like Tiger. What there is is all you will ever get. For Tiger, you will have to dig into sending Apple Events to iTunes manually. Or it might be easier to define your Apple Scripts as string resources in your application an execute them via a system() call.

  • Scripting Bridge Fully Undocumented

    I was excited to find javascript amongst the languages supported by Apple's new Scripting Bridge...
    http://www.apple.com/applescript/features/scriptingbridge.html
    ...where javascript is featured boldly in the announcement.
    But I was then immediately disappointed to find there seems no way to actually use javascript with the scripting bridge.
    Searching Apple's resources turns up nothing. Indeed on the main page, they left off the javascript example, and documented only the other two featured languages - python and ruby. What's going on?
    Does anyone know where I can start since Apple's developer resources for using Javascript with the scripting bridge seem even worse than their AppleScript documentation. A single documented example would be a beginning.

    I was excited to find javascript amongst the languages supported by Apple's new Scripting Bridge...
    http://www.apple.com/applescript/features/scriptingbridge.html
    ...where javascript is featured boldly in the announcement.
    But I was then immediately disappointed to find there seems no way to actually use javascript with the scripting bridge.
    Searching Apple's resources turns up nothing. Indeed on the main page, they left off the javascript example, and documented only the other two featured languages - python and ruby. What's going on?
    Does anyone know where I can start since Apple's developer resources for using Javascript with the scripting bridge seem even worse than their AppleScript documentation. A single documented example would be a beginning.

  • Compiling code generated for Scripting Bridge

    Hi,
    I have generated code for iTunes on MAC OS X leopard, I added the generated header file in my project, and imported (#import "Itunes.h") in my implementation file of Objective 'C'. I also linked my project with Scripting Bridge. (/System/Library/Frameworks/ScriptingBridge.framework.)
    But when I build my project I get following error,
    "error ScriptingBridge/ScriptingBridge.h no such file or directory".
    MY project link with other framework, cocoa, AppKit, WebKit fine, and it has been working fine as a web kit plug-in.
    I am new to MAC and Objective 'C' programming, could some one help solve this problem.
    Thanks,
    kumar
    Sample Code from I Tunes.h
    ++++++++++++++++++++++++++++
    #import <AppKit/AppKit.h>
    #import <ScriptingBridge/ScriptingBridge.h>
    @class ITunesPrintSettings, ITunesApplication, ITunesItem, ITunesArtwork, ITunesEncoder, ITunesEQPreset, ITunesPlaylist, ITunesAudioCDPlaylist, ITunesDevicePlaylist, ITunesLibraryPlaylist, ITunesRadioTunerPlaylist, ITunesSource, ITunesTrack, ITunesAudioCDTrack, ITunesDeviceTrack, ITunesFileTrack, ITunesSharedTrack, ITunesURLTrack, ITunesUserPlaylist, ITunesFolderPlaylist, ITunesVisual, ITunesWindow, ITunesBrowserWindow, ITunesEQWindow, ITunesPlaylistWindow;
    typedef enum {
    ITunesEKndTrackListing = 'kTrk' /* a basic listing of tracks within a playlist */,
    ITunesEKndAlbumListing = 'kAlb' /* a listing of a playlist grouped by album */,
    ITunesEKndCdInsert = 'kCDi' /* a printout of the playlist for jewel case inserts */
    } ITunesEKnd;
    typedef enum {
    ITunesEnumStandard = 'lwst' /* Standard PostScript error handling */,
    ITunesEnumDetailed = 'lwdt' /* print a detailed report of PostScript errors */
    } ITunesEnum;

    Hi,
    Could you provide some more details on the entity bean? Like, part of ejb-jar,the implementation code?
    Does your bean use any field by name 'dirty'?
    There was some discussion on a similar problem here - http://forums.oracle.com/forums/message.jsp?id=906659
    Hope this helps,
    Neelesh
    OTN Team @IDC

  • This new "Scripting Bridge"

    I've been reading up about this beat, but I was wondering how you implement it after you do something like;
    NSString * currentTrackName = [[iTunes currentTrack] name];
    Or is that the declaration and implementation in one?
    Thanks,
    Ricky.

    Right.
    So If I was to slap more code on top to make it look like this, would that work?
    iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
    NSString * currentTrackName = [[iTunes currentTrack] name];
    I'm really unsure of what I need to put in my header file. This is what I have;
    #import <Cocoa/Cocoa.h>
    #import <ScriptingBridge/SBApplication.h>
    @interface songGrab : SBApplication {
    IBOutlet id display;
    - (void) currentTrack;
    @end
    I've imported the Scripting Bridge class and added SBApplication like that page showed. songGrab is the name of my class.
    What would I do in the instance if I wanted to use the 'delay' handler? What does that belong to?
    Thanks,
    Ricky.

  • KeyNotes and Apple script / scripting Bridge

    Hi
    Sorry I am a recently started development in Mac OS, so may be this question is very simple for you guys
    actually I am looking to manage Keynote application automatically from Mac Server application, I know apple script is available for lot of functionalities available in keynote but i want that all these things happend without showing anything on GUI , like i want to do all the automation on background without effecting the running GUI of keynote
    if anybody can have idea how to do it in Apple script or using ScriptingBridge, I will really appriciate your help and support

    depending on what you want to do, this may or may not be possible (most likely not).  Applescript works by scripting other applications: some applications are set up do do background tasks, some applications are duplicated by osax or unix utilities that operate invisibly, but most often applescript has to open a document in the application and work on it through the application. 
    scripting bridge is for cocoa developers: it allows cocoa apps to script other apps.  it's not really useful for you unless you want to develop specialized software.
    more details would be helpful.

  • Scripting bridge challenge (problem)

    I need help!
    hi,
    i have a cocoa app that has been upgraded to support applescript. I can work with it just fine from the script editor. I intend it to be able to send commands so i am adding scripting bridge support, and I have hit a wall.
    the documentation is very thin, and it doesn't cover my problem, it doesn't mention it, it doesn't even hint that there might be any weird behavior from the Scripting bridge classes.
    one of the very first things I am trying to do is send my app Script commands, from within the app itself. it would be trivial to just call the proper method, but this is an important step in migrating my app to a position of being completely controllable from applescript.
    well, thats where the problem is. I can get a reference to an SBApplication object, using any of the initializers (bundle ID, URL, or PID) but when I send them a script command, it always times out, and returns an applescript error of -609... which is "Connection is invalid.", That leads me to believe that you can't use the scripting bridge to control your app from within your app through applescript.
    does Anybody out there know enough to shed some light on this?

    orangekay wrote:
    The only reason for sending an AppleEvent to oneself is to support recording, and that is accomplished thusly:
    http://developer.apple.com/documentation/AppleScript/Conceptual/AppleEvents/crea tesend_aepg/chapter_7_section_3.html#//appleref/doc/uid/TP40001449-CH209-BABEIJCA
    I would assume you have little to no control over the manner in which events are sent when using the bridge's convenience methods, so this design simply isn't likely to work. Might want to file a bug against the documentation for failing to specify this limitation explicitly, but it's not something I would have ever expected to fly given the limitations of AESend.
    No idea about Scripting Bridge, but objc-appscript [1] gives you extensive control over event creation and dispatch. e.g. To target the host process, create an application object as follows:
    FooApplication *foo = [[FooApplication alloc] init];
    HTH
    has
    [1] Unlike SB, appscript's design goal is to provide an easy-to-use ObjC API for creating and sending Apple events without restricting functionality or compromising real-world application compatibility. The documentation covers the commonly used features; see the framework headers for more arcane tasks such as supplying your own create and send procs.
    Control AppleScriptable applications from Python, Ruby and ObjC:
    http://appscript.sourceforge.net

  • Scripting Bridge for iTunes

    I'm trying to do something simple and efficient with scripting bridge and iTunes, which is to display the number of the track currently playing in the playlist (aka "get index of current track"), so here's my try:
    // initialization
    iTunes = \[ SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes" \] ;
    // repeat this on a timer
    iTunesTrack* currentTrack = \[ iTunes currentTrack \] ;
    iTunesPlaylist* currentPlaylist = \[ iTunes currentPlaylist \] ;
    SBElementArray* currentTracks = \[ currentPlaylist tracks \] ;
    NSInteger index = \[ currentTracks indexOfObject: currentTrack \] ;
    but this doesn't work because currentTracks and currentTrack are references that haven't been evaluated (and indexOf doesn't persuade them to evaluate). This can be fixed by:
    NSInteger index = \[ \[ currentTracks get \] indexOfObject: \[ currentTrack get \] \] ; // leaks mem!
    and while the index is now correct, this leaks memory (about 1K bytes per call - alot more after some time!). Am I doing something wrong? Does Scripting Bridge have a memory leak? Is there a better way to get this index, or am I stuck going back to AppleScript (I promised myself I'd quit if it got messy). Thx, -L.

    Thanks again for your collective guidance - per your advice, I've tried allocating and releasing an autorelease pool every get/loop. In fact, I've tried many variations of draining and releasing pools, as well as variable assignments and releases. No change in the memory leak.
    I'm starting to suspect that the leak is lower-level than anything Objective-C is doing, but please correct me!
    I've distilled the problem into just a few lines of code inserted into the generic Cocoa app template generated by Xcode. Please take a look below and see how one might change it to not leak memory - Activity Monitor says it ticks up .01MB (about 10K) in RSS memory usage every few seconds.
    Thanks for your continued guidance, -Lance.
    // generated a skeletal Cocoa app (just removed generic copyright comments, added startTrackWatcher)
    // generate iTunes.h with sdef /Applications/iTunes.app | sdp -fh --basename iTunes
    // and add ScriptingBridge framework to project
    #import <Cocoa/Cocoa.h>
    int main(int argc, char *argv[])
    void startTrackWatcher() ; // added these two lines
    startTrackWatcher() ; // for watching mem leak
    return NSApplicationMain(argc, (const char **) argv);
    // added lines below for startTrackWatcher
    #import <ScriptingBridge/ScriptingBridge.h>
    #import "iTunes.h"
    @interface Status : NSObject {
    @public
    NSTimer* timer ;
    iTunesApplication* iTunes ;
    - (void)doit:(NSTimer*)timer;
    - (Status*)initWithTime:(int)time;
    @end
    @implementation Status
    - (void)doit:(NSTimer*)t
    // NSAutoreleasePool* pool = [[ NSAutoreleasePool alloc ] init ] ;
    iTunesTrack* currentTrack = [ iTunes currentTrack ] ;
    iTunesPlaylist* currentPlaylist = [ iTunes currentPlaylist ] ;
    SBElementArray* currentTracks = [ currentPlaylist tracks ] ;
    // NSInteger index = [ currentTracks indexOfObject: currentTrack ] ; // wrong because items aren't evaluated
    NSInteger index = [ [ currentTracks get ] indexOfObject: [ currentTrack get ] ] ; // leaks memory (check Activity monitor)!
    printf( "%d
    ", index ) ;
    // [ pool drain ] ;
    // [ pool release ] ;
    - (Status*)initWithTime:(int)time {
    /NSAutoreleasePool pool =*/ [[NSAutoreleasePool alloc] init];
    timer = [NSTimer scheduledTimerWithTimeInterval:time
    target:self
    selector:@selector(doit:)
    userInfo:timer
    repeats:YES] ;
    iTunes = [ SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes" ] ;
    return self ;
    @end
    void startTrackWatcher() {
    [[ Status alloc ] initWithTime:0.1 ] ;

  • Scripting Bridge and iTunes

    I'm trying to add a playlist to iTunes via some Obj-C code. (Yeah I know AppleScript would be simpler, but part of this is for me to learn coding with Cocoa.) I'm not new to coding, just the Mac flavor of it, and I suspect I'm missing something simple. Anyway, the procedure in question (from a button's click handler):
    <pre>
    iTunesApplication *iTApp;
    SBElementArray *thePlaylists;
    NSDictionary *newPlaylistProps;
    iTunesPlaylist *newPlaylist;
    iTApp = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
    if ([iTApp isRunning]) {
    thePlaylists = [(iTunesSource*)[[iTApp sources] objectAtIndex:0] playlists];
    newPlaylistProps = [NSDictionary dictionaryWithObject:@"foobar" forKey:@"name"];
    newPlaylist = (iTunesPlaylist*)[[[iTApp classForScriptingClass:@"playlist"] alloc] initWithProperties:newPlaylistProps];
    [thePlaylists addObject:newPlaylist];
    </pre>
    I've got iTunes.h created and #imported like the ADC guide showed. The code above works fine until the addObject call, at which point I get an Apple event error -10014. This seems to mean I sent in a list when the handler wanted a single object. I thought newPlaylist counted as just an object.
    Also regarding populating the thePlaylists var - I've resorted to grabbing the first source solely to simplify things. Until I hit this wall, I was iterating the sources to find the library one.
    Any help would be appreciated - thanks!

    Short answer: Scripting Bridge's design is flawed. See the 'jumpstart me with the scripting bridge' thread over on AppleScript-implementors for an explanation of this particular defect:
    http://lists.apple.com/archives/Applescript-implementors/2007/Nov/index.html
    Your options are:
    1. Work around Scripting Bridge's brokenness by sending your own 'make' Apple event via -[SBObject sendEvent:id:parameters:]. (Or even via AEBuildAppleEvent or NSAppleEventDescriptor and AESendMessage if you're particularly masochistic.) You'll need to know the raw AE codes for the 'make' command to do this; e.g. Script Editor can save an application's dictionary to .sdef (XML) file, or ASDictionary [1] can export it in a more readable plain text format.
    2. Use AppleScript via NSAppleScript. Somewhat defeats the purpose of the exercise, but AppleScript knows how to speak Apple events properly so at least you know it'll work.
    3. Use a third-party bridge that speaks Apple events the same way as AppleScript does. For ObjC, use objc-appscript [2]:
    ITApplication *itunes = [[ITApplication alloc] initWithName: @"iTunes.app"];
    NSDictionary *properties = [NSDictionary dictionaryWithObject:@"my playlist" forKey:[ASConstant name]];
    ITMakeCommand *cmd = [[[itunes make] new_: [ITConstant playlist]]
    withProperties: properties];
    ITReference *playlist = [cmd send];
    [itunes release];
    HTH
    [1] http://appscript.sourceforge.net/download.html
    [2] http://appscript.sourceforge.net/objc-appscript.html

  • Scripting Bridge and Powerpoint, how to make new slide?

    I know how to make a new slide in an active presentation in Powerpoint. It works like this:
    tell application "Microsoft PowerPoint"
    set newSlideC to make new slide at before slide 2 of active presentation ¬
    with properties {layout:slide layout media clip and text}
    end tell
    (I stole this snippet from http://www.mactech.com/vba-transition-guide/index-094.html)
    Now I would like to do the same via Scripting Bridge in my Cocoa app.
    But I seem to be unable to find the appropriate classes, objects, methods, or properties in Powerpoint.h
    (which I created with this command:
    sdef /Applications/Microsoft\ Office\ 2008/Microsoft\ PowerPoint.app | sdp -fh --basename Powerpoint
    According to Script Editor's dictionary of Powerpoint, the "make" command is in the 'Standard Suite'.
    But I have no idea how to find it's defintion, let alone how to use it from my Cocoa application.
    Could somebody please give a hint to me?
    Since I'm not (yet) subscribed to the applescript-users mailing list, I am taking the liberty to post my question here.
    Thanks a lot in advance.
    Best regards,
    Gabriel.

    Hello
    You need to alloc and init to make an object instance in Scripting Bridge.
    See the following documents.
    Scripting Bridge Programming Guide for Cocoa
    http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ScriptingB ridgeConcepts/
    Scripting Bridge Framework Reference
    http://developer.apple.com/mac/library/documentation/ScriptingAutomation/Referen ce/ScriptingBridgeFramework/
    Some sample codes
    http://developer.apple.com/mac/library/samplecode/SBSendEmail/
    http://developer.apple.com/mac/library/samplecode/SBSetFinderComment/
    http://developer.apple.com/mac/library/samplecode/ScriptingBridgeFinder/
    http://developer.apple.com/mac/library/samplecode/ScriptingBridgeiCal
    As for your example, code would be something like this.
    NOT TESTED AT ALL. AND PROBABLY IT'S WRONG IN PARTS.
    Just for showing the outline, hopefully.
    PowerPointApplication *powerpoint = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.powerpoint"];
    [powerpoint activate];
    PowerPointSlide *s = [[[powerpoint classForScriptingClass:@"slide"] alloc]
    initWithProperties:
    [NSDictionary dictionaryWithObjectsAndKeys:
    @"slideLayoutMediaClipAndText", @"layout",
    nil]];
    [[powerpoint.activePresentation slides] insertObject:s atArrangedObjectIndex:0];
    Good luck,
    H
    Message was edited by: Hiroto (fixed typo)

  • Scripting Bridge: how to set current iTunes playlist

    I know how to get the current iTunes playlist using Scripting Bridge, but how do I set the current playlist?

    This is the answer:
    1. Dig into iTunesApplication's "sources" to find iTunesSource "Library"
    2. Dig into iTunesSource "Library" to find iTunesPlaylist "Party Shuffle"
    3. Do a reveal.

Maybe you are looking for

  • System Crash and Slow Performance

    Hello - I am hoping that someone might help me -- before upgrading (or downgrading dependent of your view) I was happy and go lucky with my Power Mac G5 -- I have connected via firewire two external hard drives (1 TB) and (500 GB) along with my (2X 5

  • Dynamically Loading Slide Show...

    hello everyone this is a big one...but i am stuck! i want to make a slideshow in flash 8 with the following properties... 1/ dynamically loads jpegs from an external folder and centers them on the stage (regardless of whether they are landscape/portr

  • Automator bug when save as finder plugin

    I've got a simple workflow that I've saved it as Finder plugin. 1)Get Selected Items 2)Open Finder Items (choose an application to open) I can run the workflow within automator. But when I save it as a Finder plugin, running it via the finder context

  • I am unable to sign into iCloud since upgrading my iMac to10.8.2.

    I have just upgraded my iMac to 10.8.2 and all my icloud service have been disabled. A dialogue box asked me to enter my Apple ID password and the response was password invalid. So I changed the password and each time the dialogue box would respond w

  • Sales order Number not appearing in CO-PA report painter

    Hi I have prepared profitability report through report painter through t-codes KE34 and KE31- Characteristics I have chosen is Sales order No/Plant/sales organization/product and customer- In the report Sales order Number is not appearing? We are abl