• Партнер

  • Однажды передо мной встала задача показать файлы с удаленного сервера нативно в Finder. Первое, что пришло на ум, — использовать WebDAV, но это был публичный сервис, к серверу которого у меня не было доступа, а в распоряжении имелся только REST API. В голове промелькнула мысль написать свою файловую систему, но она казалась слишком амбициозной. Однако мои сомнения развеялись, когда я обнаружил, что сообщество энтузиастов развивает проект FUSE for macOS, который сводит создание собственной файловой системы к нескольким сотням строк кода. А идущий в комплекте фреймворк не требует унылых разбирательств с API на голом C и вполне пригоден для использования в комплекте с современным и мощным Swift.
     

    Что такое FUSE?

    FUSE (Filesystem in Userspace) — это интерфейс для программ пространства пользователя, позволяющий экспортировать файловую систему ядру ОС. Этот механизм появился в Linux, и условно его можно разделить на два базовых компонента: модуль ядра (поддерживается разработчиками ядра) и библиотека пользовательского пространства (libfuse). Эта библиотека предоставляет методы для монтирования, размонтирования, отправки запросов к ядру и получения ответов от него. Также она реализует удобный верхнеуровневый API, в котором мы можем оперировать привычными понятиями имен файлов и путей, вместо работы с inode.

    Проект FUSE for macOS представляет собой аналогичный набор API (а также Objective-C фреймворк), позволяющий реализовать полноценную файловую систему, которая будет работать в пространстве пользователя на macOS. Так как его API является надмножеством FUSE API из Linux, то существует теоретическая возможность завести многие из существующих файловых систем на macOS. В настоящее время этот проект остается единственной реализацией FUSE для macOS, которая развивается и поддерживается силами сообщества, хотя и активность на GitHub и в Google Groups сейчас довольно низкая.

    Где еще используется FUSE?

    Загрузка ... Загрузка ...
     

    Установка фреймворка

    Установка не отличается сложностью: скачиваешь инсталлятор с сайта разработчика и запускаешь его. Если предпочитаешь собирать такие вещи из исходников, то это тоже не составит труда: достаточно установить зависимости через brew и запустить сборочный скрипт, все это подробно описано в Readme на GitHub.

     

    Настройка проекта

    Создание нового проекта в Xcode
    Создание нового проекта в Xcode

    Создадим новый проект в Xcode. Это должно быть Cocoa Application (в разделе macOS), я назвал его HelloFuse, язык выберем Swift, остальные параметры можно выбрать на свое усмотрение.

     

    Подключим фреймворк

    Расположение фреймворка OSXFUSE
    Расположение фреймворка OSXFUSE

    После установки фреймворк будет расположен по следующему пути: /Library/Frameworks/OSXFUSE.framework. Чтобы добавить его в проект, достаточно просто перетащить его в раздел Linked Frameworks and Libraries на вкладке General настроек сборки.

    Подключение фреймворка
    Подключение фреймворка
     

    Создадим Bridging Header

    Так как мы пишем проект на Swift, а фреймворк реализован на Objective-C, то нам нужно создать и подключить так называемый Bridging Header. Создадим заголовочный файл (File → New → File → macOS → Source → Header File), назовем его HelloFuse-Bridging-Header.h и добавим в него следующую строчку:

     #import <OSXFUSE/OSXFUSE.h>
    

    Теперь на панели навигации выбираем наш проект, выбираем сборку в разделе Targets, переходим на вкладку Build Settings, находим раздел Swift Compiler → General, в поле Objective-C Bridging Header добавляем

    $(PROJECT_DIR)/$(TARGET_NAME)/HelloFuse-Bridging-Header.h
    
    Подключаем Bridging Header в настройках проекта
    Подключаем Bridging Header в настройках проекта
     

    Отключим Sandbox

    По умолчанию во всех приложениях включена песочница, которая ограничивает возможности приложения, но в отличие от iOS на macOS ее можно отключить. Этим ты потеряешь право распространять приложение через App Store (что тоже не будет проблемой в случае с macOS), но в нашем случае нам нужен полноценный доступ к файловой системе, поэтому выбора нет.

    Перейдем на вкладку Capabilities в настройках сборки и поставим переключатель в пункте App Sandbox в положение OFF.

     

    Hello world

     

    Описание файловой системы

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

    В методе, отвечающем за отображение файлов, нужно вернуть массив строк с именами файла. В качестве параметра туда приходит путь (path), в более сложных случаях нужно будет его обрабатывать, чтобы показывать контент соответствующей директории. Здесь я просто возвращаю один файл hello.txt.

    override func contentsOfDirectory(atPath path: String) throws &rarr; [Any] {
        return ["hello.txt"]
    }
    

    В метод, который отвечает за отображение пути файла, аналогично приходит путь, в зависимости от которого мы должны решить, какое содержимое отдавать для файла. В нашем же примере мы будем для всех файлов возвращать строку «Hello world!».

    override func contents(atPath path: String) &rarr; Data? {
        return  "Hello world!".data(using: .utf8)
    }
    

    В итоге файл HelloFS.swift примет следующий вид:

    import Foundation
    
    final class HelloFS: NSObject {
    
        override func contentsOfDirectory(atPath path: String) throws &rarr; [Any] {
            return ["hello.txt"]
        }
    
        override func contents(atPath path: String) &rarr; Data? {
            return  "Hello world!".data(using: .utf8)
        }
    
    }
    

    Продолжение доступно только участникам

    Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

    Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

    Вариант 2. Открой один материал

    Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


    Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии