Створення Flutter-плагіну для нативної функціональності

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Створення Flutter-плагіну для нативної функціональності
Складний
~5 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Створення Flutter-плагінів для нативної функціональності

Flutter надає великий набір пакетів на pub.dev, але рано чи пізно зустрічаєтесь з функціональністю, якої немає в жодному готовому плагіні: проприєтарний SDK партнера, специфічна робота з залізом, інтеграція з корпоративною системою через нативний агент. Тут починається розробка власного плагіна через Platform Channels.

Архітектура Platform Channel

Flutter спілкується з нативним кодом через MethodChannel, EventChannel та BasicMessageChannel. Вибір залежить від паттерну взаємодії:

  • MethodChannel—виклик нативного методу та отримання результату (request/response)
  • EventChannel—потік подій із нативного коду в Dart (підписки на hardware-события)
  • BasicMessageChannel—двонаправлена передача довільних даних з кастомним кодеком

Типичний приклад: плагін для роботи з BLE-пристроєм. Сканування пристроїв—EventChannel (неперервний потік знайдених пристроїв). Підключення/відключення—MethodChannel. Отримання сповіщень від характеристики—знову EventChannel.

Структура плагіна

Створюємо через flutter create --template=plugin my_plugin. Структура:

my_plugin/
  lib/my_plugin.dart          — Dart API
  android/src/.../MyPlugin.kt — Android реалізація
  ios/Classes/MyPlugin.swift  — iOS реалізація
  example/                    — приклад додатку для тестування

Dart-сторона об'являє контракт:

class MyPlugin {
  static const MethodChannel _channel = MethodChannel('my_plugin');

  static Future<String?> getPlatformVersion() async {
    return await _channel.invokeMethod<String>('getPlatformVersion');
  }

  static Stream<ScanResult> get scanResults {
    return const EventChannel('my_plugin/scan_results')
        .receiveBroadcastStream()
        .map((data) => ScanResult.fromMap(Map<String, dynamic>.from(data)));
  }
}

Android-реалізація: FlutterPlugin + ActivityAware

На Android плагін реалізує FlutterPlugin для lifecycle, MethodCallHandler для обробки вызовів. Якщо потрібний Activity (наприклад для permission request), додатково ActivityAware:

class MyPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
    private lateinit var channel: MethodChannel
    private var activity: Activity? = null

    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(binding.binaryMessenger, "my_plugin")
        channel.setMethodCallHandler(this)
    }

    override fun onMethodCall(call: MethodCall, result: Result) {
        when (call.method) {
            "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}")
            else -> result.notImplemented()
        }
    }

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        activity = binding.activity
    }
}

Критична деталь: result.success(), result.error() та result.notImplemented() повинні вызиватися рівно один раз. Виклик result.success() двічі—краш IllegalStateException: Reply already submitted.

iOS-реалізація на Swift

public class MyPlugin: NSObject, FlutterPlugin {
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(
            name: "my_plugin",
            binaryMessenger: registrar.messenger()
        )
        let instance = MyPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        switch call.method {
        case "getPlatformVersion":
            result("iOS " + UIDevice.current.systemVersion)
        default:
            result(FlutterMethodNotImplemented)
        }
    }
}

Передача складних типів

StandardMessageCodec (за замовчуванням) підтримує примітиви, List, Map. Для кастомних об'єктів—серіалізуємо в Map<String, dynamic> на Dart-стороні та отримуємо HashMap на Kotlin / [String: Any] на Swift. Альтернатива: Pigeon—інструмент від Flutter team для генерації type-safe API за .dart-специфікацією. Pigeon генерує Kotlin/Swift код з типізованими класами—виключає runtime-помилки від опечаток у іменах методів.

EventChannel та витоки пам'яті

При використанні EventChannel на Android нативна сторона отримує EventSink. Типова утічка: тримаємо EventSink в полі класу, Activity пересоздається при повороті екрана, старий EventSink не валідується—і виклик sink.success() після знищення викидає виключення. Рішення: обнулювати sink в onCancel() та перевіряти перед кожним вызовом.

Публікація та версионування

Для внутрішнього використання плагін живе в git-репозиторії та підключається через path або git залежність в pubspec.yaml. Для публікації на pub.dev—flutter pub publish з обов'язковим pubspec.yaml з homepage, repository, повним CHANGELOG.md.

Розробка плагіна: простий (1–2 методи, одна платформа)—2–4 дні. Повноцінний cross-platform з EventChannel, permissions та edge-case handling—2–4 тижні. Вартість розраховується індивідуально.