Доступ к нативным API

Фреймворк Quasar предоставляет единый слой абстракции для взаимодействия с нативными API различных платформ: браузера, мобильных устройств и настольных приложений. Это достигается за счёт интеграции с такими технологиями, как Cordova, Capacitor и Electron, что позволяет использовать аппаратные возможности устройства без необходимости писать платформенно-зависимый код.


Архитектура доступа к нативным API

Доступ к нативным функциям реализуется через:

  • Boot-файлы — инициализация плагинов
  • Wrapper-утилиты Quasar — унифицированные интерфейсы
  • Плагины Cordova/Capacitor — мост к нативному коду
  • Встроенные плагины Quasar — готовые решения для распространённых задач

Ключевой принцип — один и тот же API для разных платформ.


Использование плагинов Quasar

Quasar включает набор встроенных плагинов, упрощающих доступ к базовым возможностям:

AppVisibility

Отслеживание состояния приложения (активно/свернуто):

import { AppVisibility } from 'quasar'

AppVisibility.addEventListener(state => {
  console.log('Состояние приложения:', state)
})

Platform

Определение текущей платформы:

import { Platform } from 'quasar'

if (Platform.is.mobile) {
  console.log('Запуск на мобильном устройстве')
}

if (Platform.is.electron) {
  console.log('Electron окружение')
}

Screen

Доступ к параметрам экрана:

import { Screen } from 'quasar'

if (Screen.lt.md) {
  console.log('Маленький экран')
}

Интеграция с Cordova и Capacitor

Quasar CLI позволяет создавать проекты с поддержкой мобильных платформ:

quasar mode add capacitor

или:

quasar mode add cordova

После этого становится доступным использование нативных API через плагины.


Работа с камерой

Пример использования камеры через Capacitor:

npm install @capacitor/camera
npx cap sync
import { Camera, CameraResultType } from '@capacitor/camera'

async function takePhoto () {
  const image = await Camera.getPhoto({
    quality: 90,
    resultType: CameraResultType.Uri
  })

  console.log(image.webPath)
}

Особенности:

  • Поддержка iOS и Android
  • Возможность выбора источника (камера или галерея)
  • Работа с base64, URI и Blob

Геолокация

Доступ к координатам пользователя:

npm install @capacitor/geolocation
npx cap sync
import { Geolocation } from '@capacitor/geolocation'

async function getLocation () {
  const position = await Geolocation.getCurrentPosition()
  console.log(position.coords.latitude, position.coords.longitude)
}

Важно:

  • Требуется разрешение пользователя
  • На мобильных устройствах нужно прописывать permissions

Работа с файловой системой

Пример чтения и записи файлов:

npm install @capacitor/filesystem
npx cap sync
import { Filesystem, Directory } from '@capacitor/filesystem'

async function writeFile () {
  await Filesystem.writeFile({
    path: 'example.txt',
    data: 'Пример текста',
    directory: Directory.Documents
  })
}

Push-уведомления

Подключение уведомлений:

npm install @capacitor/push-notifications
npx cap sync
import { PushNotifications } from '@capacitor/push-notifications'

PushNotifications.requestPermissions().then(result => {
  if (result.receive === 'granted') {
    PushNotifications.register()
  }
})

PushNotifications.addListener('registration', token => {
  console.log('Токен:', token.value)
})

Использование Cordova-плагинов

При использовании Cordova API доступен через глобальный объект:

document.addEventListener('deviceready', () => {
  console.log('Cordova готов')
})

Пример работы с вибрацией:

cordova plugin add cordova-plugin-vibration
navigator.vibrate(1000)

Electron и доступ к системным API

В режиме Electron Quasar даёт доступ к Node.js API:

const fs = require('fs')

fs.writeFileSync('test.txt', 'Hello Electron')

Также можно использовать IPC (межпроцессное взаимодействие):

const { ipcRenderer } = require('electron')

