applanga_flutter 0.0.10

  • Readme
  • Changelog
  • Example
  • Installing
  • 31

applanga_flutter #

A Flutter plugin for Applanga.

For a sample Usage see the example.

Note: This plugin is still under development, and some APIs might not be available yet. Feedback and Pull Requests are most welcome!

Usage #

Installation

To use this plugin, add applanga_flutter as a dependency in your pubspec.yaml file.

Applanga settings file
  1. Download the Applanga Settings File for your app from the Applanga App Overview by clicking the [Prepare Release] button and then clicking ***[Get Settings File]***.
  2. Add the Applanga Settings File to your Android modules resources res/raw directory
  3. Also Add the Applanga Settings File to your iOS modules main target. To do this open the ios module in Xcode and drag the settings file into the project. Make sure to tick the target you want it applied to.
iOS: Be aware to add the supported languages to the info.plist. Find more here.
iOS: Add the following dependancy to your podfile located at ProjectRoot/ios/PodFile

pod 'Applanga'

Import

import 'package:applanga_flutter/applanga_flutter.dart';

Methods

Note: The Flutter to native bridge is asynchronous. So all Methods are asynchronous calls.

ApplangaFlutter.getString("string_key", "default_message")

If string_key does not exists, default_message gets uploaded (see topic String Upload).

ApplangaFlutter.getUpdate()

Fetches changes from the dashboard and updates the local Applanga Database. You have to rerender your UI to see latest changes. Be aware that due to our CDN-Caching it can take up to 15 minutes to be able to fetch new translations.

ApplangaFlutter.localizeMap(
	{
		"en": {
			"hello_world": "Hello World"
		},
		"de" : {
			"hello_world": "Hallo Welt"
		}
	}
);

ApplangaFlutter.localizeMap(map) returns the same map but with the actual Applanga localizations.

String Upload

Strings from ApplangaFlutter.getString(String, String) and Strings which are located in the map of ApplangaFlutter.localizeMap(map), will be uploaded if the app is in debug mode and fulfill one of the two points: They are non existent on the Applanga Dashboard or the target text is empty.

Debug mode for iOS

