### Navigating to Unpacked Package Example Directory Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0180-dart-pub-unpack/index.md After unpacking a package, this shell command changes the current directory to the package's example folder. This allows developers to easily access and run the provided example applications or explore their source code. ```Shell cd ./flex_color_scheme-7.3.1/example ``` -------------------------------- ### Interactive Flutter CLI Screenshot Example Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0163-flutter-screenshot/index.md This example demonstrates the interactive flow of the `flutter screenshot` command, showing how a user selects a device from a list of available emulators and the confirmation message upon successful screenshot capture. It illustrates the command's output and device selection process. ```Shell flutter screenshot [1]: sdk gphone64 arm64 (emulator-5554) [2]: iPhone SE (3rd generation) (70BC6613-2548-4442-8C47-735C556161A1) [3]: iPhone 15 (A56BA8E5-19EC-4007-8261-214D30B230D4) [4]: macOS (macos) [5]: Mac Designed for iPad (mac-designed-for-ipad) [6]: Chrome (chrome) Please choose one (or "q" to quit): 3 Screenshot written to flutter_01.png (426kB). ``` -------------------------------- ### Switching Xcode Versions with xcode-select CLI Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0190-multiple-xcode-versions/index.md This snippet demonstrates how to check the currently selected Xcode path and switch to a different installed version using the `xcode-select` command-line tool. It shows querying the current path, then using `sudo xcode-select -s` to set a new path, and finally verifying the change. This is useful for managing multiple Xcode installations. ```Shell ➜ ~ xcode-select -p /Applications/Xcode.app/Contents/Developer ➜ ~ sudo xcode-select -s /Applications/Xcode-16.0.app/Contents/Developer ➜ ~ xcode-select -p /Applications/Xcode-16.0.app/Contents/Developer ``` -------------------------------- ### Alias for Get Pub and Build Runner (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-useful-aliases-flutter-dev/index.md Defines a shell alias `fpgbrb` that combines `fpg` (flutter pub get) and `brb` (build runner build) using the `&&` operator. This executes `pub get` first, and if successful, then runs the build runner, streamlining common setup tasks. ```Shell alias fpgbrb="fpg && brb" ``` -------------------------------- ### Configuring l10n.yaml for Flutter Localization (YAML) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md This configuration file specifies the input directory for Application Resource Bundle (ARB) files (`arb-dir`), the output directory for generated localization classes (`output-dir`), and the template ARB file (`template-arb-file`). These settings guide Flutter's code generation process for localization. ```YAML arb-dir: lib/l10n output-dir: lib/generated template-arb-file: app_en.arb ``` -------------------------------- ### Unpacking a Dart Package with `pub unpack` Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0180-dart-pub-unpack/index.md This command downloads a specified Dart/Flutter package, such as `flex_color_scheme`, to a local directory. It's useful for inspecting the package's source code, examples, and internal structure without needing to add it as a dependency to a project. ```Shell dart pub unpack flex_color_scheme ``` -------------------------------- ### Alias for Pod Install (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-useful-aliases-flutter-dev/index.md Defines a shell alias `pinst` for `pod install`, a CocoaPods command used in Flutter iOS development to install project dependencies. This simplifies the command for frequent use. ```Shell alias pinst="pod install" ``` -------------------------------- ### Initializing Mixpanel with Environment Variable Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0175-dart-define-from-file-env-json/index.md This example demonstrates how to initialize the Mixpanel analytics SDK in Dart, using the `mixpanelProjectToken` retrieved from the `Env` class. This approach ensures that sensitive API keys are managed externally and accessed securely. ```Dart final mixpanel = await Mixpanel.init( Env.mixpanelProjectToken, trackAutomaticEvents: true, ) ``` -------------------------------- ### Initializing SembastCartRepository Asynchronously (Dart) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0056-async-init-provider-overrides/index.md Defines a `SembastCartRepository` class with a static asynchronous factory method `withDefaultDB`. This method encapsulates the asynchronous initialization logic for the underlying database, ensuring the repository instance is created only after all setup is complete. It returns a `Future` of the repository. ```Dart import 'package:flutter/widgets.dart'; // Placeholder for a Database class class Database {} class SembastCartRepository { final Database _db; SembastCartRepository(this._db); static Future withDefaultDB() async { // Simulate async database initialization await Future.delayed(const Duration(seconds: 1)); // Example async operation final db = await _initDatabase(); // Actual database initialization return SembastCartRepository(db); } static Future _initDatabase() async { // In a real app, this would open a Sembast database // e.g., return await databaseFactoryIo.openDatabase('cart.db'); print('Database initialized asynchronously.'); return Database(); // Return a dummy Database instance } // Example method to show synchronous usage List getCartItems() { // Access _db synchronously return ['Item A', 'Item B']; } } ``` -------------------------------- ### Alias for Get Pub and Watch Build Runner (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-useful-aliases-flutter-dev/index.md Defines a shell alias `fpgbrw` that combines `fpg` (flutter pub get) and `brw` (build runner watch) using the `&&` operator. This executes `pub get` first, and if successful, then starts the build runner in watch mode, ideal for development. ```Shell alias fpgbrw="fpg && brw" ``` -------------------------------- ### Defining CocoaPods Aliases in Zsh Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-6-steps-64x-programmer/index.md This snippet defines shell aliases for common CocoaPods commands, designed to be added to a `.zshrc` file. These aliases simplify `pod install` and `pod repo update` operations, which are frequently used in Flutter iOS development, enhancing workflow efficiency. ```Shell alias pinst="pod install" alias pru="pod repo update" ``` -------------------------------- ### Writing Human-Readable Widget Tests with Robot - Flutter/Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0019-how-to-use-robot-testing-to-write-more-readable-widget-tests/index.md This example demonstrates how to use the `Robot` class within a `testWidgets` block to create highly readable and maintainable Flutter widget tests. By instantiating the `Robot` and calling its methods, test scenarios become clear, resembling human-readable instructions rather than low-level finder and tester calls. ```Dart testWidgets('CounterPage', (tester) async { final robot = Robot(tester); await robot.pumpMyApp(); robot.expectCounterValue(0); // Initial value await robot.tapCounterButton(); robot.expectCounterValue(1); // After first tap await robot.tapCounterButton(); robot.expectCounterValue(2); // After second tap }); ``` -------------------------------- ### Example Remote Configuration JSON for GitHub Gist Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0195-remote-config-github-gist/index.md This JSON snippet demonstrates a typical structure for remote configuration data stored in a GitHub Gist. It includes a 'config' object for app-wide settings like a 'required_version' and a 'feature-flags' array for managing feature rollout percentages, useful for A/B testing or phased feature releases. This data is intended to be fetched by a mobile application (e.g., Flutter) at startup to dynamically control its behavior. ```JSON { "config" : { "required_version": "2.0.0" }, "feature-flags": [ { "id": "new-paywall", "percentage": 10 }, { "id": "feature-discovery", "percentage": 25 } ] } ``` -------------------------------- ### Alias for Getting Flutter Pub Dependencies (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-useful-aliases-flutter-dev/index.md Defines a shell alias `fpg` to execute `flutter pub get`, fetching all necessary dependencies for a Flutter project. This is a common command used after modifying `pubspec.yaml`. ```Shell alias fpg="flutter pub get" ``` -------------------------------- ### Installing Hugeicons Package (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0173-hugeicons-flutter-stroke-icons/index.md This command adds the Hugeicons package to your Flutter project's dependencies, allowing you to use its extensive icon set. It automatically updates the `pubspec.yaml` file with the new dependency. ```Shell dart pub add hugeicons ``` -------------------------------- ### Initializing WidgetsBindingObserver in Flutter State Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0034-how-to-use-widgetsbindingobserver/index.md This snippet demonstrates the foundational setup for using `WidgetsBindingObserver` in a Flutter application. It shows how to add the `WidgetsBindingObserver` mixin to a `State` subclass and correctly register and unregister the observer within the `initState` and `dispose` methods, ensuring proper lifecycle management. ```Dart import 'package:flutter/material.dart'; class MyObserverWidget extends StatefulWidget { const MyObserverWidget({Key? key}) : super(key: key); @override State createState() => _MyObserverWidgetState(); } class _MyObserverWidgetState extends State with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); print('Observer added'); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); print('Observer removed'); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('WidgetsBindingObserver Example')), body: const Center( child: Text('Observe app lifecycle changes'), ), ); } } ``` -------------------------------- ### Logging Simple Events with log and name in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0177-log-function-args/index.md This example shows how to use the `log` function to track application events. The `name` argument is utilized to categorize the log entry, making it easier to filter and understand log output. ```Dart log('trackAppCreated', name: 'Event'); ``` -------------------------------- ### Defining BuildContext Extension for Simplified Navigation in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0187-build-context-extension-push-pop/index.md This Dart extension, `NavigatorContext`, simplifies common Navigator 1.0 operations by adding `pop` and `pushNamed` methods directly to `BuildContext`. This eliminates the need for repetitive `Navigator.of(context)` calls, making navigation code more concise. For example, instead of `Navigator.of(context).pushNamed('about');`, one can simply use `context.pushNamed('about');`. ```Dart extension NavigatorContext on BuildContext { void pop([T? result]) { return Navigator.of(this).pop(); } Future pushNamed(String routeName, {Object? arguments,}) { return Navigator.of(this).pushNamed(routeName, arguments: arguments); } } ``` -------------------------------- ### Validating Environment Variables at App Startup Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0175-dart-define-from-file-env-json/index.md This Dart code provides a crucial safety mechanism by checking if essential environment variables are defined when the application starts. If a required key is missing or empty, it throws an exception, preventing runtime errors and aiding in early configuration issue detection. ```Dart if (Env.mixpanelProjectToken.isEmpty) { throw Exception('MIXPANEL_PROJECT_TOKEN not defined'); } if (Env.sentryDsn.isEmpty) { throw Exception('SENTRY_DSN not defined'); } ``` -------------------------------- ### Configuring VSCode Launch for Specific Flutter Route Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0232-flutter-run-route/index.md This JSON configuration snippet for VSCode's `launch.json` allows you to set a specific route for your Flutter application to start from when launched via the debugger. The `--route` argument is passed to the `flutter run` command, enabling consistent debugging of particular screens or flows. ```JSON { "version": "0.2.0", "configurations": [ { "name": "Run", "request": "launch", "type": "dart", "args": [ "--route", "/jobs/add" ] } ] } ``` -------------------------------- ### Using url_launcher Link Widget for URLs in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0243-show-flutter-web-url-text-span/index.md This example shows how to use the Link widget from the url_launcher package to create a clickable URL. It wraps a Text.rich widget, passing the uri and using the followLink callback with a TapGestureRecognizer to handle navigation. The text is styled to resemble a web link, and the cursor is set to click. ```Dart import 'package:url_launcher/link.dart'; Link( uri: uri, builder: (BuildContext context, FollowLink? followLink) => Text.rich( TextSpan( text: uri.toString(), // Follow the URL link on tap recognizer: TapGestureRecognizer()..onTap = followLink, // Customize the cursor style mouseCursor: SystemMouseCursors.click, // Make it look like a web link style: TextStyle( color: Theme.of(context).colorScheme.primary, decoration: TextDecoration.underline, decorationColor: Theme.of(context).colorScheme.primary, ), ), overflow: overflow, maxLines: maxLines, ), ) ``` -------------------------------- ### Defining Error-Throwing Future in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0178-await-vs-unawaited-vs-ignore/index.md This snippet defines a Future named someFuture that immediately completes with an UnimplementedError. It serves as a common example for demonstrating different ways to handle futures that might throw exceptions. ```Dart Future someFuture() => Future.error(UnimplementedError()); ``` -------------------------------- ### Maestro UI Test Flow Example (YAML) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0237-semantics-identifiers/index.md This YAML snippet illustrates a basic Maestro UI test flow. It configures the appId and name for the test, then defines steps to launchApp and tapOn a specific UI element. The tapOn action uses the id property, referencing the semantic identifier previously assigned to a Flutter widget, ensuring reliable interaction regardless of the widget's displayed text. ```YAML appId: com.example.yourApp name: "Test User Flows" --- - launchApp - tapOn: id: "save-button" label: "Tap on Save button" ``` -------------------------------- ### Conditionally Rendering UI with Dart Toggles Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0241-release-toggles-dart-define/index.md This Flutter widget example demonstrates how to use a defined static toggle (`Toggles.showProductsAsGrid`) to conditionally render different UI components. Based on the toggle's value, it switches between a `GridView.builder` and a `ListView.builder`, allowing for A/B testing or gradual feature rollout. ```Dart Widget build(BuildContext context) { if (Toggles.showProductsAsGrid) { return GridView.builder(...); } else { return ListView.builder(...); } } ``` -------------------------------- ### Implementing Keyboard Shortcuts with CallbackShortcuts in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0227-hotkeys-callback-shortcuts/index.md This snippet demonstrates how to integrate keyboard shortcuts using Flutter's `CallbackShortcuts` widget. It maps left and right arrow keys to `onPrevious` and `onNext` callbacks, respectively, and ensures the shortcuts are active by wrapping the UI in a `Focus` widget with `autofocus: true`. This setup allows users to navigate or trigger actions via keyboard input. ```Dart CallbackShortcuts( bindings: { const SingleActivator(LogicalKeyboardKey.arrowLeft): () { onPrevious(); }, const SingleActivator(LogicalKeyboardKey.arrowRight): () { onNext(); } }, child: Focus( focusNode: hotkeysFocusNode, autofocus: true, child: Row( children: [ IconButton( tooltip: 'Hotkey: ⬅️', icon: const Icon(Icons.arrow_back), onPressed: onPrevious ), IconButton( tooltip: 'Hotkey: ➡️', icon: const Icon(Icons.arrow_forward), onPressed: onNext ) ] ) ) ); ``` -------------------------------- ### Initializing In-App Purchase Stream Asynchronously in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0192-async-stream-initialization/index.md This Dart snippet demonstrates how to create a stream that first performs an asynchronous initialization (checking `inAppPurchase.isAvailable()`) and then yields events from an existing stream (`inAppPurchase.purchaseStream`). It uses `async*` to define an asynchronous generator function and `yield*` to forward events from another stream, useful when a stream's source requires prior async setup. It depends on the `in_app_purchase` package. ```Dart import 'package:in_app_purchase/in_app_purchase.dart'; Stream> purchaseStream() async* { final inAppPurchase = InAppPurchase.instance; // first, initialize asynchronously await inAppPurchase.isAvailable(); // then, start vending events yield* inAppPurchase.purchaseStream; } ``` -------------------------------- ### Initializing and Preloading SVGs in Flutter Main Function Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0150-preload-svgs/index.md Illustrates how to integrate the `preloadSVGs` function into the `main` entry point of a Flutter application. It ensures that the Flutter binding is initialized before asynchronously preloading a specific list of SVG assets, making them available globally for immediate rendering throughout the app. This setup is crucial for optimizing initial load times of SVG graphics. ```Dart void main() async { WidgetsFlutterBinding.ensureInitialized(); await preloadSVGs([ 'assets/icon_comment.svg', 'assets/icon_info.svg', 'assets/icon_link.svg', ]); runApp(const MainApp()); } ``` -------------------------------- ### Example Usage of Adaptive Alert Dialog (Dart) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0248-adaptive-alert-dialog/index.md This snippet demonstrates how to use the `showAlertDialog` function to prompt the user for confirmation. It sets the title to "Are you sure?" and content to "This action cannot be undone.", defining "Yes" as the default action and "No" as the cancel action. The result is awaited to perform subsequent actions based on the user's choice. ```Dart final success = await showAlertDialog( context: context, title: "Are you sure?", content: "This action cannot be undone.", defaultActionText: "Yes", cancelActionText: "No", ); if (success == true) { ... } ``` -------------------------------- ### Better Solution: Multiple Entry Points for Firebase Initialization in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0201-firebase-init-multiple-flavors/index.md This section presents an improved method for Firebase initialization across multiple Flutter flavors by using separate entry points for each flavor. This approach loads only the necessary configuration file, enhancing security and reducing app size compared to the `appFlavor` constant method. ```Dart // main_dev.dart import 'package:flutter_ship_app/firebase_options_dev.dart'; import 'main.dart'; void main() async { firebaseMain(DefaultFirebaseOptions.currentPlatform); } ``` ```Dart // main.dart import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; void firebaseMain(FirebaseOptions firebaseOptions) async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: firebaseOptions); runApp(const MainApp()); } ``` ```Shell // Run like this: flutter run --flavor dev -t lib/main_dev.dart flutter run --flavor stg -t lib/main_stg.dart flutter run --flavor prod -t lib/main_prod.dart ``` -------------------------------- ### Defining Flutter and Dart Build Runner Aliases in Zsh Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-6-steps-64x-programmer/index.md This snippet defines a set of shell aliases for common Flutter and Dart `build_runner` commands, intended to be added to a `.zshrc` file. These aliases streamline repetitive tasks like cleaning Flutter projects, getting/upgrading Dart packages, and running `build_runner` in build or watch mode, improving developer efficiency. ```Shell alias fclean="flutter clean" alias fpg="flutter pub get" alias fpu="flutter pub upgrade" alias brb="dart run build_runner build -d" alias brw="dart run build_runner watch -d" alias fpgbrb="fpg && brb" alias fpgbrw="fpg && brw" ``` -------------------------------- ### Creating Template ARB File for English Localization (JSON) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md This ARB (Application Resource Bundle) file serves as the template for English localization. It defines the `@@locale` key to specify the language and includes a sample key-value pair (`helloWorld`) with a description, which will be used for code generation. ```JSON { "@@locale": "en", "helloWorld": "Hello World", "@helloWorld": { "description": "The conventional first program" } } ``` -------------------------------- ### Adding Badges to Flutter IconButtons Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0185-add-badge-icon-button/index.md This snippet demonstrates how to attach badges to IconButton widgets in Flutter using the Badge widget. It shows two examples: one using Badge.count to display a numeric notification count (e.g., '999+') and another using a regular Badge to display a custom text label with specific background and text colors. Both examples illustrate how to wrap an Icon with a Badge and place it within an IconButton's icon property. ```Dart IconButton( icon: Badge.count( count: 9999, child: const Icon(Icons.notifications), ), onPressed: () {}, ), IconButton( icon: const Badge( label: Text('Offline'), backgroundColor: Colors.orangeAccent, textColor: Colors.black87, child: Icon(Icons.wifi), ), onPressed: () {}, ), ``` -------------------------------- ### Flutter Web App Bootstrap HTML Structure (HTML) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0162-flutter-web-app-initialization-logic/index.md This HTML snippet illustrates the basic structure of an `index.html` file for a Flutter web app using the new bootstrap process (Flutter 3.22). It includes the `` tag and a ` ``` -------------------------------- ### Creating Empty Flutter Project via Command Line Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0105-flutter-create-empty/index.md This command creates a new Flutter project named `test_app` with minimal boilerplate code. The `-e` flag ensures that only essential `pubspec.yaml` and `main.dart` files are generated, omitting the default counter application code. ```Shell flutter create -e test_app ``` -------------------------------- ### Example Usage of Conditional CanvasKit Check (Dart) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0166-conditional-imports/index.md This snippet demonstrates how to conditionally execute code based on whether the application is running on the web (kIsWeb) and if the CanvasKit renderer is enabled, using the platform-agnostic isCanvasKitRenderer function. ```Dart if (kIsWeb && isCanvasKitRenderer()) { print('CanvasKit enabled'); } ``` -------------------------------- ### Upgrading Flutter Web Project to New Bootstrap (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0162-flutter-web-app-initialization-logic/index.md These shell commands are used to upgrade an existing Flutter web project to utilize the new, faster web bootstrap process introduced in Flutter 3.22. It involves deleting the old 'web' folder and recreating it with the Flutter CLI, ensuring the project uses the updated bootstrap code. ```Shell rm -rf web/ flutter create . --platforms web ``` -------------------------------- ### Initializing Robot Class and Pumping Root Widget - Flutter/Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0019-how-to-use-robot-testing-to-write-more-readable-widget-tests/index.md This snippet defines the `Robot` class constructor, which takes a `WidgetTester` instance. It also includes a `pumpMyApp` convenience method to pump the root widget and set up any necessary mocks or Riverpod overrides, ensuring the test environment is correctly initialized. ```Dart class Robot { Robot(this.tester); final WidgetTester tester; Future pumpMyApp() async { // Example: Set up Riverpod overrides or other mocks await tester.pumpWidget( ProviderScope( overrides: [ // Add any necessary overrides here ], child: const MyApp(), // Your root widget ), ); } } ``` -------------------------------- ### Alias for Pod Repo Update (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0159-useful-aliases-flutter-dev/index.md Defines a shell alias `pru` for `pod repo update`, a CocoaPods command to update the local CocoaPods spec repository. This ensures that `pod install` uses the latest available pod versions. ```Shell alias pru="pod repo update" ``` -------------------------------- ### Configuring VSCode Launch for Flutter Flavors (JSON) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0030-vscode-launch-configurations/index.md This VSCode launch configuration defines two profiles, 'dev' and 'prod', for a Flutter application. It utilizes the `--dart-define` argument to inject compile-time environment variables such as 'FLAVOR' and 'API_KEY', facilitating seamless switching between different build environments. ```JSON { "version": "0.2.0", "configurations": [ { "name": "dev", "request": "launch", "type": "dart", "args": [ "--dart-define=FLAVOR=dev", "--dart-define=API_KEY=dev_api_key" ] }, { "name": "prod", "request": "launch", "type": "dart", "args": [ "--dart-define=FLAVOR=prod", "--dart-define=API_KEY=prod_api_key" ] } ] } ``` -------------------------------- ### Configuring TextFormField for Numeric Input in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0244-text-form-field-numeric/index.md This snippet demonstrates how to configure a TextFormField in Flutter to accept only numeric input. It sets keyboardType to TextInputType.number to display a numeric keypad and uses FilteringTextInputFormatter.digitsOnly to ensure only digits are entered, improving user experience for numeric fields. ```Dart TextFormField( controller: likesController, decoration: InputDecoration( labelText: 'BlueSky Likes', border: const OutlineInputBorder(), ), textInputAction: TextInputAction.next, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, ], ) ``` -------------------------------- ### Adding Localization Packages to pubspec.yaml (Flutter) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md This snippet adds the necessary `flutter_localizations` and `intl` packages to the `pubspec.yaml` file, enabling Flutter's localization features and internationalization utilities. The `sdk: flutter` dependency is crucial for integrating with the Flutter framework. ```YAML dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter intl: ^0.17.0 ``` -------------------------------- ### Checking Platform with `UniversalPlatform.isIOS` - Dart/Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0164-universal-platform-package/index.md This snippet illustrates the use of `UniversalPlatform.isIOS` from the `universal_platform` package for platform detection. This approach provides a unified and robust way to check the platform across all Flutter targets, including web, offering a cleaner syntax compared to manual `kIsWeb` checks. ```Dart // Cleaner and more robust if (UniversalPlatform.isIOS) { // iOS logic here } ``` -------------------------------- ### Combining Spacing and Flex in Flutter Columns Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0216-spacing-row-column/index.md This example demonstrates how the `spacing` argument can be effectively combined with `flex` properties on `Expanded` widgets within a Flutter `Column`. This powerful combination allows for both fixed spacing between elements and proportional sizing of the children themselves, offering greater layout control. ```Dart Column( crossAxisAlignment: CrossAxisAlignment.stretch, spacing: 16.0, children: [ Expanded(flex: 3, child: ColoredBox(color: Colors.green)), Expanded(flex: 2, child: ColoredBox(color: Colors.orange)), Expanded(flex: 1, child: ColoredBox(color: Colors.red)), ], ) ``` -------------------------------- ### Executing Fastlane Lane for Screenshot Upload Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0238-uploading-screenshots-fastlane/index.md This command-line snippet shows how to execute the `upload_screenshots_and_metadata` lane defined in the Fastfile. Running this command initiates the automated process of uploading screenshots and metadata to App Store Connect, as configured in the Fastfile. ```Shell fastlane upload_screenshots_and_metadata ``` -------------------------------- ### Managing Firebase Auth and GoRouter with Riverpod Providers in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0103-simple-auth-firebase-ui/index.md This snippet refactors the Firebase authentication and GoRouter setup using Riverpod providers. It defines providers for `FirebaseAuth.instance`, `authStateChanges`, and `GoRouter`, allowing for better dependency management, testability, and reactive updates across the application by centralizing state. ```Dart final firebaseAuthProvider = Provider((ref) => FirebaseAuth.instance);\n\nfinal authStateChangesProvider = StreamProvider.autoDispose((ref) {\n return ref.watch(firebaseAuthProvider).authStateChanges();\n});\n\nfinal goRouterProvider = Provider.autoDispose((ref) {\n final authState = ref.watch(authStateChangesProvider);\n return GoRouter(\n routes: [\n GoRoute(\n path: '/',\n name: AppRoute.signIn.name,\n builder: (context, state) => const CustomSignInScreen(),\n ),\n GoRoute(\n path: '/profile',\n name: AppRoute.profile.name,\n builder: (context, state) => const CustomProfileScreen(),\n ),\n ],\n redirect: (context, state) {\n final isLoggedIn = authState.value != null;\n if (isLoggedIn) {\n if (state.location == AppRoute.signIn.name) {\n return AppRoute.profile.name;\n }\n }\n return null;\n },\n refreshListenable: StreamNotifier(authState.stream),\n );\n}); ``` -------------------------------- ### Building and Uploading iOS IPA to App Store Connect (Shell) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0209-build-upload-ios-script/index.md This shell script automates the process of building an iOS IPA file with Flutter and uploading it to App Store Connect using `xcrun altool`. It includes validation for `APP_STORE_CONNECT_KEY_ID` and `APP_STORE_CONNECT_ISSUER_ID` environment variables, performs a clean build, fetches dependencies, and then builds and uploads the IPA. Authentication is handled via App Store Connect API keys. ```Shell set -e # Validate that the API Key ID and Issuer ID are set if [[ -z ${APP_STORE_CONNECT_KEY_ID} ]]; then echo "Please set APP_STORE_CONNECT_KEY_ID as an environment variable." exit 1 fi if [[ -z ${APP_STORE_CONNECT_ISSUER_ID} ]]; then echo "Please set APP_STORE_CONNECT_ISSUER_ID as an environment variable." exit 1 fi # Start from a clean slate # This ensures that there's only one *.ipa inside build/ios/ipa when uploading with xcrun flutter clean flutter pub get # Build the IPA file using Flutter echo "Building the IPA..." flutter build ipa # TODO: add your app-specific build arguments here # Upload the IPA file to App Store Connect using xcrun echo "Uploading the IPA to App Store Connect..." xcrun altool --upload-app --type ios --file build/ios/ipa/*.ipa \ --apiKey ${APP_STORE_CONNECT_KEY_ID} --apiIssuer ${APP_STORE_CONNECT_ISSUER_ID} ``` -------------------------------- ### Applying Null-Aware Elements for Conditional List Population in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0252-null-aware-elements-dart-3.8/index.md This example demonstrates how Dart 3.8's null-aware elements simplify conditional list population. It shows adding a nullable 'lunch' string and its nullable 'length' property to a list, comparing the new '?element' syntax with the traditional 'if' statements. ```Dart String? lunch = isTuesday ? 'tacos!' : null; // before var withoutNullAwareElements = [ if (lunch != null) lunch, if (lunch?.length != null) lunch!.length, if (lunch?.length case var length?) length, ]; // after var withNullAwareElements = [ ?lunch, ?lunch.length, ?lunch.length, ]; ``` -------------------------------- ### Upgrading cupertino_icons Package Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0139-github-copilot-tips-flutter-devs/index.md This snippet shows a targeted 'flutter pub add' command to upgrade a specific package, 'cupertino_icons', to a recommended version. This is useful for resolving direct version conflicts with a single dependency, as suggested by tools like GitHub Copilot. ```Dart flutter pub add cupertino_icons:^1.0.6 ``` -------------------------------- ### Configuring GitHub Action Workflow for Flutter Tests (YAML) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0026-running-tests-with-github-actions/index.md This YAML configuration defines a GitHub Actions workflow named 'Run Tests'. It triggers on `push` events and `workflow_dispatch`. The `drive` job runs on `ubuntu-latest`, checks out the repository, and then uses `subosito/flutter-action` to execute `flutter test`, ensuring all tests pass before merging. ```YAML name: Run Tests on: [push, workflow_dispatch] jobs: drive: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: subosito/flutter-action@v2.8.0 run: flutter test ``` -------------------------------- ### Generating Fake Data with Faker in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0010-how-to-generate-fake-data-with-the-faker-package/index.md This snippet demonstrates how to initialize the Faker package and generate various types of fake data including email addresses, IPv6 addresses, usernames, person names, prefixes, suffixes, and lorem ipsum sentences. It showcases the basic usage of different Faker properties for quick data generation. ```Dart import 'package:faker/faker.dart'; void main() { final faker = Faker(); faker.internet.email(); // francisco_lebsack@buckridge.com faker.internet.ipv6Address(); // 2450:a5bf:7855:8ce9:3693:58db:50bf:a105 faker.internet.userName(); // fiona-ward faker.person.name(); // Fiona Ward faker.person.prefix(); // Mrs. faker.person.suffix(); // Sr. faker.lorem.sentence(); // Nec nam aliquam sem et } ``` -------------------------------- ### Resolving Flutter Dependency Conflicts with pub add Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0139-github-copilot-tips-flutter-devs/index.md This command demonstrates how to use 'flutter pub add' to update multiple package constraints simultaneously, specifically addressing version solving failures related to null safety in older Flutter projects. It provides a comprehensive solution to bring dependencies up to compatible versions. ```Dart flutter pub add cupertino_icons:^1.0.6 flutter:'{"version":"^0.0.0","sdk":"flutter"}' flutter_launcher_icons:^0.13.1 dev:flutter_test:'{"version":"^0.0.0","sdk":"flutter"}' ``` -------------------------------- ### Using JsonCodable Macro for JSON Serialization in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0160-dart-macros-json-codable/index.md This snippet demonstrates how to use the experimental `JsonCodable` macro in Dart. It shows defining a `Movie` class with the `@JsonCodable()` annotation, which automatically generates `fromJson` and `toJson` methods. The example then deserializes a JSON map into a `Movie` object and serializes it back to JSON, illustrating the macro's real-time functionality. ```Dart // Example showing how to use the JsonCodable macro import 'package:json/json.dart'; @JsonCodable() class Movie { final int id; final String title; } void main() { const movieJson = { 'id': 5, 'title': 'Dune', }; final movie = Movie.fromJson(movieJson); print(movie.toJson()); } ``` -------------------------------- ### Running Flutter App from Specific Route via CLI Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0232-flutter-run-route/index.md This command allows you to start your Flutter application directly from a specified named route. It is particularly useful for debugging nested routes, as it enables hot-restarts to begin at the desired screen without navigating manually. Works with both Navigator 1.0 named routes and Navigator 2.0 router APIs. ```Shell flutter run --route /path/to/route ``` -------------------------------- ### Initializing Firebase with appFlavor in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0201-firebase-init-multiple-flavors/index.md This snippet demonstrates how to initialize Firebase by dynamically selecting `FirebaseOptions` based on the `appFlavor` constant. While convenient, this method bundles all Firebase configuration files (production, staging, development) into the final application, which is not ideal for security or app size. ```Dart import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_ship_app/firebase_options_prod.dart' as prod; import 'package:flutter_ship_app/firebase_options_stg.dart' as stg; import 'package:flutter_ship_app/firebase_options_dev.dart' as dev; Future initializeFirebaseApp() async { // Determine which Firebase options to use based on the flavor final firebaseOptions = switch (appFlavor) { 'prod' => prod.DefaultFirebaseOptions.currentPlatform, 'stg' => stg.DefaultFirebaseOptions.currentPlatform, 'dev' => dev.DefaultFirebaseOptions.currentPlatform, _ => throw UnsupportedError('Invalid flavor: $flavor'), }; await Firebase.initializeApp(options: firebaseOptions); } void main() async { WidgetsFlutterBinding.ensureInitialized(); await initializeFirebaseApp(); runApp(const MainApp()); } ``` -------------------------------- ### Generating Widget Tests for AsyncValueWidget - Dart/Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0139-github-copilot-tips-flutter-devs/index.md This snippet demonstrates GitHub Copilot's ability to generate Flutter widget tests for an existing `AsyncValueWidget` class. It includes tests for loading, data presence, and error states, utilizing `flutter_test`, `flutter/material`, and `flutter_riverpod` for comprehensive coverage. ```Dart import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ecommerce_app/src/common_widgets/async_value_widget.dart'; void main() { testWidgets('AsyncValueWidget shows CircularProgressIndicator when loading', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( home: AsyncValueWidget( value: AsyncValue.loading(), data: (value) => Text('$value'), ), )); expect(find.byType(CircularProgressIndicator), findsOneWidget); }); testWidgets('AsyncValueWidget shows Text widget when data is present', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( home: AsyncValueWidget( value: AsyncValue.data(10), data: (value) => Text('$value'), ), )); expect(find.text('10'), findsOneWidget); }); } ``` -------------------------------- ### Running Flutter App with JSON File Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0175-dart-define-from-file-env-json/index.md This command illustrates how to launch a Flutter application, instructing it to load environment variables from a specified JSON file. The `--dart-define-from-file` flag ensures that the variables defined in `api-keys.json` are accessible within the Dart code. ```Shell flutter run --dart-define-from-file=api-keys.json ``` -------------------------------- ### Creating BuildContext Extension for Shorter Localization Syntax (Flutter/Dart) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md This Dart extension on `BuildContext` provides a convenient getter `loc` to access `AppLocalizations.of(this)`. This shortens the syntax for accessing localized strings throughout the application, improving readability and developer experience. ```Dart extension AppLocalizationsExtension on BuildContext { AppLocalizations get loc => AppLocalizations.of(this); } ``` -------------------------------- ### Applying Tabular Figures to TextStyle in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0218-text-style-tabular-figures/index.md This snippet demonstrates how to apply `FontFeature.tabularFigures()` to a `TextStyle` in Flutter. This feature ensures that all digits within the text are rendered with a fixed width, making them monospaced. It is particularly useful for displaying numbers or dates that need to align vertically or update in real-time, improving readability and visual consistency. The example uses a `Text` widget with a `const TextStyle`. ```Dart Text( currentTimeFormatted, style: const TextStyle( // Set this font feature to ensure all digits are rendered with a fixed width (monospace) // Useful when showing numbers or dates that update in realtime fontFeatures: [FontFeature.tabularFigures()], fontFamily: "Roboto", fontSize: 48, fontWeight: FontWeight.w700, ), ) ``` -------------------------------- ### Configuring Non-Synthetic Localization Generation in l10n.yaml (YAML) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md Adding `synthetic-package: false` to `l10n.yaml` instructs Flutter to generate localization files as a non-synthetic package. This ensures the generated files are placed in the `output-dir` specified, rather than the default `.dart_tool` directory. ```YAML synthetic-package: false ``` -------------------------------- ### Extracting Current Method Name (Initial Hack) - Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0174-get-method-name-stack-trace/index.md This snippet demonstrates an initial, basic approach to extracting the current method's name from the stack trace in Dart. It parses the stack trace string, splits it by newlines, and then extracts the method name from the second frame. This method is noted as fragile and not robust for all scenarios like extension methods or closures. ```Dart import 'dart:collection'; String getCurrentMethodName() { final frames = StackTrace.current.toString().split('\n'); final frame = frames.elementAtOrNull(1); if (frame != null) { // Example frame: // #1 LoggerAnalyticsClient.trackAppOpen (package:flutter_ship_app/src/monitoring/logger_analytics_client.dart:28:9) final tokens = frame.split(' '); final methodName = tokens.elementAtOrNull(tokens.length - 2); if (methodName != null) { final methodTokens = methodName.split('.'); return methodTokens.lastOrNull ?? ''; } } return ''; } class LoggerAnalyticsClient { void trackAppOpen() { log(getCurrentMethodName()); } } ``` -------------------------------- ### Partially Correct Platform Check with kIsWeb and dart:io.Platform in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0165-default-target-platform/index.md This snippet shows a partially correct approach. While it prevents web crashes by checking `kIsWeb` first, it still imports `dart:io`, which is unnecessary if `Platform` is only used for `isIOS` and `defaultTargetPlatform` can achieve the same. It's less efficient and still relies on `dart:io`. ```Dart import 'dart:io'; import 'package:flutter/foundation.dart'; if (!kIsWeb && Platform.isIOS) { ... } ``` -------------------------------- ### Launching App Store/Play Store URLs in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0157-force-upgrade-gone-wrong/index.md This Dart function demonstrates how to programmatically launch the appropriate app store URL (Google Play Store for Android or Apple App Store for iOS) using the `url_launcher` package. It first checks if the URL can be launched before attempting to open it, providing error handling if the launch fails. The original implementation contained placeholder URLs, which caused the described issue. ```Dart Future _launchAppStore() async { // TODO: Replace these URLs with your app's URLs final urlAndroid = Uri.parse( 'https://play.google.com/store/apps/details?id=com.example.myapp'); final urlIOS = Uri.parse('https://apps.apple.com/us/app/myapp/id123456789'); final url = Platform.isIOS ? urlIOS : urlAndroid; if (await canLaunchUrl(url)) { await launchUrl(url); } else { throw 'Could not launch $url'; } } ``` -------------------------------- ### Running the Dart Formatter from Project Root Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0229-new-formatting-style-dart-3.7/index.md This command executes the Dart formatter across your entire codebase from the project's root directory, applying the new formatting rules based on the configured `page_width`. ```Bash dart format . ``` -------------------------------- ### Enabling Synthetic Localization Generation in pubspec.yaml (Flutter) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md Setting `generate: true` in `pubspec.yaml` enables the generation of localization files as a synthetic package. This means the generated files will reside under the `.dart_tool` directory, and the `output-dir` specified in `l10n.yaml` will be ignored. ```YAML flutter: generate: true ``` -------------------------------- ### Extracting Current Method Name (Refined Hack) - Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0174-get-method-name-stack-trace/index.md This refined Dart snippet provides a more robust way to extract the current method name from the stack trace, specifically handling anonymous closures. It parses the stack trace, identifies the relevant frame, and then extracts the method name, attempting to remove the class name if present. This method is still considered a hack, slow, and not suitable for obfuscated builds. ```Dart /// Helper function to extract the current method name from the stack trace String getCurrentMethodName() { final frames = StackTrace.current.toString().split('\n'); // The second frame in the stack trace contains the current method final frame = frames.elementAtOrNull(1); if (frame != null) { // Extract the method name from the frame. For example, given this input string: // #1 LoggerAnalyticsClient.trackAppOpen (package:flutter_ship_app/src/monitoring/logger_analytics_client.dart:28:9) // The code will return: LoggerAnalyticsClient.trackAppOpen final tokens = frame .replaceAll('', '') .split(' '); final methodName = tokens.elementAtOrNull(tokens.length - 2); if (methodName != null) { // if the class name is included, remove it, otherwise return as is final methodTokens = methodName.split('.'); // ignore_for_file:avoid-unsafe-collection-methods return methodTokens.length >= 2 && methodTokens[1] != '' ? (methodTokens.elementAtOrNull(1) ?? '') : methodName; } } return ''; } ``` -------------------------------- ### Creating ARB File for Spanish Localization (JSON) Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0070-localizations/index.md This ARB file provides Spanish translations. Unlike the template file, it only needs to define the `@@locale` and the translated key-value pairs, without the additional metadata like descriptions for each key. ```JSON { "@@locale": "es", "helloWorld": "Hola Mundo" } ``` -------------------------------- ### Determining Platform for Emulation and Testing with `Theme.of(context).platform` - Dart/Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0164-universal-platform-package/index.md This snippet demonstrates how Material library widgets can use `Theme.of(context).platform` to determine the current platform, enabling emulation of platform-specific UI behaviors. A key advantage is the ability to override the platform during testing by supplying a `ThemeData` with a different `TargetPlatform` value, which is not possible with `Platform` or `UniversalPlatform`. ```Dart // Widgets from the material library should use Theme.of(context) // to determine the current platform for the purpose of emulating // the platform behavior if (Theme.of(context).platform == TargetPlatform.iOS) { // iOS logic here } // Tests can check behavior for other platforms by setting the // [platform] of the [Theme] explicitly to another [TargetPlatform] value ``` -------------------------------- ### Implementing Shimmer Loading UI in Flutter Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0154-shimmer-effect/index.md This snippet demonstrates how to create a Shimmer loading effect using the `Shimmer.fromColors` widget. It defines base and highlight colors for the shimmer animation and applies it to a placeholder UI structure, including a container and an aspect ratio box, to simulate content loading. ```Dart Shimmer.fromColors( baseColor: Colors.grey.shade300, highlightColor: Colors.grey.shade100, child: Column( mainAxisSize: MainAxisSize.min, children: [ Container(height: 22.0, color: Colors.white), const SizedBox(height: 12.0), // some spacing const AspectRatio( aspectRatio: 16.0 / 9.0, child: ColoredBox(color: Colors.white), ) ], )) ``` -------------------------------- ### Importing dart:developer for Logging in Dart Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0177-log-function-args/index.md This snippet demonstrates the necessary import statement to access the `log` function, which provides enhanced logging capabilities within Dart and Flutter applications. ```Dart import 'dart:developer'; ``` -------------------------------- ### Running Riverpod Generator with build_runner Source: https://github.com/bizz84/flutter-tips-and-tricks/blob/main/tips/0081-future-provider-riverpod-generator/index.md This command initiates the `build_runner` tool in watch mode, which automatically generates and updates Riverpod provider code (e.g., `.g.dart` files) whenever changes are saved in the project. It's essential for utilizing the Riverpod Generator package. ```Dart dart run build_runner watch ```