Can I Send Apple Events in Cocoa?

  • Hi,

    I need to send an Apple Event to a program to automate
    exporting of data from it to a web-site.

    As far as I can tell, I can receive Apple Events in
    Cocoa, but I can't send them directly. (This was
    stated in "Cocoa Programming" in which they said that
    this was true as of 10.1.3)

    I  understand that I could embed Apple Scripts in
    Cocoa, but this seems indirect and less good than just
    directly sending Apple Events and receiving a reply as
    to whether the export was successful or not.

    I believe that Apple is de-emphasizing Apple Events.
    I suppose the next generation software would use some
    kind of Unix technology for interapplication
    communication.  I've heard a source at Apple say that
    this is faster.

    What I'm doing is fairly simple, I could embed an
    Apple Script in my Objective-C code.  Or, I know Java,
    actually, I'd rather add to this Cocoa-Objective-C app
    that I've inerited and add the new functionality in
    Java.  Or I understand that you can use the Cocoa
    framework and build on it with Apple Script Studio,
    which I guess is different than embedding Apple
    Scripts in Objective C.

    Can someone with experience give me a recommendation
    of how to proceed?

    Thanks.

    Kaydell

    __________________________________________________
    Do You Yahoo!?
    Tired of spam?  Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com
  • on 2005-12-10 12:07 AM, Kaydell Leavitt at <kaydell_cocoa...> wrote:

    > I need to send an Apple Event to a program to automate
    > exporting of data from it to a web-site.
    >
    > As far as I can tell, I can receive Apple Events in
    > Cocoa, but I can't send them directly.

    Cocoa doesn't have its own facility to send Apple events, but it's easy
    enough to use AESendMessage once you've built up the Apple event. You can
    built up the Apple event using the appropriate Cocoa classes.

    There are many ways to do messaging in Mac OS X, and Apple events certainly
    have their place. This is especially true when you want to control or read
    another application that is AppleScriptable, and when you want to send one
    of the core Apple events to which all applications respond, such as 'quit'.
    Here's how I send a 'quit' Apple event to my helper application, using Cocoa
    as much as I can:

    - (void)stopUIActions {
        if ([self isUIActionsRunning]) {
            OSType signature = 'UIAc';
            NSAppleEventDescriptor *applicationDesc = [NSAppleEventDescriptor
    descriptorWithDescriptorType:typeApplSignature bytes:&signature
    length:sizeof(OSType)];
            NSAppleEventDescriptor *quitApplicationAppleEvent =
    [NSAppleEventDescriptor appleEventWithEventClass:kCoreEventClass
    eventID:kAEQuitApplication targetDescriptor:applicationDesc
    returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
            AppleEvent *quitApplicationAppleEventPtr = (AEDesc
    *)[quitApplicationAppleEvent aeDesc];
            if (quitApplicationAppleEventPtr) {
                AESendMessage(quitApplicationAppleEventPtr, NULL, kAENoReply,
    kAEDefaultTimeout);
            }
        }
    }

    --

    Bill Cheeseman - <wjcheeseman...>
    Quechee Software, Quechee, Vermont, USA
    http://www.quecheesoftware.com

    PreFab Software - http://www.prefab.com/scripting.html
    The AppleScript Sourcebook - http://www.AppleScriptSourcebook.com
    Vermont Recipes - http://www.stepwise.com/Articles/VermontRecipes
  • Hi,

    Can I call the following Carbon C++ function from the
    app that is thusfar written in Cocoa and Objective C?
    I have to use Apple Events because that's what's
    available to me.

    Thanks.

    Kaydell

    OSStatus SendRoutineMaintenanceAE(FSSpec fileSpec) {
    // --- declare local variables --- //
    OSStatus status;
    AppleEvent theAEvent, theReply;
    AEAddressDesc inventoryAddress;
    OSType inventoryCreator = kInventorySignature;
    long index;
    // --- set up locals  --- //
    AECreateDesc(typeNull, NULL, 0, &theAEvent);
    AECreateDesc(typeNull, NULL, 0, &inventoryAddress);
    AECreateDesc(typeNull, NULL, 0, &theReply);
    // --- create an Do Routine Web Maint. event
    targeting the Inventory Client app --- //
    status = AECreateDesc(typeApplSignature,
    &inventoryCreator, sizeof(inventoryCreator),
    &inventoryAddress);
    if (noErr == status)
      status = AECreateAppleEvent(kInventoryAnalyzerClass,
    kRoutineWebMaintenance, &inventoryAddress,
    kAutoGenerateReturnID, kAnyTransactionID, &theAEvent);
    // --- send the event to the POSIM Inventory Client
    --- //
    if (noErr == status)
      status = AESend(&theAEvent, &theReply, kAEWaitReply,
    kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
    // --- clean up and leave --- //
    AEDisposeDesc(&theAEvent);
    AEDisposeDesc(&inventoryAddress);
    AEDisposeDesc(&theReply);
    // --- return the status --- //
    return status;
    }

    --- Bill Cheeseman <wjcheeseman...> wrote:

    > on 2005-12-10 12:07 AM, Kaydell Leavitt at
    > <kaydell_cocoa...> wrote:
    >
    >> I need to send an Apple Event to a program to
    > automate
    >> exporting of data from it to a web-site.
    >>
    >> As far as I can tell, I can receive Apple Events
    > in
    >> Cocoa, but I can't send them directly.
    >
    > Cocoa doesn't have its own facility to send Apple
    > events, but it's easy
    > enough to use AESendMessage once you've built up the
    > Apple event. You can
    > built up the Apple event using the appropriate Cocoa
    > classes.
    >
    > There are many ways to do messaging in Mac OS X, and
    > Apple events certainly
    > have their place. This is especially true when you
    > want to control or read
    > another application that is AppleScriptable, and
    > when you want to send one
    > of the core Apple events to which all applications
    > respond, such as 'quit'.
    > Here's how I send a 'quit' Apple event to my helper
    > application, using Cocoa
    > as much as I can:
    >
    > - (void)stopUIActions {
    > if ([self isUIActionsRunning]) {
    > OSType signature = 'UIAc';
    > NSAppleEventDescriptor *applicationDesc =
    > [NSAppleEventDescriptor
    > descriptorWithDescriptorType:typeApplSignature
    > bytes:&signature
    > length:sizeof(OSType)];
    > NSAppleEventDescriptor
    > *quitApplicationAppleEvent =
    > [NSAppleEventDescriptor
    > appleEventWithEventClass:kCoreEventClass
    > eventID:kAEQuitApplication
    > targetDescriptor:applicationDesc
    > returnID:kAutoGenerateReturnID
    > transactionID:kAnyTransactionID];
    > AppleEvent *quitApplicationAppleEventPtr =
    > (AEDesc
    > *)[quitApplicationAppleEvent aeDesc];
    > if (quitApplicationAppleEventPtr) {
    >
    > AESendMessage(quitApplicationAppleEventPtr, NULL,
    > kAENoReply,
    > kAEDefaultTimeout);
    > }
    > }
    > }
    >
    >
    > --
    >
    > Bill Cheeseman - <wjcheeseman...>
    > Quechee Software, Quechee, Vermont, USA
    > http://www.quecheesoftware.com
    >
    > PreFab Software -
    > http://www.prefab.com/scripting.html
    > The AppleScript Sourcebook -
    > http://www.AppleScriptSourcebook.com
    > Vermont Recipes -
    > http://www.stepwise.com/Articles/VermontRecipes
    >
    >
    > _______________________________________________
    > Do not post admin requests to the list. They will be
    > ignored.
    > Cocoa-dev mailing list
    > (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    >
    http://lists.apple.com/mailman/options/cocoa-dev/<kaydell_cocoa...>
    >
    > This email sent to <kaydell_cocoa...>
    >

    __________________________________________________
    Do You Yahoo!?
    Tired of spam?  Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com
  • On Dec 11, 2005, at 2:02 PM, Kaydell Leavitt wrote:

    > Can I call the following Carbon C++ function from the
    > app that is thusfar written in Cocoa and Objective C?
    > I have to use Apple Events because that's what's
    > available to me.
    >
    > Thanks.
    >
    > Kaydell
    >
    > OSStatus SendRoutineMaintenanceAE(FSSpec fileSpec) {
    > // --- declare local variables --- //
    > OSStatus status;
    > AppleEvent theAEvent, theReply;
    > AEAddressDesc inventoryAddress;
    > OSType inventoryCreator = kInventorySignature;
    > long index;
    > // --- set up locals  --- //
    > AECreateDesc(typeNull, NULL, 0, &theAEvent);
    > AECreateDesc(typeNull, NULL, 0, &inventoryAddress);
    > AECreateDesc(typeNull, NULL, 0, &theReply);
    > // --- create an Do Routine Web Maint. event
    > targeting the Inventory Client app --- //
    > status = AECreateDesc(typeApplSignature,
    > &inventoryCreator, sizeof(inventoryCreator),
    > &inventoryAddress);
    > if (noErr == status)
    > status = AECreateAppleEvent(kInventoryAnalyzerClass,
    > kRoutineWebMaintenance, &inventoryAddress,
    > kAutoGenerateReturnID, kAnyTransactionID, &theAEvent);
    > // --- send the event to the POSIM Inventory Client
    > --- //
    > if (noErr == status)
    > status = AESend(&theAEvent, &theReply, kAEWaitReply,
    > kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
    > // --- clean up and leave --- //
    > AEDisposeDesc(&theAEvent);
    > AEDisposeDesc(&inventoryAddress);
    > AEDisposeDesc(&theReply);
    > // --- return the status --- //
    > return status;
    > }

    This is all just C, so drop it in as-is to your existing codebase and
    just call it.  Remember that Obj-C is a superset of C.  Also remember
    to link against the Carbon framework to gain access to those APIs.

    Note that you can also incorporate C++ code; search the docs/archives
    for examples if needed.
    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • Ricky is right - it's generally safe to assume that you can "use what
    you want" when it comes to incorporating non-Cocoa stuff into your
    application.

    The fact that the inquiry is about events makes it slightly less of a
    "slam dunk" piece of advice, because there are some areas in which a
    Cocoa application is seriously limited from participating in the
    "Carbon Event" model, but when it comes to *AppleEvents* in
    particular, there shouldn't be any restrictions.

    Daniel

    On Dec 11, 2005, at 3:37 PM, Ricky Sharp wrote:

    > This is all just C, so drop it in as-is to your existing codebase
    > and just call it.  Remember that Obj-C is a superset of C.  Also
    > remember to link against the Carbon framework to gain access to
    > those APIs.
    >
    > Note that you can also incorporate C++ code; search the docs/
    > archives for examples if needed.
  • Thanks.

    This is what I have so far.  It works in Carbon.  I
    haven't tried calling it from Cocoa yet.  It works
    when I use the application signature, but I was hoping
    to be able to specify the app to get the Apple Event
    with a relative path from my app.

    Using the address of the application signature works,
    but a FSSpec and an FSRef both fail with a -600 error.
    I read something in mach ports and such.  It sounds
    to me like I'm running into something that changed
    with OS X, where things now are in Unix and the
    low-level mechanism for sending Apple Events has
    changed from the PPC toolbox to a Unix thing.

    Kaydell

    OSStatus SendRoutineMaintenanceAE(FSRef appRef) {
    // --- declare local variables --- //
    OSStatus status;
    AppleEvent theAEvent, theReply;
    AEAddressDesc inventoryAddress;
    // OSType inventoryCreator = kInventorySignature;
    // --- set up locals  --- //
    AECreateDesc(typeNull, NULL, 0, &theAEvent);
    AECreateDesc(typeNull, NULL, 0, &inventoryAddress);
    AECreateDesc(typeNull, NULL, 0, &theReply);
    // --- create an open documents event targeting the
    finder --- //
    // status = AECreateDesc(typeApplSignature,
    &inventoryCreator, sizeof(inventoryCreator),
    &inventoryAddress);
    status = AECreateDesc(typeFSRef, &appRef,
    sizeof(appRef), &inventoryAddress);
    if (noErr == status)
      status = AECreateAppleEvent(kInventoryAnalyzerClass,
    kRoutineWebMaintenance, &inventoryAddress,
    kAutoGenerateReturnID, kAnyTransactionID, &theAEvent);
    // --- send the event to the POSIM Inventory Client
    --- //
    if (noErr == status)
      status = AESend(&theAEvent, &theReply, kAEWaitReply,
    kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
    // --- clean up and leave --- //
    AEDisposeDesc(&theAEvent);
    AEDisposeDesc(&inventoryAddress);
    AEDisposeDesc(&theReply);
    // --- return the status --- //
    return status;
    }

    --- Daniel Jalkut <jalkut...> wrote:

    > Ricky is right - it's generally safe to assume that
    > you can "use what
    > you want" when it comes to incorporating non-Cocoa
    > stuff into your
    > application.
    >
    > The fact that the inquiry is about events makes it
    > slightly less of a
    > "slam dunk" piece of advice, because there are some
    > areas in which a
    > Cocoa application is seriously limited from
    > participating in the
    > "Carbon Event" model, but when it comes to
    > *AppleEvents* in
    > particular, there shouldn't be any restrictions.
    >
    > Daniel
    >
    > On Dec 11, 2005, at 3:37 PM, Ricky Sharp wrote:
    >
    >> This is all just C, so drop it in as-is to your
    > existing codebase
    >> and just call it.  Remember that Obj-C is a
    > superset of C.  Also
    >> remember to link against the Carbon framework to
    > gain access to
    >> those APIs.
    >>
    >> Note that you can also incorporate C++ code;
    > search the docs/
    >> archives for examples if needed.
    >
    >

    __________________________________________________
    Do You Yahoo!?
    Tired of spam?  Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com
  • Hi,

    I saw some Cocoa code in the project that I'm working
    on that was written by my predecessor.  He used
    embeded Apple Script in the Cocoa/Objective-C app that
    I'm working on.  I thought that this was not good,
    that I could do better writing code in C, but so far,
    I've only been able to assume that the database server
    and the inventory client app are both running.  It's
    not likely that there will be two Inventory clients
    running, but it can happen.  I want to be able to
    specify which instance of the Inventory Client gets
    the Apple Event if more than one is running.

    The following Apple Script is really what I need, but
    with the additional ability to specify an app if two
    or more copies are running.

    tell application "Inventory Client"
    activate
    «event InvARTMT»
    end tell

    Kaydell

    --- Kaydell Leavitt <kaydell_cocoa...> wrote:

    > Thanks.
    >
    > This is what I have so far.  It works in Carbon.  I
    > haven't tried calling it from Cocoa yet.  It works
    > when I use the application signature, but I was
    > hoping
    > to be able to specify the app to get the Apple Event
    > with a relative path from my app.
    >
    > Using the address of the application signature
    > works,
    > but a FSSpec and an FSRef both fail with a -600
    > error.
    > I read something in mach ports and such.  It sounds
    > to me like I'm running into something that changed
    > with OS X, where things now are in Unix and the
    > low-level mechanism for sending Apple Events has
    > changed from the PPC toolbox to a Unix thing.
    >
    > Kaydell
    >
    > OSStatus SendRoutineMaintenanceAE(FSRef appRef) {
    > // --- declare local variables --- //
    > OSStatus status;
    > AppleEvent theAEvent, theReply;
    > AEAddressDesc inventoryAddress;
    > // OSType inventoryCreator = kInventorySignature;
    > // --- set up locals  --- //
    > AECreateDesc(typeNull, NULL, 0, &theAEvent);
    > AECreateDesc(typeNull, NULL, 0, &inventoryAddress);
    > AECreateDesc(typeNull, NULL, 0, &theReply);
    > // --- create an open documents event targeting the
    > finder --- //
    > // status = AECreateDesc(typeApplSignature,
    > &inventoryCreator, sizeof(inventoryCreator),
    > &inventoryAddress);
    > status = AECreateDesc(typeFSRef, &appRef,
    > sizeof(appRef), &inventoryAddress);
    > if (noErr == status)
    > status =
    > AECreateAppleEvent(kInventoryAnalyzerClass,
    > kRoutineWebMaintenance, &inventoryAddress,
    > kAutoGenerateReturnID, kAnyTransactionID,
    > &theAEvent);
    > // --- send the event to the POSIM Inventory Client
    > --- //
    > if (noErr == status)
    > status = AESend(&theAEvent, &theReply,
    > kAEWaitReply,
    > kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
    > // --- clean up and leave --- //
    > AEDisposeDesc(&theAEvent);
    > AEDisposeDesc(&inventoryAddress);
    > AEDisposeDesc(&theReply);
    > // --- return the status --- //
    > return status;
    > }
    >
    > --- Daniel Jalkut <jalkut...> wrote:
    >
    >> Ricky is right - it's generally safe to assume
    > that
    >> you can "use what
    >> you want" when it comes to incorporating non-Cocoa
    >> stuff into your
    >> application.
    >>
    >> The fact that the inquiry is about events makes it
    >> slightly less of a
    >> "slam dunk" piece of advice, because there are
    > some
    >> areas in which a
    >> Cocoa application is seriously limited from
    >> participating in the
    >> "Carbon Event" model, but when it comes to
    >> *AppleEvents* in
    >> particular, there shouldn't be any restrictions.
    >>
    >> Daniel
    >>
    >> On Dec 11, 2005, at 3:37 PM, Ricky Sharp wrote:
    >>
    >>> This is all just C, so drop it in as-is to your
    >> existing codebase
    >>> and just call it.  Remember that Obj-C is a
    >> superset of C.  Also
    >>> remember to link against the Carbon framework to
    >> gain access to
    >>> those APIs.
    >>>
    >>> Note that you can also incorporate C++ code;
    >> search the docs/
    >>> archives for examples if needed.
    >>
    >>
    >
    >
    > __________________________________________________
    > Do You Yahoo!?
    > Tired of spam?  Yahoo! Mail has the best spam
    > protection around
    > http://mail.yahoo.com
    >

    __________________________________________________
    Do You Yahoo!?
    Tired of spam?  Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com
  • On Dec 12, 2005, at 2:19 AM, Kaydell Leavitt wrote:

    > I saw some Cocoa code in the project that I'm working
    > on that was written by my predecessor.  He used
    > embeded Apple Script in the Cocoa/Objective-C app that
    > I'm working on.  I thought that this was not good,
    > that I could do better writing code in C,

    It was probably best to assume that if AppleScript worked, and was
    simple to maintain and understand, and was of high enough
    performance, then it was good (and better!) than writing code in C to
    do the same thing.

    > but so far,
    > I've only been able to assume that the database server
    > and the inventory client app are both running.  It's
    > not likely that there will be two Inventory clients
    > running, but it can happen.  I want to be able to
    > specify which instance of the Inventory Client gets
    > the Apple Event if more than one is running.

    At *this* point you might have a reasonable argument for switching to
    something besides AppleScript. As far as I know there is no way to
    coerce AppleScript into targeting a specific process out of many
    running copies.

    It's hard for me to imagine a scenario in which this "multiple
    running copies" arrangement isn't a design flaw.  Sounds like a
    poorly thought-out Windows port.

    > The following Apple Script is really what I need, but
    > with the additional ability to specify an app if two
    > or more copies are running.
    >
    > tell application "Inventory Client"
    > activate
    > «event InvARTMT»
    > end tell

    I think you're on the right track simply using AppleEvents directly.
    Build a list of all the process serial numbers of your target
    applications, and send these "InvARTMT" directly to the process
    serial number desired.

    Daniel
  • Take a look at these webpages for a relatively fast way to achieve
    what you want.

    Unsanity.org: Lazy AppleScript Sending <http://www.unsanity.org/
    archives/000107.php
    >
    AEBuild*, AEPrint* and Friends <http://developer.apple.com/technotes/
    tn/tn2045.html
    >

    It's much faster than fiddling with lots of invocations of C code!

    Annard

    On 12 Dec 2005, at 08:19, Kaydell Leavitt wrote:
    > The following Apple Script is really what I need, but
    > with the additional ability to specify an app if two
    > or more copies are running.
    >
    > tell application "Inventory Client"
    > activate
    > «event InvARTMT»
    > end tell
    >
  • Thanks,

    I think that my motivation to send the Apple Events,
    to make sure that the event goes to the right app, is
    not necessary, but can I process a reply Apple Event?

    Also, I read in "Cocoa Programming" that as of 10.1.3
    that Apple Events were not fully supported.  Has this
    changed.  We're targeting 10.4.3 and up.

    Maybe this isn't an issue given that I can use
    embedded Apple Script and that I can call anything in
    the Carbon framework.

    But, is there a nice object-oriented Cocoa/Objective-C
    solution?

    -- Kaydell

    --- Annard Brouwer <annard...> wrote:

    > Take a look at these webpages for a relatively fast
    > way to achieve
    > what you want.
    >
    > Unsanity.org: Lazy AppleScript Sending
    > <http://www.unsanity.org/
    > archives/000107.php>
    > AEBuild*, AEPrint* and Friends
    > <http://developer.apple.com/technotes/
    > tn/tn2045.html>
    >
    > It's much faster than fiddling with lots of
    > invocations of C code!
    >
    > Annard
    >
    > On 12 Dec 2005, at 08:19, Kaydell Leavitt wrote:
    >> The following Apple Script is really what I need,
    > but
    >> with the additional ability to specify an app if
    > two
    >> or more copies are running.
    >>
    >> tell application "Inventory Client"
    >> activate
    >> «event InvARTMT»
    >> end tell
    >>
    >

    __________________________________________________
    Do You Yahoo!?
    Tired of spam?  Yahoo! Mail has the best spam protection around
    http://mail.yahoo.com
  • on 2005-12-14 12:13 PM, Kaydell Leavitt at <kaydell_cocoa...> wrote:

    > But, is there a nice object-oriented Cocoa/Objective-C
    > solution?

    The Cocoa AppleScript documentation was updated, expanded and greatly
    improved in June 2005. There's still a lack of good task-oriented
    implementation detail, but the concept documents are quite good. You can do
    pretty much everything you need in Cocoa to make a Cocoa application
    scriptable and to build Apple events. But, as I noted in a previous message,
    you still have to use AEMessageSend to actually send an Apple event.

    --

    Bill Cheeseman - <wjcheeseman...>
    Quechee Software, Quechee, Vermont, USA
    http://www.quecheesoftware.com

    PreFab Software - http://www.prefab.com/scripting.html
    The AppleScript Sourcebook - http://www.AppleScriptSourcebook.com
    Vermont Recipes - http://www.stepwise.com/Articles/VermontRecipes
  • Funny you mention this since right at this moment I'm investigating
    on how to deal with reply events in both Carbon and Cocoa for a
    plugin. Based on my research (note: NO empirical data yet), you
    should be able to install a handler for your reply event in a Cocoa
    application.

    If you use an embedded AppleScript and you don't care about the
    response of the server application, you're fine. This is the route I
    take most of the time: I use the script as a format string where I
    fill in the details at runtime and fire away. Works great. You could
    even consider writing a response inside the script to a file and read
    that from your Cocoa code when it's done executing...

    If you want a nice OO solution and you control both the client and
    the server applications, it wouldn't be too much trouble to implement
    a Distributed Objects implementation. However, if you're stuck with
    AppleEvents and need to interact with the server application, welcome
    to the world of Carbon and lots and lots of functions to do little
    bits of stuff... :-)

    Annard

    On 14 Dec 2005, at 18:13, Kaydell Leavitt wrote:
    > I think that my motivation to send the Apple Events,
    > to make sure that the event goes to the right app, is
    > not necessary, but can I process a reply Apple Event?
    >
    > Also, I read in "Cocoa Programming" that as of 10.1.3
    > that Apple Events were not fully supported.  Has this
    > changed.  We're targeting 10.4.3 and up.
    >
    > Maybe this isn't an issue given that I can use
    > embedded Apple Script and that I can call anything in
    > the Carbon framework.
    >
    > But, is there a nice object-oriented Cocoa/Objective-C
    > solution?
  • On 12/14/05, Bill Cheeseman <wjcheeseman...> wrote:
    > on 2005-12-14 12:13 PM, Kaydell Leavitt at <kaydell_cocoa...> wrote:
    >
    >> But, is there a nice object-oriented Cocoa/Objective-C
    >> solution?
    >
    > The Cocoa AppleScript documentation was updated, expanded and greatly
    > improved in June 2005. There's still a lack of good task-oriented
    > implementation detail, but the concept documents are quite good. You can do
    > pretty much everything you need in Cocoa to make a Cocoa application
    > scriptable and to build Apple events. But, as I noted in a previous message,
    > you still have to use AEMessageSend to actually send an Apple event.

    The conceptual documentation in question..
    <http://developer.apple.com/documentation/Cocoa/Conceptual/Scriptability/ind
    ex.html#//apple_ref/doc/uid/10000007i
    >
  • On Fri, 9 Dec 2005 21:07:40 -0800 (PST), Kaydell Leavitt
    <kaydell_cocoa...> said:
    > Hi,
    >
    > I need to send an Apple Event to a program to automate
    > exporting of data from it to a web-site.
    >
    > As far as I can tell, I can receive Apple Events in
    > Cocoa, but I can't send them directly. (This was
    > stated in "Cocoa Programming" in which they said that
    > this was true as of 10.1.3)
    >
    > I  understand that I could embed Apple Scripts in
    > Cocoa, but this seems indirect and less good than just
    > directly sending Apple Events and receiving a reply as
    > to whether the export was successful or not.
    >
    > I believe that Apple is de-emphasizing Apple Events.
    > I suppose the next generation software would use some
    > kind of Unix technology for interapplication
    > communication.  I've heard a source at Apple say that
    > this is faster.
    >
    > What I'm doing is fairly simple, I could embed an
    > Apple Script in my Objective-C code.  Or, I know Java,
    > actually, I'd rather add to this Cocoa-Objective-C app
    > that I've inerited and add the new functionality in
    > Java.  Or I understand that you can use the Cocoa
    > framework and build on it with Apple Script Studio,
    > which I guess is different than embedding Apple
    > Scripts in Objective C.
    >
    > Can someone with experience give me a recommendation
    > of how to proceed?

    The upcoming second edition of my AppleScript book has a section on sending
    Apple events without using AppleScript, and one of the methods I demonstrate
    involves Cocoa. Here is some code:

    ae =
        [NSAppleEventDescriptor appleEventWithEventClass:'core'
                            eventID:'setd'
                            targetDescriptor:bbedit
                            returnID:kAutoGenerateReturnID
                            transactionID:kAnyTransactionID];
    [ae setParamDescriptor:
        [NSAppleEventDescriptor descriptorWithString:@"Hello, world!"]
                            forKeyword:'data'];
    AEDesc docu1;
    CreateObjSpecifier('docu',
                            [[NSAppleEventDescriptor nullDescriptor] aeDesc],
                            formAbsolutePosition,
                            [[NSAppleEventDescriptor descriptorWithInt32:1]
    aeDesc],
                            YES, &docu1);
    AEDesc allText;
    CreateObjSpecifier('ctxt', &docu1, formAbsolutePosition,
                            [[NSAppleEventDescriptor
    descriptorWithDescriptorType:
                                'abso' bytes:"all " length:4] aeDesc],
                            YES, &allText);
    NSAppleEventDescriptor* allTextDesc =
        [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&allText];
    [ae setParamDescriptor:allTextDesc forKeyword:keyDirectObject];
    AESendMessage([ae aeDesc], NULL,
                            kAENoReply | kAENeverInteract,
                            kAEDefaultTimeout);

    As you can see, I create the Apple event in Cocoa, but I create object
    specifiers and actually send the Apple event using Carbon. Cocoa is
    automatically linked to Carbon and Objective-C is C so this kind of hybrid
    is easy. m.

    --
    matt neuburg, phd = <matt...>, <http://www.tidbits.com/matt/>
    A fool + a tool + an autorelease pool = cool!
    AppleScript: the Definitive Guide
    <http://www.amazon.com/exec/obidos/ASIN/0596005571/somethingsbymatt>