Как правильно запускать AppleScript в Mail.app с помощью NSAppleScript и парсить результаты как список строк.

Вопрос или проблема

У меня есть следующий код, который я хотел бы использовать для получения списка доступных учетных записей электронной почты в Mail.app.

import Foundation

struct EmailAccounts {
    func getAccountNames() -> [String] {
        let appleScriptSource = """
        tell application "Mail"
            set accountDict to {}
            repeat with acc in accounts
                set accName to name of acc
                set accEmails to email addresses of acc
                set accountDict's end to {accName:accEmails}
            end repeat
            return accountDict
        end tell
        """

        var error: NSDictionary?
        var accountNames: [String] = []

        if let scriptObject = NSAppleScript(source: appleScriptSource) {
            let scriptResult = scriptObject.executeAndReturnError(&error)
            if let listDescriptor = scriptResult.coerce(toDescriptorType: typeAEList) {
                for index in 1...listDescriptor.numberOfItems {
                    if let listItemString = listDescriptor.atIndex(index)?.stringValue {
                        accountNames.append(listItemString)
                    }
                }
            }
        }

        return accountNames

    }
}

Отладка показывает, что scriptResult.coerce(toDescriptorType: typeAEList) возвращает nil, так как устанавливаемые точки останова ниже, в цикле, не срабатывают.

AppleScript выполняется без проблем и возвращает список имен учетных записей и связанных с ними адресов электронной почты.

tell application "Mail"
    set accountInfoList to {}
    repeat with acc in accounts
        set accName to name of acc
        set accEmails to email addresses of acc
        set end of accountInfoList to {accName, accEmails}
    end repeat
    return accountInfoList
end tell

Результаты Apple Script

Вопрос: Как я могу использовать объект scriptResult, чтобы получить массив строк, представляющий вывод, полученный с помощью AppleScript?


В данный момент я игнорирую тот факт, что выводы должны рассматриваться как вложенный массив с несколькими адресами электронной почты, прикрепленными к одной учетной записи, но я могу разобраться с этой незначительной проблемой позже.

Ответ или решение

Ваша задача заключается в использовании AppleScript через NSAppleScript для получения списка аккаунтов электронной почты в Mail.app и последующем парсинге результатов в виде массива строк. Давайте исправим ваш код, чтобы он правильно обрабатывал вывод AppleScript.

Во-первых, ваше текущее обращение к AppleScript возвращает не список, а более сложную структуру данных, поэтому вам нужно будет разобрать её, чтобы получить нужный формат. Вот пример исправленного кода:

import Foundation

struct EmailAccounts {
    func getAccountNames() -> [String] {
        let appleScriptSource = """
        tell application "Mail"
            set accountInfoList to {}
            repeat with acc in accounts
                set accName to name of acc
                set accEmails to email addresses of acc
                set end of accountInfoList to {accName, accEmails} -- Список пар (имя аккаунта, список адресов)
            end repeat
            return accountInfoList
        end tell
        """

        var error: NSDictionary?
        var accountNames: [String] = []

        if let scriptObject = NSAppleScript(source: appleScriptSource) {
            let scriptResult = scriptObject.executeAndReturnError(&error)

            if let listDescriptor = scriptResult coerce(toDescriptorType: typeAEList) {
                for index in 1...listDescriptor.numberOfItems {
                    if let accountInfo = listDescriptor.atIndex(index) {
                        let accName = accountInfo.atIndex(1)!.stringValue // Имя аккаунта
                        accountNames.append(accName)
                    }
                }
            }
        }

        if let error = error {
            print("Ошибка выполнения AppleScript: \(error)")
        }

        return accountNames
    }
}

Объяснение кода:

  1. AppleScript: Мы изменили скрипт так, чтобы он возвращал список пар, где каждой паре соответствует имя аккаунта и массив его адресов электронной почты.

  2. Обработка результата: Мы используем coerce(toDescriptorType: typeAEList) для преобразования результата выполнения скрипта в список. Затем мы проходим по элементам списка и извлекаем имя аккаунта из каждой пары, которую мы сохранили в accountInfoList.

  3. Обработка ошибок: В конце мы добавили обработку ошибок. Если возникает ошибка при выполнении AppleScript, она будет выведена в консоль.

Замечания:

  • На данный момент мы не обрабатываем адреса электронных почт (вторую часть каждой пары). Если вы хотите их добавить в массив или иным образом обрабатывать, вы можете сделать это в том же цикле.
  • Убедитесь, что ваше приложение имеет необходимые разрешения для обращения к Mail.app.

Данный подход должен успешно обеспечивать извлечение имён аккаунтов из Mail.app с помощью AppleScript и их последующее парсинг в массив строк.

Оцените материал
Добавить комментарий

Капча загружается...