Однажды передо мной встала задача показать файлы с удаленного сервера нативно в 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. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи один материал

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


Оставить мнение

Check Also

FPGA. Создаем хардверный счетчик в Xilinx Vivado, чтобы освоить инструменты разработки ПЛИС

Если ты хочешь превратить код в микросхему, используя FPGA, то эта статья поможет тебе осв…