Rapid Updates?

Split can evaluate a feature flag at any time, but also boasts a streaming service to update your app immediately when a flag has changed. Streaming is the default means of receiving updates from the Split cloud (polling can be used as a fallback measure), but you do have to write a little code to take advantage of updates. This article builds on a previous one to explain how to take full advantage of Split and Split dynamic updates.

What are Split and Flutter?

Split is the premier feature delivery platform, encompassing feature flags, measurement, and experimentation. Flutter is a cross-plaform approach to building snazzy apps.

Split Flutter Plugin

Split has supported Flutter for years, and now it has a native Flutter Plugin. The Split plugin gives you the full SDK experience that you enjoy on other platorms:

  • Client-side Evaluation
    Now private information stays private, on the client-side. Split will never send private attributes back to its cloud.
  • Integration with Flutter staples like the FutureBuilder (read on for details)
  • Dynamic configuration
    Describe your user interface at the Split console, where a product manager might make changes, and see the results in your application without code changes (read on for details)
  • Streaming updates, the main subject of this article
  • … and more you can read about in the official technical documentation.

Introducing Flutter Araki

Flutter Araki is a simple example of using Split with Flutter. You can review, clone, and run the example right from the Github site:

https://github.com/splitio/flutter-araki

You’ll need to sign up for a Split account if you haven’t already got one. Otherwise, I just expect that you’re already familiar with flutter. While flutter supports many IDEs, my examples are at the command line so as to be as universal as possible.

The rest of this article will walk through the Araki example.

Getting Started

Create a new directory and clone the repository.

git clone https://github.com/splitio/flutter-araki

I assume you have flutter on the command line. When you run the app, flutter will ask you to choose between targets.

flutter run

You should get a spinning blue circle. Stop it. The Split service is not available because:

  • We haven’t installed the Split API token
  • The referenced “multivariant_demo” feature flag has not been created.

Adding the Split API Token

To your lib/ directory (where main.dart is located) add a new file called splitApiToken.dart. It’s contents should look like below.

class SplitApiConfig {
	static const  String apiToken = '<your split client-side api token>';
}

You can get a client-side API token from the Syntax button of your feature flag editor screen (under the “…” menu to the right of the KILL button) or the Admin Settings of your Split account (top-left dropdown menu), and there is more coaching in the official documention.

Choose a client-side language, like iOS or Android for a key.

Creating the multivariant_demo split

Split is two-variant, “on” and “off”, by default, but you can create as many variants as you like for this example.

Each config has an “image” and a “text” key. This ultimately determines what Flutter will see in JSON at runtime. Make sure that you give your treatments an “image” URL and a “text”, as these are the values used by the Araki example.

Here are my treatment configs, and you may use them. You will need to change the treatment names from “on” to “blue” and “off” to “red” as well as adding a third treatment for “green”. In the Attach configuration to your treatments section of your multivariant_demo split, cut-and-paste the JSON below into each respective treatment.

For blue... 
{"text":"Bring a Cute Dog Home","image":"http://www.cortazar-split.com/dog_by_the_door.jpeg"}

For red...
{"text":"Adopt a  Dog","image":"http://www.cortazar-split.com/dog_origin.jpeg"}

For green...
{"text":"This dog is chillin'","image":"http://www.cortazar-split.com/dog_on_the_couch.jpeg"}

Run again!

flutter run

Now you should be looking at one of your images captioned by your text. If you used my example, your screen will be showing a dog.

With streaming enabled, you can change the dog by changing treatments. Just change the default treatment from red to green and you’ll see a new dog show up.

Streaming takes about a minute to enable, so if you switch immediately after launch you may have to wait a few seconds for the change. Once streaming is fully enabled, the treatment changes should take effect immediately.

How does it work?

Flutter features a FutureBuilder that is perfect for use with Split.

  
  Widget build(BuildContext context) {

    return FutureBuilder<SplitResult>(
      future: _splitResult,
      builder: (BuildContext context, AsyncSnapshot<SplitResult> snapshot) {
        List<Widget> children;
        
        if(snapshot.hasData) {
           ... what to show when data is available ...
        else if (snapshot.hasError) {
           ... what to show when there's a problem ...
        } else {
           ... show a progress indicator... spinning blue circle? ..
        }

The FutureBuilder is waiting for its snapshot to become available. The snapshot is returned from the future, which is a _splitResult.

Future<SplitResult> getSplitTreatment() {  
    Completer<SplitResult> resultCompleter = Completer();  
  
  _split.client(onReady: (client) async {  
      print("client is ready, calling getTreatment");  
  resultCompleter  
        .complete(client.getTreatmentWithConfig('multivariant_demo'));  
  }, onReadyFromCache: (client) {  
      print("onReadyFromCache!");  
  }, onUpdated: (client) async {  
      print("onUpdated!");  
  SplitResult result = await client.getTreatmentWithConfig('multivariant_demo');  
 var json = jsonDecode(result.config!);  
  print(json);  
  print("adding JSON to stream controller");  
  streamController.add(json);  
  }, onTimeout: (client) {  
      print("onTimeout!");  
  });  
  
 return resultCompleter.future;  
}

Future<SplitResult> _splitResult = getSplitTreatment();

This getSplitTreatment has more event handling than the one from my earlier article. In particular, Araki is listening for onUpdated. The SDK will fire onUpdated when streaming has picked up a change in the feature flags.

The onUpdated handler retrieves the latest treatment (with config) for our split, then parses the JSON. Finally, it passes the JSON to the streamController.

What is the streamController?

StreamController<dynamic> streamController = StreamController<dynamic>();

We declare it up at the top of the main.dart. Its stream is passed to the MyHomePage constructor.

  
Widget build(BuildContext context) {  
  return MaterialApp(  
    title: 'Split Demo',  
  theme: ThemeData(  
      primarySwatch: Colors.blue,  
  ),  
  home: MyHomePage('Split Demo Home Page', streamController.stream),  
  );  
}

_MyHomePageState has an initState and mySetState function for handling the stream.

class _MyHomePageState extends State<MyHomePage> {  
  int _counter = 0;  
 var _image;  
 var _text;  
  
    
  void initState() {  
    super.initState();  
  widget.stream.listen((json) {  
      print("LISTEN");  
  mySetState(json);  
  });  
  }  
  
  void mySetState(dynamic json) {  
    print ("mySetState");  
  setState(() {  
      _image = json['image'];  
  _text = json['text'];  
  });  
  }

Now, the JSON passed as a streaming event will be received and used to set the _image and _text variables of our main component such that the component automatically refreshes.

Conclusions

Using Split with Flutter is fun and profitable. If you want more Split coaching specifically, please get in touch for more information. david.martin@split.io