Как добавить Flutter в нативное приложение iOS и протестировать его на Codemagic (Часть 2)

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Hola, Amigos! На связи Саша Чаплыгин, Flutter dev компании заказной разработки Amiga. Нашел интересную статью на английском о том, как добавить Flutter в новый или существующий проект Native iOS. Решил поделиться с вами переводом. Это вторая часть, в которой будет идти речь про реализацию экрана Flutter в приложение для iOS и использование platform channel.

Первая часть здесь. Она посвящена созданию приложения на iOS и интеграции Flutter в это приложение. 

Третья часть выйдет совсем скоро. Чтобы не пропустить, подписывайтесь на наш телеграм-канал Flutter. Много. Там мы с командой делимся опытом, интересными мероприятиями для разработчиков и другой полезной информацией. В последней статье рассмотрим использование «Hot Reload», «Hot Restart» и тестирование на Codemagic.

Поехали!

Добавление экрана Flutter в приложение iOS

FlutterViewController используется для отображения экрана Flutter внутри приложения iOS. Но также потребуется создать FlutterEngine.

Подходящее место для создания FlutterEngine — внутри AppDelegate.swift.

Заменяем все содержимое этого файла следующим кодом:

// AppDelegate.swift
import UIKit
import Flutter
import FlutterPluginRegistrant
@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
    
    var flutterEngine : FlutterEngine?;
    
    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        self.flutterEngine = FlutterEngine(name: "io.flutter", project: nil);
        self.flutterEngine?.run(withEntrypoint: nil);
        GeneratedPluginRegistrant.register(with: self.flutterEngine!);
        return super.application(application, didFinishLaunchingWithOptions: launchOptions);
    }
}

Теперь просто добавляем в файл следующие строки ViewController.swift, чтобы отобразить экран на Flutter:

// ViewController.swift
// ...
import Flutter
class ViewController: UIViewController {
    
    // ...
    
    @IBAction func calculatePressed(_ sender: UIButton) {
        // ...
        let flutterEngine = ((UIApplication.shared.delegate as? AppDelegate)?.flutterEngine)!;
        let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil);
        self.present(flutterViewController, animated: true, completion: nil)
    }
}

Если запустим приложение сейчас, то сможем просмотреть экран приложения Flutter Demo Counter, нажав кнопку «CALCULATE» .

Обратитесь к официальной документации Flutter для получения дополнительной информации.

Завершение пользовательского интерфейса Flutter

Пользовательский интерфейс экрана результатов ИМТ будет очень простым и будет содержать всего несколько текстовых виджетов.

Код для пользовательского интерфейса экрана результатов ИМТ:

// main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BMI Calculator Module',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  Future<void> _receiveFromHost(MethodCall call) async {
    // To be implemented.
    // Will be used for retrieving data passed from
    // the native iOS app.
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.blue,
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(
                'YOUR BMI',
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 40,
                    fontWeight: FontWeight.bold),
              ),
              Text(
                '23.7',
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 70,
                    fontWeight: FontWeight.bold),
              ),
              Text(
                'Fit as a fiddle!',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Использование Platform Channel

Используем Platform Channel для передачи данных из приложения iOS в модуль Flutter.

Настройка модуля Flutter (получение данных)

  1. Прежде всего, нужно создать канал с каким-нибудь именем внутри класса _MyHomePageState.

// main.dart
static const platform = const MethodChannel('com.souvikbiswas.bmi/data');
  1. Создаем метод _receiveFromHost(), который будет извлекать данные, переданные из нативной части, и получим данные для отображения внутри модуля Flutter.

// main.dart
Future<void> _receiveFromHost(MethodCall call) async {
   var jData;
 
   try {
     print(call.method);
 
     if (call.method == "fromHostToClient") {
       final String data = call.arguments;
       print(call.arguments);
       jData = await jsonDecode(data);
     }
   } on PlatformException catch (error) {
     print(error);
   }
 
   setState(() {
     jData1 = jData;
     if (jData['color'] == 'blue') {
       color = Colors.blue;
     } else if (jData['color'] == 'green') {
       color = Colors.green;
     } else {
       color = Colors.pink;
     }
   });
 }
  1. Устанавливаем _receiveFromHost()метод как Обработчик вызова метода setMethodCallHandler.

// main.dart
_MyHomePageState() {
     platform.setMethodCallHandler(_receiveFromHost);
}
  1. Пишем код для метода build, чтобы отображать данные, полученные с использованием Platform Channel:

// main.dart
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: color, // Updated
        child: Center(
          child: Column(
            // ...
            children: <Widget>[
              Text(
                'YOUR BMI',
                // ...
              ),
              Text(
                jData1['value'], // Updated
                // ...
              ),
              Text(
                jData1['advice'], // Updated
                // ...
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Настройка приложения iOS (отправка данных)

  1. Создаем канал для общения с модулем Flutter

// Define inside calculatePressed() method
let bmiDataChannel = FlutterMethodChannel(name: "com.souvikbiswas.bmi/data", binaryMessenger: flutterViewController.binaryMessenger)
  1. Отправляем данные по каналу

// Define inside calculatePressed() method
 let bmiDataChannel = FlutterMethodChannel(name: "com.souvikbiswas.bmi/data", binaryMessenger: flutterViewController.binaryMessenger)
     
 let jsonObject: NSMutableDictionary = NSMutableDictionary()
 jsonObject.setValue(bmiValue, forKey: "value")
 jsonObject.setValue(bmiAdvice, forKey: "advice")
 jsonObject.setValue(bmiColor, forKey: "color")
 
 var convertedString: String? = nil
 
 do {
     let data1 =  try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions.prettyPrinted)
     convertedString = String(data: data1, encoding: String.Encoding.utf8)
 } catch let myJSONError {
     print(myJSONError)
 }
     
 bmiDataChannel.invokeMethod("fromHostToClient", arguments: convertedString)

На этом вторая часть статьи подошла к концу. Мы рассмотрели реализацию экрана Flutter в приложение для iOS и использование platform channel. В последней части речь будет идти про использование «Hot Reload», «Hot Restart» и тестирование на Codemagic.

Чтобы не пропустить анонс, подписывайтесь на наш телеграм-канал Flutter. Много!

Если вы пропустили 1 часть статьи, то она здесь.

Источник: https://habr.com/ru/articles/775928/


Интересные статьи

Интересные статьи

Мы продолжаем изучать летопись функционального развития легендарного редактора FineReader PDF. Первую часть 30-летней истории можно прочитать здесь. А сейчас перенесемся в середину нулевых. 
В первой части этой серии мы обсудили модули проверки подключения, установки некоторых пакетов и выполнения ряда команд на целевых узлах. Во второй части изучили различные модули, используемые для обр...
Состояния загрузки и ошибки очень часто встречаются в приложениях, работающих асинхронно.Если мы не отобразим пользовательский интерфейс (UI) загрузки или ошибки, когда это необходимо, пользователи мо...
Не секрет, что большинство из нас, когда речь заходит о таких вещах, как управление сервером или кластером Kubernetes, в первую очередь думают не про какой-то GUI, а любимый терминал. Для многих это к...
Продолжение моей первой статьи о переезде в Данию. В этой части я расскажу о том, как я обустраивался и искал жильё, оформлении документов, своей работе и стоимости жизни...