ipcRenderer.send('message', 'данные')

Boot-файлы и инициализация API

Boot-файлы используются для настройки и подключения нативных возможностей:

quasar new boot my-native-api
export default async () => {
  // инициализация API
}

Регистрация в quasar.config.js:

boot: ['my-native-api']

Работа с разрешениями

На мобильных устройствах доступ к API требует явного разрешения:

import { Geolocation } from '@capacitor/geolocation'

const permissions = await Geolocation.checkPermissions()

if (permissions.location !== 'granted') {
  await Geolocation.requestPermissions()
}

Особенности:

  • iOS требует описания в Info.plist
  • Android требует записи в AndroidManifest.xml

Унификация API

Одна из ключевых задач Quasar — скрыть различия платформ:

import { Platform } from 'quasar'

function vibrate () {
  if (Platform.is.capacitor || Platform.is.cordova) {
    navigator.vibrate(500)
  }
}

Ограничения и особенности

  • Некоторые API доступны только на мобильных устройствах
  • Поведение может отличаться между iOS и Android
  • В браузере часть функций эмулируется или недоступна
  • Требуется обработка ошибок и fallback-логика

Лучшие практики

Изоляция платформенного кода

function getCamera () {
  if (!Platform.is.mobile) return null
  return Camera
}

Асинхронная обработка

Все нативные API работают через Promise:

try {
  const data = await someNativeCall()
} catch (e) {
  console.error(e)
}

Graceful degradation

if ('geolocation' in navigator) {
  navigator.geolocation.getCurrentPosition(...)
} else {
  console.log('Геолокация недоступна')
}

Кэширование данных

let cachedPosition = null

async function getPosition () {
  if (cachedPosition) return cachedPosition

  cachedPosition = await Geolocation.getCurrentPosition()
  return cachedPosition
}

Отладка нативных функций

  • Использование Chrome DevTools для Android
  • Safari DevTools для iOS
  • Electron DevTools для desktop
  • Логи через console.log и платформенные инструменты

Структурирование проекта

Рекомендуется:

  • Выносить работу с API в отдельные сервисы
  • Использовать boot-файлы для инициализации
  • Делать обёртки над плагинами

Пример структуры:

src/
 ├── boot/
 ├── services/
 │    ├── camera.js
 │    ├── location.js
 │    └── filesystem.js

Пример сервиса для камеры

// src/services/camera.js

import { Camera, CameraResultType } from '@capacitor/camera'

export async function takePhoto () {
  return await Camera.getPhoto({
    quality: 80,
    resultType: CameraResultType.Uri
  })
}

Расширение через собственные плагины

Возможна разработка собственных нативных расширений:

  • Создание плагина Capacitor
  • Написание кода на Java/Kotlin (Android)
  • Использование Swift/Objective-C (iOS)

Безопасность

  • Проверка разрешений перед вызовом API
  • Валидация входных данных
  • Ограничение доступа к чувствительным функциям
  • Использование HTTPS

Кроссплатформенные различия

API Web Android iOS Electron
Камера частично да да нет
Геолокация да да да да
Файловая система ограничено да да да
Push нет да да да

Производительность

  • Минимизация количества нативных вызовов
  • Использование batching
  • Кэширование результатов
  • Lazy loading плагинов

Управление жизненным циклом

document.addEventListener('pause', () => {
  console.log('Приложение свернуто')
})

document.addEventListener('resume', () => {
  console.log('Приложение активно')
})

Тестирование

  • Эмуляторы Android/iOS
  • Реальные устройства
  • Mock-объекты для unit-тестов
jest.mock('@capacitor/geolocation', () => ({
  Geolocation: {
    getCurrentPosition: jest.fn()
  }
}))

Подход к масштабированию

  • Абстракция над API
  • Использование DI (dependency injection)
  • Разделение бизнес-логики и платформенных вызовов
  • Централизованное управление ошибками