Skip to content

United Network NFC application

Dependencies

The project relies on the Flutter SDK and the following key third-party packages, as identified in the imports and build configurations:

  • flutter_bloc: Used for state management (BLoC pattern).
  • flutter_native_splash: Handles the native splash screen preservation and removal during initialization.
  • lottie: Renders vector animations (JSON format).
  • intl: Provides internationalization and localization facilities.
  • flutter_localizations: Built-in Flutter package for localization delegates.
  • get_it / injectable (Inferred): Used for Dependency Injection (referenced as getIt and configureDependencies).

Customization

Change application title

Open lib/l10n/app_en.arb and change appTitle value or any other desired one, then run:

shell
flutter pub get

Change application ID and launcher title

Android

android/app/build.gradle

groovy
android {
    namespace = "your.android.package"
    ...
    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId = "your.android.package"
        ...
    }
}

android/app/src/main/AndroidManifest.xml

xml
<application
    android:label="Your App"
    ...
</application>

iOS

Change your app's Bundle ID in XCode then edit the following file:

ios/Runner/Info.plist

xml
<dict>
    ...
    <key>CFBundleDisplayName</key>
    <string>Your App</string>
    <key>CFBundleName</key>
    <string>your.bundle.id</string>
    ...
    <key>NFCReaderUsageDescription</key>
    <string>Scan your YourCompany card</string>
    ...
</dict>

Change default web application URL

Open pubspec.yaml, search for defaultUrl variable inside dart_define section, change default value and run:

shell
dart run dart_define generate --force

Change splash screen background image (both iOS and Android)

Replace assets/splash_logo.png with the desired one and run:

shell
dart run flutter_native_splash:create

Change application icon

Android

Open android folder in Android Studio, then open Resource Manager, select module android.app.main and navigate to Mip Map tab. There will be ic_launcher and ic_launcher_round resources. Navigate inside them, there will be 6 icon variants for each asset. Replace them by importing the new vector or image asset of different resolution and renaming it accordingly. Also replace android/app/src/main/ic_launcher-playstore.png icon for the Android Play Store.

iOS

Navigate to ios/Runner/Assets.xcassets/AppIcon.appiconset and replace a set of PNG files with your own.

Update Android signing

Use this command to generate new android/release.keystore file:

shell
keytool -genkeypair -v -keystore release.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias androidkey

You’ll be asked for:

  • keystore password
  • key password
  • name / organization (can be anything)

Update RELEASE_KEY_PASSWORD and RELEASE_STORE_PASSWORD in android/gradle.properties if needed.

Then retrieve the fingerprints from it:

shell
keytool -list -v -keystore release.keystore -alias androidkey

Update version

pubspec.yaml

toml
name: your_app_name
description: "Your App Description"
version: 1.0.0+1

Android

Add the required changes into android/app/src/main/AndroidManifest.xml

xml
...
<activity>
    ...
    <meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="your.domain" />
        ... Any number of additional domains ...
    </intent-filter>
    <intent-filter android:autoVerify="true">
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="your.domain" />
        ... Any number of additional domains ...
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="yourscheme" android:host="open" />
    </intent-filter>
</activity>
...

Use yourscheme for deep links in your web application.

Add the associated domains to your web application's web site. Create a file https://your.domain/.well-known/assetlinks.json

json
[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "your.android.package",
      "site": "your.domain",
      "sha256_cert_fingerprints":
      ["00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"]
    }
  }
  ... Any number of additional domains ...
]

Where sha256_cert_fingerprints is an array of SHA-256 fingerprints of your keystore used to sign the Android app.

iOS

Add the required changes into ios/Runner/Runner.entitlements

xml
<dict>
    ...
   	<key>com.apple.developer.associated-domains</key>
	<array>
		<string>applinks:your.domain</string>
		<string>webcredentials:your.domain</string>
        ... Any number of additional domains ...
	</array>
</dict>

Add the associated domains to your web application's web site. Create a file https://your.domain/.well-known/apple-app-site-association

json
{
  "applinks": {
      "details": [
           {
             "appIDs": [ "YOURTEAM.your.domain" ],
             "components": [
               {
                  "/": "/*",
                  "comment": ""
               }
             ]
           }
       ]
   },
   "webcredentials": {
      "apps": [ "YOURTEAM.your.domain" ]
   },
   "appclips": {
      "apps": ["YOURTEAM.your.domain.YourApp.Clip"]
   }
}

Where YOURTEAM is your Apple Team ID.

Building the app

Android

After cloning and making changes run the following commands:

shell
# Fetching dependencies and generating localizations
flutter pub get
# Code generation
dart run build_runner build --delete-conflicting-outputs --verbose
# Config generation
dart run dart_define generate --force
# Building debug APK
flutter build apk --debug --dart-define-from-file=config.json
# Building release APK
flutter build apk --dart-define-from-file=config.json
# Building AAB for Google Play Market
flutter build aab --dart-define-from-file=config.json

iOS

Although, there is no need to build it directly, it is crucial to run

shell
flutter build ios --dart-define-from-file=config.json

in order to config will be picked up by the subsequent XCode builds.

Deployment to stores

Android

Use the AAB built on previous step and upload it in your Google Play Console.

iOS

Create a provisioning profile for your app on Apple developer portal. Download it to your device. Enable Associated Domains and NFC Tag Reading entitlements. Open Runner.xcworkspace in XCode. On Runner -> Signing and Capabilities page select dowloaded provisioning profile. Then select Build -> Archive. After successful build you will be presented with Archives window with a list of builds of your application. Select the topmost one and click Distribute App. Select a method for distribution window will appear. Select a desired method (eg. App Store or TestFlight) and click Distribute. The app will be deployed to selected platform.