Есть ли более быстрый способ просмотреть установленные приложения в macOS?

Я пишу дополнительную строку меню, которая показывает вам список ваших установленных приложений и позволяет вам нажимать на каждую кнопку в списке, чтобы открыть это приложение. Очевидно, для этого мне нужен список всех приложений, которые есть у пользователя. Конкретный способ, который я выбрал для этого, заключался в создании функции, которая будет перебирать файлы в системной папке «Приложения», удалять все в содержимом приложения или то, что не заканчивается на .app, и возвращать массив, содержащий список файлов. как имена, которые затем повторяются для создания списка «кнопок приложения», которые пользователь может нажать, чтобы запустить приложение.

Код для моей функции

func enumerateAppsFolder() -> Array<String> {
    var fileNames:Array<String> = []
    
    let fileManager = FileManager.default
    let enumerator:FileManager.DirectoryEnumerator = fileManager.enumerator(atPath:"/Applications/")!
    
    while let element = enumerator.nextObject() as? String {
        if element.hasSuffix("app") && !element.contains("Contents") { // checks the extension
            fileNames.append(element)
        }
    }
    return fileNames
}

И я создаю свой список с

ForEach(enumerateAppsFolder(), id:\.self){
    AppBarMenuItem(itemAppName: $0)
}

Но когда я делаю это таким образом, результат оказывается таким, как я ожидал, но производительность ужасна. Это видно на снимке экрана, и будет только хуже из-за больших папок приложений в системах некоторых людей. (Когда приложение запускается, что занимает около 5 минут, загрузка ЦП и диска также чрезвычайно высока) Есть ли лучший и более быстрый метод, который будет извлекать каждое приложение в системе, аналогично панели запуска macOS или списку «Открыть с помощью ..»?

[JS за 1 час] - 9. Асинхронный
[JS за 1 час] - 9. Асинхронный
JavaScript является однопоточным, то есть он может обрабатывать только одну задачу за раз. Для обработки длительных задач, таких как сетевые запросы,...
Топ-10 компаний-разработчиков PHP
Топ-10 компаний-разработчиков PHP
Если вы ищете надежных разработчиков PHP рядом с вами, вот список лучших компаний по разработке PHP.
Скраппинг поиска Apple App Store с помощью Python
Скраппинг поиска Apple App Store с помощью Python
📌Примечание: В этой статье я покажу вам, как скрапировать поиск Apple App Store и получить точно такой же результат, как на Apple iMac, потому что...
Редкие достижения на Github ✨
Редкие достижения на Github ✨
Редкая коллекция доступна в профиле на GitHub ✨
Подъем в javascript
Подъем в javascript
Hoisting - это поведение в JavaScript, при котором переменные и объявления функций автоматически "перемещаются" в верхнюю часть соответствующих...
Улучшение генерации файлов Angular
Улучшение генерации файлов Angular
Angular - это фреймворк. Вы можете создать практически любое приложение без использования сторонних библиотек.
3
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Вот обновленная версия вашей функции, которая получает .skipsSubdirectoryDescendants непосредственно из URL для папки «Приложения», а затем выполняет неглубокое перечисление, чтобы получить список приложений.

func enumerateAppsFolder() -> [String] {
    var appNames = [String]()

    let fileManager = FileManager.default
    if let appsURL = fileManager.urls(for: .applicationDirectory, in: .localDomainMask).first {
        if let enumerator = fileManager.enumerator(at: appsURL, includingPropertiesForKeys: nil, options: .skipsSubdirectoryDescendants) {
            while let element = enumerator.nextObject() as? URL {
                if element.pathExtension == "app" { // checks the extension
                    appNames.append(element.deletingPathExtension().lastPathComponent)
                }
            }
        }
    }

    return appNames
}

print(enumerateAppsFolder())

Пример вывода при запуске с игровой площадки Swift:

«Числа», «Dropbox», «Xcode», «Apple Configurator 2», «iMovie»

Это сработало отлично! Он получил все в папке «Приложения» всего за несколько миллисекунд. Хотя этот ответ работает нормально, я посмотрю, найдет ли кто-нибудь еще способ перечислить приложения, более похожие на то, как их перечисляет системная информация, панель запуска и т. д.

AcinonX 19.11.2022 01:55

Каким образом вы ищете другой результат? Приведите конкретный пример.

HangarRash 19.11.2022 02:11

Что-то вроде того, как Launchpad перечисляет приложения. Я знаю, как составить список приложений, но я не знаю, как получить приложения так, как это делается.

AcinonX 19.11.2022 02:15

Опять же, приведите четкий конкретный пример того, что вы имеете в виду. Вы спрашиваете об отображении приложений со значками в сетке или о чем-то еще? Опять же, будьте конкретны.

HangarRash 19.11.2022 02:28

Я имел в виду отображение каждого приложения, которое пользователь установил в списке. Launchpad показывает папки и группы приложений, и, кажется, ищет приложения в нескольких местах. Я хотел узнать, как это делается.

AcinonX 19.11.2022 02:34

Вы заметите в коде, который я разместил, использование .localDomainMask. Это получает приложения от /Applications. Если вы запустите это с .userDomainMask, вы получите приложения от ~/Applications. Вам также может потребоваться добавить проверку, чтобы увидеть, действительно ли возвращаемый URL-адрес приложения является папкой (например, «Утилиты»), а также выполнить поиск в этой папке. Возможно, это то, что вы ищете.

HangarRash 19.11.2022 02:49

Другие вопросы по теме