Вопрос или проблема
У меня есть следующий код, который я хотел бы использовать для получения списка доступных учетных записей электронной почты в 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
Вопрос: Как я могу использовать объект 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
}
}
Объяснение кода:
-
AppleScript: Мы изменили скрипт так, чтобы он возвращал список пар, где каждой паре соответствует имя аккаунта и массив его адресов электронной почты.
-
Обработка результата: Мы используем
coerce(toDescriptorType: typeAEList)
для преобразования результата выполнения скрипта в список. Затем мы проходим по элементам списка и извлекаем имя аккаунта из каждой пары, которую мы сохранили вaccountInfoList
. -
Обработка ошибок: В конце мы добавили обработку ошибок. Если возникает ошибка при выполнении AppleScript, она будет выведена в консоль.
Замечания:
- На данный момент мы не обрабатываем адреса электронных почт (вторую часть каждой пары). Если вы хотите их добавить в массив или иным образом обрабатывать, вы можете сделать это в том же цикле.
- Убедитесь, что ваше приложение имеет необходимые разрешения для обращения к Mail.app.
Данный подход должен успешно обеспечивать извлечение имён аккаунтов из Mail.app с помощью AppleScript и их последующее парсинг в массив строк.