Определение App flavors для приложений Flutter

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

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Этот пост будет полезен для Flutter-разработчиков, которым хочется поработать с флейворами (flavours), изменить и дополнить их. Сегодня мы не будем говорить о процессе создания флейворов с разными иконками, названиями и идентификаторами, благо таких публикаций существует уже очень много. Вместо этого речь пойдет о том, как определять флейвор в Dart-коде, а также о решении некоторых часто встречающихся при сборке приложений проблем, связанных с введением флейворов. 

Почему можем об этом рассказать: наше мобильное приложение для модуля HCM-платформы TalentTech Обучение создано на Flutter. 

Итак, я рассчитываю, что вы знаете, что такое флейвор и зачем он нужен (если нет, почитайте, например, вот этот материал). Поэтому мы сразу перейдем к тем вопросам, с которыми сталкивается разработчик Flutter, когда у него возникает задача определить новый флейвор. 

Определение нового флейвора 

Выбрать стандартный флейвор достаточно просто. Для этого необходимо указать его имя в настройках фреймворка. Например, в Android Studio нужно перейти в Run → Edit Configurations → и указать имя флейвора в поле Build Flavor вот так:

Но если требуется что-то более оригинальное, необходимо подготовить ваше приложение для работы с другим флейфором. Для этого можно добавить несколько строк кода на Dart:

import 'dart:async';
import 'package:flutter/services.dart';

enum MyFlavor { staging, prod }

Future<MyFlavor> getCurrentFlavor() async {
  try {
    final flavorString = await const MethodChannel('flavor').invokeMethod<String>('getFlavor');
    return flavorString == "staging" ? MyFlavor.staging : MyFlavor.prod;
  } catch (e) {
    return MyFlavor.prod;
  }
}

Android

В окружении Android для определения флейвора нужно модифицировать файл android/app/src/main/kotlin/<app_package>/MainActivity.kt, а также определить обработчик для MethodChannel в методе configureFlutterEngine(). Сделать это можно следующим образом:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    companion object {
        const val CHANNEL = "flavor"
    }
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
        
        // Method channel
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
                .setMethodCallHandler { call, result ->
                    if (call.method == "getFlavor") {
                        result.success(BuildConfig.FLAVOR);
                    } else {
                        result.notImplemented()
                    }
                }
    }
}

iOS

Под iOS процесс будет более многоступенчатым и потребует выполнить ряд ручных действий:

1.Для начала, точно также как и для Android, нужно определить обработчик для MethodChannel в методе application:didFinishLaunchingWithOptions. Сделать это необходимо в  ios/Runner/AppDelegate.swift. Для этого достаточно выполнить следующий код:

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    
    // Method channel
    if let controller = self.window.rootViewController as? FlutterBinaryMessenger {
        let channel = FlutterMethodChannel(name: "flavor", binaryMessenger: controller)
        
        channel.setMethodCallHandler { (call, result) in
            let flavor = Bundle.main.infoDictionary?["Flavor"]
            result(flavor)
        }
    }
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

2.Открыть ios/Runner/Info.plist. Добавить ключ Flavor типа String со значением ${PRODUCT_FLAVOR}:

3.Открыть Targets → Runner → Build Settings, нажать на “+”, выбрать Add User-Defined Setting и добавить настройку с названием PRODUCT_FLAVOR. Для каждой конфигурации задать имя флейвора, которое будет передаваться во Flutter.

4.Если для какого-то флейвора изменялся application identifier, нужно создать provisioning profile для него:

  • Пойти на developer.apple.com → Certificates, Identifiers & Profiles → Identifiers → + → App IDs → …

  • Выбрать Bundle ID explicit и указать там новый application identifier

  • В capabilities выбрать те же самые параметры, что и у основного identifier

  • Выполнить fastlane match --app_identifier “<YOUR_NEW_IDENTIFIER>“

Проблемы при сборке

Нередко при сборке приложения с обновленный флейвором возникают ошибки. На нашем опыте они чаще всего встречаются под iOS. И сегодня разберем две самые популярные из них:

ERROR: iOS архив успешно собран, но выдается неизвестная ошибка

Подобная ошибка может быть вызвана невалидным названием флейвора. В нашем случае не принимались квадратные скобки в названии (а конкретно в строке “[S] TT обучение”). Поэтому, если у вас возникает подобная ошибка, попробуйте сменить название, убрав из него нестандартные символы.

ERROR: Ошибка сертификата на iOS

В реальности описание такой ошибки может выглядеть следующим образом:

Для подобной ситуации было найдено проверенное решение. Разобраться с невалидными провижнами и сертификатами можно в несколько шагов:

  1. Зайти в Runner → Target → Signing & Capabilities и проверить, что нигде нет красных восклицательных знаков

  2. Зайти в Runner → Target → Build Settings, выполнить поиск по слову provision и попытаться найти, есть ли какая-то ошибка в результатах

  3. Если запускаете на локальной машине:

    1. Скачать провижны с помощью fastlane match

    2. Зайти в Xcode → Preferences → Accounts → выбрать нужный аккаунт → Download Manual Profiles.

    3. Перейти к п1.

    4. Если есть ошибки, то убить процесс Xcode, запустить заново и проверить еще раз (это реально помогает).

  4. Если все это не сработало, поискать дополнительные подсказки можно в документации здесь или здесь, а также на https://stackoverflow.com

Заключение

Флейворы — полезная и удобная штука, но при попытке работать с ними могут возникать ошибки и сложности. Надеюсь, что этот небольшой пост поможет вам избежать проблем с определением флейвора, а также окажется полезен тем, у кого возникли те же ошибки при сборке приложения. Учитывая, что Flutter набирает популярность и становится все более востребованным, обмен опытом должен оказаться полезен для всех нас.

Источник: https://habr.com/ru/company/talenttech/blog/584788/


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

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

Всем привет! За последние пять лет мы достаточно часто сталкивались с запросами на мониторинг Java приложений. Собрав ос...
Всем привет. Меня зовут Дмитрий Андриянов. Два года писал на React Native, сейчас я разработчик в Surf и уже полтора года пишу на Flutter. Когда я только решил серьёзно взяться за Flu...
Привет всем! В этой статье я хотел бы показать вам, как создать Flutter приложение, используя Redux. Если вы не знаете, что такое Flutter, то это — SDK с открытым исходным кодом для создания ...
Устраивать конкурсы в инстаграме сейчас модно. И удобно. Инстаграм предоставляет достаточно обширный API, который позволяет делать практически всё, что может сделать обычный пользователь ручками.
Некоторое время назад мне довелось пройти больше десятка собеседований на позицию php-программиста (битрикс). К удивлению, требования в различных организациях отличаются совсем незначительно и...