ann_flutter_flavor 0.1.4 copy "ann_flutter_flavor: ^0.1.4" to clipboard
ann_flutter_flavor: ^0.1.4 copied to clipboard

CLI tool and runtime API for ANN Flutter flavor management. Reads annspec.yaml and generates typed Dart flavor code, wires the Gradle plugin for Android, and wires the CocoaPods plugin for iOS.

ann_flutter_flavor #

A CLI tool and runtime API for ANN Flutter flavor management.

Reads a single annspec.yaml source-of-truth and:

  • Generates typed Dart flavor code (lib/generated/ann_flavor.g.dart)
  • Generates Firebase configuration scripts
  • Wires the Gradle plugin into Android build files (settings.gradle.kts, app/build.gradle.kts)
  • Generates per-flavor Android manifests with AdMob meta-data when configured
  • Generates per-flavor iOS xcconfig files and patches Info.plist with variable references
  • Wires the CocoaPods plugin into the iOS Podfile

Installation #

Add to your Flutter app's pubspec.yaml:

dependencies:
  ann_flutter_flavor: ^0.1.0

IDE Plugin #

The ANN Flutter Flavor plugin for Android Studio and IntelliJ IDEA lets you author and validate annspec.yaml visually.

  • Guided form UI for flavors, Firebase config, RevenueCat subscriptions, Google Sign-In keys, and AdMob IDs
  • Spec validation highlights missing or invalid fields before you sync
  • One-click sync via Tools → ANN Tools → Sync Spec

Install: Android Studio → Settings → Plugins → Marketplace → search "ANN Flutter Flavor"

Plugin ID: dev.anntech.studio.flavorize


annspec.yaml format #

annai_app:

  android:
    sdk:
      minSdk: 23
      compileSdk: 35
      targetSdk: 35
    default:
      id: com.example.myapp
      name: "My App"
      version_name: 1.0.0
      version_code: 10000
      admob:                                      # optional — enables AdMob for all flavors
        gms_ads_id: "ca-app-pub-XXXX~XXXXXXXXXX"
      build_types:
        release:
          firebase:
            project_id: "my-firebase-prod"
            path: "firebase/android/prod"
          auth:
            clientId: "000000000000-release.apps.googleusercontent.com"
            reversedClientId: "com.googleusercontent.apps.000000000000-release"
        debug:
          firebase:
            project_id: "my-firebase-dev"
            path: "firebase/android/dev"
      custom:                                       # default-level custom attributes
        revenuecat:
          api_key: "rc_default_key"
          entitlement_ids:
            - standard
        analytics:
          enabled: true
    flavor:
      free:
        id_suffix: .free
        name: "My App Free"
        main_file: "lib/flavors/main_free.dart"
        admob:                                    # flavor-level override
          gms_ads_id: "ca-app-pub-YYYY~YYYYYYYYYY"
        in_app_subscription:
          - apiKey: "goog_XXXX"
            entitlementIds: ["standard"]
        custom:
          revenuecat:
            api_key: "rc_free_key"               # overrides default; entitlement_ids falls through
        build_types:
          debug:
            custom:
              revenuecat:
                api_key: "rc_free_debug_key"     # overrides free.release for debug builds
      pro:
        id_suffix: .pro
        name: "My App Pro"
        main_file: "lib/flavors/main_pro.dart"
        custom:
          revenuecat:
            api_key: "rc_pro_key"
            entitlement_ids:
              - standard
              - premium

  ios:
    default:
      id: com.example.myapp
      name: "My App"
      version_name: 1.0.0
      version_code: 10000
      team_id: "YOURTEAMID"
      admob:                                      # optional — shared AdMob ID for iOS
        gms_ads_id: "ca-app-pub-XXXX~XXXXXXXXXX"
    flavor:
      free:
        id_suffix: .free
        name: "My App Free"
        main_file: "lib/flavors/main_free.dart"
      pro:
        id_suffix: .pro
        name: "My App Pro"
        main_file: "lib/flavors/main_pro.dart"

admob field cascade #

admob.gms_ads_id resolves in priority order: build_type → flavor → default.

  • Set it once under default: to share one AdMob App ID across all flavors
  • Override under a specific flavor: to use a different ID for that flavor
  • Override under flavor.build_types.<bt>: for build-type-level control
  • Presence of admob: enables AdMob — no separate admob_enabled flag needed

AdMob is only applicable to Android and iOS. Web and Windows have no AdMob support.


CLI Commands #

sync #

dart run ann_flutter_flavor sync
dart run ann_flutter_flavor sync -p ../my_flutter_app

What it generates / patches:

