0

I'm using the following Swift to execute an AppleScript to capture the currently selected message in Apple Mail.

func getMessage(messageID: String) -> String?
{
    if let url = Bundle.main.url(forResource: "getMessages", withExtension: "scpt") //need to add it to the build phases
    {
        var appleScriptError: NSDictionary? = nil
        guard let script = NSAppleScript(contentsOf: url, error: &appleScriptError) else 
        {
            return nil
        }

        let message = NSAppleEventDescriptor(string: messageID)

        let parameters = NSAppleEventDescriptor(listDescriptor: ())
        parameters.insert(message, at: 1)

        var psn = ProcessSerialNumber(highLongOfPSN: UInt32(0), lowLongOfPSN: UInt32(kCurrentProcess))

        let target = NSAppleEventDescriptor(descriptorType: typeProcessSerialNumber, bytes: &psn, length: MemoryLayout<ProcessSerialNumber>.size)

        let handler = NSAppleEventDescriptor(string: "getMessages")

        let event = NSAppleEventDescriptor.appleEvent(withEventClass: AEEventClass(kASAppleScriptSuite), eventID: AEEventID(kASSubroutineEvent), targetDescriptor: target, returnID: AEReturnID(kAutoGenerateReturnID), transactionID: AETransactionID(kAnyTransactionID))

        event.setParam(handler, forKeyword: AEKeyword(keyASSubroutineName))
        event.setParam(parameters, forKeyword: AEKeyword(keyDirectObject))

        var executeError: NSDictionary? = nil
        let result = script.executeAppleEvent(event, error: &executeError)
        if let executeError = executeError
        {
            print("ERROR: \(executeError)")
            return nil
        }
        else
        {
            return (result.stringValue ?? "")
        }
    }
    return nil
}

It's calling this AppleScript:

on getMessages(messageID)
    tell application "Mail"

        my dlog("Start getMessages")

        set theSelection to selection

        my dlog("Got the selection")

        set returnString to ""
        repeat with theMessage in selection
            set messageUUID to message id of theMessage
            my dlog("Message " & messageUUID)
            set messageSender to my getMessageSenderName(sender of theMessage)
            set messageBody to my getMessageBody(content of theMessage)
            set messageDate to my ISODate(date received of theMessage)

            my saveMessage(theMessage, mailPath)

        end repeat
        my dlog("End getMessages")
        return returnString
    end tell
    return "-"
end getMessages

on dlog(message)
    do shell script "logger -t 'AS DEBUG' getMessage: " & message
end dlog

The problem I am having is that any call to the selection command is taking forever to execute.

From Console:

10:49:39.036005+0100 getMessage: Start getMessages 10:50:03.618299+0100 getMessage: Got the selection 10:50:03.648670+0100 getMessage: Message 3c7f13fb334e41e21cf231212c77f199@www.domain.com 10:49:39.036005+0100 getMessage: Started 7

In this example it took 24 seconds to execute. The rest of the AppleScript was very fast. It doesn't matter how I restructure my code any call to selection takes this amount of time. Subsequent calls to selection are also fast.

If I execute the same command from AppleScript directly it is also very fast.

Am I doing something wrong or is there something else going on?

iphaaw
  • 6,764
  • 11
  • 58
  • 83
  • 1
    Have you tried sending a different command first (e.g. `get name of window 1`) to see if the slowness is in the first Apple event sent or `get selection` in particular? You might also enable [AEDebug*](http://hints.macworld.com/article.php?story=20030430145833233) on Mail so you can see exactly when it receives and responds to AEs. – foo May 18 '20 at 14:15
  • You were right. get name of window 1 was also slow. I have enabled AEDebug but how to see the logs? – iphaaw May 18 '20 at 19:15
  • You have to set the environment variables and launch Mail in a Terminal session, not from Finder. The exact command for setting environment variables vary depending on what shell you’re using; for zsh, use `export VARIABLE=VALUE`. The AE logs should display there. – foo May 18 '20 at 21:04
  • donot run your NSAppleScript on sync thread, do it in async. – Jack Martin Nov 09 '21 at 01:25

0 Answers0