Open your ios/*.xcodeproj or ios/*.xcworkspace in XCode and run your app.

Debug mode for Android

Open Android Studio, File - Open. android/ directory. Run "Debug 'app'".

Draft Mode and screeshot menu

To trigger the draft mode activation dialog you can call ApplangaFlutter.showDraftModeDialog();

Once in draft mode you can show or hide the screenshot menu like so ApplangaFlutter.setScreenShotMenuVisible(bool);

NOTE: Screenshots collect the values of strings on screen using server side OCR, so will not be 100% accurate in some cases.

Automating screenshot upload

By using tests and a test runner like flutter_driver you can automate the taking and uploading of screenshotd from your apps. In the example project, in the test_driver folder you can see how we setup an automatic screenshot flow including 2 views.

In the driver app wrapper 'test_driver/app.dart' you can see that we first initialise the applanga test utils and then we use them to decode messages in the driver handler like so:

void main() {

  var applangaTestUtil = ApplangaFlutterTestUtils(ApplangaFlutter.captureScreenshotWithTag, ApplangaFlutter.setLanguage);

  enableFlutterDriverExtension(handler: (payload) async {
    applangaTestUtil.checkForApplangaRequests(payload);
  });

  app.main();

}

Then in the test running file 'test_driver/app_test.dart', we have a test that takes 2 screenshots, the first with OCR disabled and the string IDs manually passed, the second with OCR enabled.

test('takeScreenShots', () async {

        //allow time for app to init
        await Future.delayed(const Duration(seconds: 2), (){});

        //set the sdk language to german so that the screenshots are attached to the german language in the applanga dashboard
        ApplangaFlutterTestUtils.setApplangaLanguage(driver,"de");

        //manually add the string ids for this view
        var stringIds = new List<String>();
        stringIds.add("draftModeLabel");
        stringIds.add("showScreenShotMenu");

        //upload a screenshot with the tag "Page-1", OCR disabled and the string ids manually set
        await ApplangaFlutterTestUtils.takeApplangaScreenshot(driver,"Page-1", false, stringIds);

        //open the second view
        driver.tap(drive.find.byValueKey("OpenSecondPage"));
        await Future.delayed(const Duration(seconds: 1), (){});

        //take a screenshot with the tag "Page-2", OCR enabled and no string ids manually passed
        await ApplangaFlutterTestUtils.takeApplangaScreenshot(driver,"Page-2", true,null);

      });

[0.0.7] #

  • Added ApplangaFlutterTestUtils for better automated screenshot flow

[0.0.6] #

  • Added Autoimated screenshot example using flutter_driver

[0.0.5] #

  • Added programattic screenshots

[0.0.4] #

  • OCR Screenshot support

[0.0.1] #

  • Initial Release

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:applanga_flutter/applanga_flutter.dart';
import 'localisations.dart';

void main() {
  runApp(new Demo());
}

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      localizationsDelegates: [
        const ApplangaLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en'),
        const Locale('de')
      ],
      // Watch out: MaterialApp creates a Localizations widget
      // with the specified delegates. DemoLocalizations.of()
      // will only find the app's Localizations widget if its
      // context is a child of the app.
      home: new DemoApp(),
    );
  }
}

class DemoApp extends StatefulWidget {
  DemoAppState createState() => new DemoAppState();
}
class DemoAppState extends State<DemoApp>{

  void _applangaUpdate() async{
    await ApplangaFlutter.update();
    await ApplangaLocalizations.of(context).localizeMap();
    setState(() {
      //do nothing just rebuild widget tree -> important
    });
  }

  void initState() {
    super.initState();
    _applangaUpdate();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        //title: new Text(DemoLocalizations.of(context).title),
        title: new Text(ApplangaLocalizations.of(context).get("hello_world")),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FlatButton(
              onPressed: () {
                    ApplangaFlutter.showDraftModeDialog();
              },
              child: Text(
                ApplangaLocalizations.of(context).get("draftModeLabel"),
              ),

            ),
            FlatButton(
              onPressed: () {
                ApplangaFlutter.setScreenShotMenuVisible(true);
              },
              child: Text(
                  ApplangaLocalizations.of(context).get("showScreenShotMenu")
              ),

            ),
            FlatButton(
              onPressed: () {
                ApplangaFlutter.setScreenShotMenuVisible(false);
              },
              child: Text(
                  ApplangaLocalizations.of(context).get("hideScreenShotMenu")
              ),
            ),
            FlatButton(
              onPressed: () {
                ApplangaFlutter.captureScreenshotWithTag("test",true,null);
              },
              child: Text(
                  ApplangaLocalizations.of(context).get("takeProgramaticScreenshot")
              ),
            ),
            FlatButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondRoute()),
                );
              },
              key: Key("OpenSecondPage"),
              child: Text(
                  "Open Second View"
              ),
            )
          ],
        ),
      ),
    );
  }

}
class SecondRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            // Navigate back to first route when tapped.
          },
          child: Text(ApplangaLocalizations.of(context).get("secondPageTitle")),
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  applanga_flutter: ^0.0.10

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:applanga_flutter/applanga_flutter.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
17
Health:
Code health derived from static analysis. [more]
41
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
50
Overall:
Weighted score of the above. [more]
31
Learn more about scoring.

We analyzed this package on Jul 10, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.14
  • Flutter: 1.17.5

Health issues and suggestions

Fix lib/applanga_test_utils.dart. (-57.81 points)

Analysis of lib/applanga_test_utils.dart failed with 3 errors:

line 2 col 8: Target of URI doesn't exist: 'package:flutter_driver/flutter_driver.dart'.

line 18 col 46: Undefined class 'FlutterDriver'.

line 31 col 35: Undefined class 'FlutterDriver'.

Document public APIs. (-1 points)

22 out of 22 API elements have no dartdoc comment.Providing good documentation for libraries, classes, functions, and other API elements improves code readability and helps developers find and use your API.

Format lib/applanga_flutter.dart.

Run flutter format to format lib/applanga_flutter.dart.

Maintenance issues and suggestions

No valid SDK. (-20 points)

The analysis could not detect a valid SDK that can use this package.

The package description is too short. (-20 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
flutter_localizations 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
intl 0.16.1
meta 1.1.8 1.2.2
path 1.6.4 1.7.0
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies
flutter_test