File Description
lib/generated/ann_flavor.g.dart Typed AnnFlavorConfig subclass per flavor
lib/generated/scripts/firebase.sh flutterfire configure commands per flavor/platform/build-type
fastlane/Fastfile + fastlane_*.rb CI/CD lanes per platform
android/settings.gradle.kts Patches mavenCentral() + ANN plugin declaration
android/app/build.gradle.kts Patches id("dev.anntech.flavorize")
android/app/src/<flavor>/AndroidManifest.xml Per-flavor manifest; GMS Ads meta-data if admob: set
ios/Flutter/<Flavor>Debug.xcconfig Per-flavor debug xcconfig
ios/Flutter/<Flavor>Release.xcconfig Per-flavor release xcconfig
ios/Runner/Info.plist Patches keys to use $(VARIABLE) references
ios/Podfile Patches in CocoaPods plugin reference

validate #

dart run ann_flutter_flavor validate
dart run ann_flutter_flavor validate -p ../my_flutter_app

Checks annspec.yaml for errors and warnings without writing any files. Useful in CI.


Runtime API #

Initialise in each flavor entry point #

// lib/flavors/main_free.dart
import 'package:ann_flutter_flavor/ann_flutter_flavor.dart';
import 'package:my_app/generated/ann_flavor.g.dart';
import 'dart:io';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  AnnFlavor.init(
    config:    FreeFlavor(),
    platform:  Platform.isAndroid ? AnnPlatform.android
             : Platform.isIOS    ? AnnPlatform.ios
             : AnnPlatform.web,
    buildType: const String.fromEnvironment('BUILD_TYPE', defaultValue: 'release'),
  );

  runApp(const MyApp());
}

Pass --dart-define=BUILD_TYPE=debug / --dart-define=BUILD_TYPE=release in your Flutter commands so custom() resolves the correct build-type override at runtime.

Access flavor data anywhere #

AnnFlavor.key                                       // "free"
AnnFlavor.current.name                              // "My App Free"
AnnFlavor.current.androidId                         // "com.example.myapp.free"
AnnFlavor.current.iosId                             // "com.example.myapp.free"
AnnFlavor.platform                                  // AnnPlatform.android
AnnFlavor.buildType                                 // "release" or "debug"

// RevenueCat subscriptions
final subs = AnnFlavor.current.subscriptions(AnnFlavor.platform);
subs?.first.apiKey                                  // "goog_XXXX"
subs?.first.entitlementIds                          // ["standard"]

// Google Sign-In
final auth = AnnFlavor.current.auth(AnnFlavor.platform);
auth?.clientId                                      // release client ID
final authDebug = AnnFlavor.current.authDebug(AnnFlavor.platform);
authDebug?.clientId                                 // debug client ID

// Custom attributes — resolves cascade + build type automatically
AnnFlavor.current.custom('revenuecat')?.string('api_key')
AnnFlavor.current.custom('revenuecat')?.strings('entitlement_ids')
AnnFlavor.current.custom('analytics')?.boolean('enabled')

AdMob: The AdMob App ID is injected natively into AndroidManifest.xml and Info.plist by the sync command. The AdMob SDK reads it automatically — just call MobileAds.instance.initialize(). No Dart API needed.

Custom attributes reference #

Accessor YAML type Returns
string(key) quoted string String?
boolean(key) true / false bool?
integer(key) integer number int?
decimal(key) decimal number double?
strings(key) YAML list List<String>?
[key] any dynamic

All accessors return null if the group doesn't exist or the key is missing. See docs/custom-attributes.md for the full cascade rules.

API reference #

Symbol Description
AnnFlavor.init(config:, platform:) Initialise once at app startup
AnnFlavor.current Active AnnFlavorConfig — throws if not initialised
AnnFlavor.platform Active AnnPlatform — throws if not initialised
AnnFlavor.key Shorthand for AnnFlavor.current.key
AnnFlavorConfig.key Flavor key string (e.g. "free")
AnnFlavorConfig.name Display name
AnnFlavorConfig.androidId Full Android bundle ID
AnnFlavorConfig.iosId Full iOS bundle ID
AnnFlavorConfig.subscriptions(platform) List of AnnSubscription or null
AnnFlavorConfig.auth(platform) Release AnnAuthConfig or null
AnnFlavorConfig.authDebug(platform) Debug AnnAuthConfig or null
AnnPlatform android, ios, web, windows
AnnSubscription apiKey + entitlementIds
AnnAuthConfig clientId + reversedClientId

Build commands #

flutter run   --flavor free -t lib/flavors/main_free.dart
flutter run   --flavor pro  -t lib/flavors/main_pro.dart
flutter build apk       --flavor free -t lib/flavors/main_free.dart
flutter build appbundle --flavor pro  -t lib/flavors/main_pro.dart
flutter build ipa       --flavor free -t lib/flavors/main_free.dart

License #

MIT

1
likes
0
points
1.64k
downloads

Publisher

unverified uploader

Weekly Downloads

CLI tool and runtime API for ANN Flutter flavor management. Reads annspec.yaml and generates typed Dart flavor code, wires the Gradle plugin for Android, and wires the CocoaPods plugin for iOS.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

args, collection, meta, path, yaml

More

Packages that depend on ann_flutter_flavor