Как добавить Flutter в нативное приложение iOS и протестировать его на Codemagic (Часть 1)
Hola, Amigos! На связи Саша Чаплыгин, Flutter dev компании заказной разработки Amiga. Нашел интересную статью, решил поделиться переводом. Автор материала рассказывает, как добавить Flutter в новый или существующий проект Native iOS и протестировать его на Codemagic CI/CD с помощью codemagic.yaml
.
Всю статью пришлось разделить на 3 части для упрощения восприятия, поэтому сегодня мы рассмотрим создание приложения на iOS и интеграцию Flutter в это приложение.
Вторая часть будет посвящена реализации экрана Flutter в приложение для iOS и использованию platform channel для отправки данных из натива во Flutter.
И третья часть будет про использование «Hot Reload», «Hot Restart» и тестирование на Codemagic.
Чтобы не пропустить анонсы статей, подписывайтесь на наш телеграм-канал Flutter. Много. Там мы с командой делимся опытом, полезными советами, рассказываем про интересные ивенты и многое другое.
Поехали!
Обзор приложения
Начнем с создания приложения для iOS. Оно представляет собой простой калькулятор индекса массы тела (ИМТ).
Приложение имеет два экрана:
Экран расчета ИМТ (с использованием встроенной iOS).
Экран результатов ИМТ (с использованием Flutter).
Создание приложения для iOS
Запускаем Xcode в системе.
Нажимаем «Создать новый проект Xcode».
Переходим на вкладку iOS и выбираем «App» или «Single View App». Нажимаем Далее.
Вводим название приложения, выбираем «Team» и остальные данные. Затем нажимаем Далее.
Создан пустой проект iOS со всеми необходимыми файлами.
Работаем над приложением для iOS
Прежде всего, нужно сверстать экраны приложения. Итак, переходим к файлу Main.storyboard
и реализуем дизайн пользовательского интерфейса.
Приложение будет содержать только один экран с некоторыми основными компонентами. Связываем компоненты пользовательского интерфейса с ViewController.swift
.
// ViewController.swift
import UIKit
class ViewController: UIViewController {
// Reference to the UI components
@IBOutlet weak var heightLabel: UILabel!
@IBOutlet weak var weightLabel: UILabel!
@IBOutlet weak var heightSlider: UISlider!
@IBOutlet weak var weightSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func heightSliderChanged(_ sender: UISlider) {
// Perform some action when height slider position
// is changed.
}
@IBAction func weightSliderChanged(_ sender: UISlider) {
// Perform some action when weight slider position
// is changed.
}
@IBAction func calculatePressed(_ sender: UIButton) {
// Perform some action when calculate button
// is pressed.
}
}
Теперь создаем два новых файла, чтобы проект был организован:
BMI.swift
— этот файл будет содержать struct BMI для описания важной информации BMI.CalculatorBrain.swift
— этот файл будет отвечать за получение данных и расчет ИМТ человека.
// BMI.swift
import UIKit
struct BMI {
let value: Float
let advice: String
let color: String
}
// CalculatorBrain.swift
import UIKit
struct CalculatorBrain {
var bmi: BMI?
func getBMIValue() -> String {
let bmiTo1DecimalPlace = String(format: "%.1f", bmi?.value ?? 0.0)
return bmiTo1DecimalPlace
}
func getAdvice() -> String {
return bmi?.advice ?? "No advice"
}
func getColor() -> String {
return bmi?.color ?? "white"
}
mutating func calculateBMI(_ weight: Float, _ height: Float) {
let bmiValue = weight / pow(height, 2)
if bmiValue < 18.5 {
bmi = BMI(value: bmiValue, advice: "Eat more pies!", color: "blue")
} else if bmiValue < 24.9 {
bmi = BMI(value: bmiValue, advice: "Fit as a fiddle!", color: "green")
} else {
bmi = BMI(value: bmiValue, advice: "Eat less pies!", color: "pink")
}
}
}
Завершаем реализацию методов ViewController.swift
.
// ViewController.swift
// (with methods implemented)
import UIKit
class ViewController: UIViewController {
var calculatorBrain = CalculatorBrain()
@IBOutlet weak var heightLabel: UILabel!
@IBOutlet weak var weightLabel: UILabel!
@IBOutlet weak var heightSlider: UISlider!
@IBOutlet weak var weightSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func heightSliderChanged(_ sender: UISlider) {
heightLabel.text = String(format: "%.2fm", sender.value)
}
@IBAction func weightSliderChanged(_ sender: UISlider) {
weightLabel.text = String(format: "%.0fKg", sender.value)
}
@IBAction func calculatePressed(_ sender: UIButton) {
let height = heightSlider.value
let weight = weightSlider.value
calculatorBrain.calculateBMI(weight, height)
let bmiValue = calculatorBrain.getBMIValue()
let bmiAdvice = calculatorBrain.getAdvice()
let bmiColor = calculatorBrain.getColor()
print(bmiValue)
print(bmiAdvice)
print(bmiColor)
}
}
Если запустить приложение сейчас, можно увидеть рассчитанное значение ИМТ, рекомендации и значение цвета в консоли Xcode.
Далее будем отправлять эти параметры на экран результатов BMI (созданный с использованием Flutter) через platform channel.
Создание модуля Flutter
Папку проекта iOS и папку модуля Flutter следует хранить в корневой папке для удобства доступа.
Структура каталогов проекта:
Запускаем эту команду из корневого каталога, чтобы создать модуль Flutter:
flutter create --template module <имя_модуля>
Или можем запустить аналогичную команду:
flutter create -t module <имя_модуля>
Заменяем текст в угловых скобках соответствующей информацией.
--org <organization_id>
— необязательный параметр, с помощью которого можно указать идентификатор организации для этого модуля. По умолчанию установлено значение com.example.
Открываем папку модуля Flutter с помощью любого редактора кода. Обнаруживаем, что он содержит демо-приложение Flutter Counter.
Запускаем модуль Flutter на физическом устройстве iOS или в симуляторе, чтобы проверить, правильно ли он работает.
Теперь перейдем к интеграции модуля Flutter в собственный проект iOS.
Интеграция модуля Flutter в нативную iOS
Самый простой вариант интеграции модуля Flutter в нативную iOS — использование CocoaPods .
Есть еще два варианта интеграции модуля Flutter в нативное приложение iOS, их можно найти здесь.
Если в системе не установлены CocoaPods, можно найти руководство по установке здесь.
Теперь нам нужно создать Podfile.
Если в проекте iOS уже создан Podfile, можно пропустить первый шаг.
Запускаем эту команду из каталога проекта iOS:
pod init
После создания Podfile вся структура проекта должна быть такой:
bmi_calculator/
├── bmi_flutter/
│ └── .ios/
│ └── Flutter/
│ └── podhelper.rb
└── BMI Calculator/
└── Podfile
Теперь открываем Podfile с помощью Xcode .
Добавляем следующий код в наш Podfile:
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
Заменяем my_flutter
на имя папки нашего модуля Flutter.
Для каждой цели Podfile, в которую необходимо встроить Flutter, необходимо добавить следующую строку:
install_all_flutter_pods (flutter_application_path).
Сохраняем и закрываем Podfile, а также Xcode.
Выполняем следующую команду для установки модулей:
pod install
Снова открываем проект, используя файл с
.xcworkspace
расширением.
Если открываем файл с .xcodeproject
расширением, то получаем множество ошибок, так как с ним невозможно использовать Podfile.
Дополнительная информация в официальной документации Flutter.
На этом первая часть статьи подошла к концу. Мы интегрировали модуль Flutter в нативное приложение iOS, в следующей части рассмотрим добавление экрана и platform channel для отправки данных из натива во Flutter.
Совсем скоро опубликую вторую! Следите за анонсом в нашем телеграм-канале Flutter. Много!