Навигация

Mail App

Ускорение поиска нужного почтового ящика

Изначальный вариант функции, которая искала в учётной записи Account ящик, в имени которого есть Desired:

on SearchMailboxes(Account, Desired)
	tell application "Mail"
		
		set ListOfNames to {}
		set ListOfMailboxes to {}
		set ListIndex to 0
		
		repeat with i in every mailbox of Account
			set iName to name of i
			if iName contains Desired then
				set ListIndex to ListIndex + 1
				if ListIndex < 10 then
					set ListIndexName to "0" & (ListIndex as string) & ". "
				else
					set ListIndexName to (ListIndex as string) & ". "
				end if
				set end of ListOfNames to ListIndexName & iName
				set end of ListOfMailboxes to i
				
			end if
		end repeat
		
	end tell
	return {ListOfNames, ListOfMailboxes, ListIndex}
end SearchMailboxes

В macOS Tahoe функция стала работать отвратительно медленно, поиск увеличился в моём случае с пару секунд до нескольких минут. Изначально казалось, что проблема в beta-версии, но и после официального релиза ничего не изменилось. Апгрейд пришлось отложить.

При очередном поиске вариантов решения проблемы случайно вот тут наткнулся на комментарий:

It seems the issue isn’t with AppleScript, but with Script Editor, after confirming it with a back and forth with an Apple engineer. I’m still not convinced of why this should be the case, but the script runs a lot better when run via osascript, especially after refactoring it to use a whose statement when fetching messages, rather than iterating over them with an if condition.

И ещё одна подсказка нашлась тут - пример конструкции с использованием whose для другого случая:

tell application "Finder" to move my ((choose folder)'s files whose name contains "Zebra") to desktop

Это изменило всё!

Новый вариант с whose работает прекрасно:

on SearchMailboxes_speedy(Account, Desired)
	tell application "Mail"
		
		set ListOfNames to {}
		set ListOfMailboxes to {}
		set ListIndex to 0
		
		set filtered_malbox_list to (every mailbox of Account) whose name contains Desired
		set ListOfMailboxes to filtered_malbox_list
		
		repeat with i in filtered_malbox_list
			set iName to name of i
			set ListIndex to ListIndex + 1
			if ListIndex < 10 then
				set ListIndexName to "0" & (ListIndex as string) & ". "
			else
				set ListIndexName to (ListIndex as string) & ". "
			end if
			set end of ListOfNames to ListIndexName & iName
		end repeat
		
	end tell
	return {ListOfNames, ListOfMailboxes, ListIndex}
end SearchMailboxes_speedy