rb-appscript

5. Targeting Applications

The Application class

The Application class represents an application to which Apple events will be sent. Its constructor allows applications to be identified in one of four ways: by full path, by eppc URL, by custom AEAddressDesc, or the host application if no other value is given. Its main method, #event, is used to construct the Apple events to send. Several utility methods are also provided.

Application -- the target application

    Class methods:

        process_exists_for_path?(path) -- Does a local process launched
                from the specified application file exist?
            path : string -- application's path, e.g. '/Applications/iCal.app'
            Result : boolean -- Note: if path is invalid, an AE::MacOSError
                    is raised.

        process_exists_for_pid?(pid) -- Is there a local application process
                with the given Unix process id?
            pid : integer
            Result : boolean
		
        process_exists_for_url?(url) -- Does an application process specified
                by the given eppc:// URL exist?
            url : string -- url for remote process
                    (e.g. 'eppc://user:pass@0.0.0.1/TextEdit')
            Result : boolean -- Returns false if process doesn't exist, or if
                    access isn't allowed.

        process_exists_for_desc?(desc) -- Does an application process specified
                by the given AEAddressDesc exist?
            desc : AE::AEDesc -- AEAddressDesc for application
            Result : boolean -- Returns false if process doesn't exist, or if
                    access isn't allowed.

        launch(path) -- launch an application in background if not
                already running, and send it a 'ascrnoop' event
            path : string -- application's path, e.g. '/Applications/iCal.app'
    
    Constructors:

        by_path(path)
            path : string -- full path to local application
                    (e.g. '/Applications/TextEdit.app')

        by_pid(pid)
            pid : integer -- Unix process id

        by_url(url)
            url : string -- url for remote process
                    (e.g. 'eppc://user:pass@0.0.0.1/TextEdit')

        by_desc(desc)
            desc : AEDesc -- AEAddressDesc for application

        current -- the host process

    Methods:

        event(...) -- construct an Apple event (see next chapter for details)

        begin_transaction(session=nil) -- begin a new transaction;
                all Events constructed after begin_transaction is
                called will belong to the same transaction until
                end_transaction or abort_transaction is called
            session : anything -- optional value identifying the 
                    specific session (where supported)

        end_transaction -- end the current transaction

        abort_transaction -- abort the current transaction

        reconnect -- Make sure this Application object has a valid
                AEAddressDesc for the target application, relaunching
                the target application if it's not currently running.
                (Note: this only works for Application objects created
                via the by_path constructor.)

Creating Application objects

When targeting a local application by path, the full path to the application (or application bundle) must be given, including a .app suffix if present. Note that aem identifies local applications by process serial number for reliability. If the target application is not already running when a new Application instance is created, it will be started automatically so that a PSN can be acquired. If the application can't be launched for some reason (e.g. if it's in the Trash), an AEM::CantLaunchApplicationError error will be raised.

If the by_url constructor is used, its url argument should be an eppc URL string. Aem will pack this as an AEDesc of typeApplicationURL. The target machine must have Remote Apple Events enabled in its Sharing preferences.

Clients can also supply their own AEAddressDesc if they prefer. This should be an AE::AEDesc of one of the following types:

KAE::TypeApplicationBundleID
KAE::TypeApplicationURL
KAE::TypeApplSignature
KAE::TypeKernelProcessID
KAE::TypeMachPort
KAE::TypeProcessSerialNumber

See the Apple Event Manager documentation for more information on these addressing modes.

Launching applications

Application.launch is a class method attached to the Application class for convenience. It allows a non-running application to be launched without sending it the 'run' event (aevtoapp) normally sent to applications - a 'no-op' event (ascrnoop) is sent instead. It should be called before creating an Application object for the target application, otherwise the application will be launched as normal.

Transactions

The #begin_transaction and #end_transaction methods are used to start and stop transaction sessions for applications that support this. All events created while a transaction session is active will be identified as part of that transaction.

Note that during a transaction, sending the application an event not created during that transaction will cause an error. Similarly, sending the application an event created during a transaction after that transaction has ended will cause an error.

The #end_transaction method must be called to close both successful and failed transactions on completion. If a transaction session is accidentally left open, aem will attempt to close it when the Application object is garbage-collected, although this cannot be guaranteed to succeed.

Reconnecting to local applications

Because local applications are identified by process serial number, an existing Application object created using the by_path constructor will no longer hold a valid AEAddressDesc if the target application subsequently quits. Sending events to an invalid address will cause a EventError -600 ("application isn't running") or -609 ("connection is invalid") to be raised.

The process_exists_for_path? class method can be used to check if a local application is running or not, given its full path.

Calling the #reconnect method will create a new AEAddressDesc for an existing Application object that was originally created via the by_path constructor. If the application is not running at the time, it will be started automatically.

Note that only Event instances created after #reconnect is called will receive the new AEAddressDesc. Any Event instances created before reconnect is called will still contain the old AEAddressDesc.