Making Flutter more Reactive

When chatting with some dev about the reactivity of Flutter he made the great statement Flutter is REACTive and not reactive in the sense we know from Reactive Extensions (Rx).

Coming from Xamarin and ReactiveUI this somewhat disappointed me because if you once started to think the Rx way you never want to go back.

From MVVM to RxVAMS

Coming from Xamarin Forms MVVM is the natural architectural pattern for Apps for me. MVVM solves a lot of problems while still is easy to understand and don’t introduce unnecessary components.

Please stay with me for a moment we come back to Flutter I promise

I won’t describe MVVM in detail this is excellently done here

MVVM

It basically consists of three layers where the View which consists of all UI elements you see on the screen. It can also contain logic that only concerns the UI. The Model contains your business logic and backend connections. The ViewModel is the glue between both in that it processes and transforms data from the Model to a form the View can easily display. It offers functions (often called Commands) the View can call to trigger actions on the Model and provides events to signal the View about data changes.

Important: The ViewModel knows nothing about the View which makes it testable and more than one View can use the same ViewModel. A ViewModel just offers services to the View (events, commands). The _View decides which it uses.

Several MVVM frameworks encapsulate the subscription of events and calling functions to update data in the ViewModel from the View using DataBindings

To trigger any other action in the View besides data updates from the ViewModel gets tedious because you have to publish events and functions if the View should be able to retrieve data as a result of the event.

Another problem is that we always moving state between the different layers which have to be kept in sync.

What we really want is an App that just reacts on any event from the outside without having to deal with state management all the time.

Rx to the rescue

If you never heard of Rx before think of it as streams of events on that you can do transformations in a Linq like manor. Although Rx was first developed be Microsoft it is no available to almost any Language. You can find an introduction on reativex.io From there:

The ReactiveX Observable model allows you to treat streams of asynchronous events with the same sort of simple, combindable operations that you use for collections of data items like arrays. It frees you from tangled webs of call-backs, and thereby makes your code more readable and less prone to bugs.

When working with Rx you define rules how to react on events in a declarative way. This is done in a functional manor to reduce any side effects. Applied to MVVM this means all communication between layers happen over even streams (called Observable in Rx) and reactive commands. Best of all Observable streams are asynchronous by nature.

The Dart implementation of Rx is RxDart.

ghuntley

Introducing RxVAMS

I have no idea if anybody else will use this name but I like it 🙂

There is another observation that leaves some doubt if MVVM is the right pattern for mobile Apps. MVVM was aimed at sharing the code of Model and even ViewModel between different apps which is really rarely the case.
Looking at real world apps you often realize that the model layer degenerated to a service layer that connects the app to the rest of the world and that the VieModels have more and more logic in it instead just beeing an adapter. The reason for this is that typical apps don’t deal with complex business logic. So I propose the following pattern for Apps:

RxVAMS

This also separates the App in three layers but replaces the ViewModel with an AppModel that contains the whole app logic and the interface for the View consisting of reactive commands (in the following RxCommands) and Observables that offer state changes to the view.
In order to react on events the View subscribes to this Observables

The Model is replaced by a designated Service layer which offers all services that connects the app to the outside (REST APIs, device APIs, databases). Data from the Service Layer is returned as Observable or be asynchronous function calls to make the access asynchronous.

If you don’t want to follow this pattern just replace AppModel with ViewModel in your mind for the rest of the post.

Calling to action

I made a little demo app to show the following in practise. It queries a REST API for Weather data and displays it in a ListView. I made branches for every step of the rest of this post so that you can easily try it yourself.

A big, big thank to Brian Egan for polishing the App for the last step, even including unit and UI Tests!

Inject the AppModel to the View

Code for this step

To access an object from anywhere in the widget tree Flutter offers the concept of the InheritedWidget. When added to a widget tree the InheritedWidget can be accessed anywhere down that tree by calling its static of() method.

In main.dart:

class TheViewModel extends InheritedWidget
{
  final HomePageAppModel theModel;

  const TheViewModel({Key key, 
                      @required 
                      this.theModel, 
                      @required 
                      Widget child}) :  assert(theModel != null),assert(child != null),
                      super(key: key, child: child);

  static HomePageAppModel of(BuildContext context) => (context.inheritFromWidgetOfExactType(TheViewModel)as TheViewModel).theModel;                  

  @override
  bool updateShouldNotify(TheViewModel oldWidget) => theModel != oldWidget.theModel;

}

In this case the .of() doesn’t return the inherited widget but directly the contained HomePageAppModel instance as it is the only data field.

As we want to have our AppModel available anywhere in our HomePage we insert it in the very top of our widget tree.

In main.dart:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  @override
  Widget build(BuildContext context) {
    return new TheViewModel( 
                  theModel:  new HomePageAppModel(),
                  child: 
                  new MaterialApp(
                    title: 'Flutter Demo',
                    home: new HomePage()
                  ),
                );
  }
}

Step 1: Making the Views Reactive

Code for this step

The typical way to react with Flutter on events from a ViewModel is to create a StatefulWidget and subscribe to an event in the initState method of the State and call setState on each event.

Using StreamBuilder and Streams instead of event subscriptions is the first step to make this easier StreamBuilder takes a stream as an input and calls its builder function each time it receives a new input:

In listview.dart:

Widget build(BuildContext context) {
    return new StreamBuilder<List<WeatherEntry>>(   // Streambuilder rebuilds its subtree on every item the stream issues
            stream: TheViewModel.of(context).newWeatherEvents,   //We access our AppwModel through the inherited Widget
            builder: (BuildContext context, AsyncSnapshot<List<WeatherEntry>> snapshot)  // in Dart Lambdas with body don't use =>
                {
                // only if we get data
                if (snapshot.hasData && snapshot.data.length > 0)
                {
                    return new ListView.builder(
                                itemCount: snapshot.data.length,
                                itemBuilder : (BuildContext context, int index) => 
                                                    buildRow(context,index,snapshot.data)                                            
                    );
                }
                else
                {
                    return new Text("No items");
                }
            }                                              
            );                            

Anytime someone queues a new Lists of WeatherEntry in this stream this ListView will be recreated with the latest data.

This happens in homepage_appmodel.dart:

// Subjects are like StreamSinks. You can queue new events that are then published on the .observable property of th subject. 
final _newWeatherSubject = new BehaviorSubject<List<WeatherEntry>>() ;

// Only the observable of the Subject gets published
Observable<List<WeatherEntry>> get newWeatherEvents  => _newWeatherSubject.observable;

update({String filtertext = ""})
{
     _newWeatherSubject
        .addStream( WeatherService.getWeatherEntriesForCity(filtertext)
                                        .handleError((error)=> print)       // if there is an error while accessing the REST API we just make a debug output
                    );          
}

Querying data and updating are completely decoupled which makes testability easy.

update is triggered by pressing the update button on the page

In homepage.dart:

new MaterialButton(                               
        child: 
        new Text("Update"), // Watch the Button is again a composition
        color: new Color.fromARGB(255, 33, 150, 243),
        textColor: new Color.fromARGB(255, 255, 255, 255),
see->   onPressed: TheViewModel.of(context).update
        ),

and if the user types into the filter TextField.

In homepage_appmodel.dart:

_inputSubject.observable
.debounce( new Duration(milliseconds: 500))  // make sure we start processing if the user make a short pause 
    .listen( (filterText)
    {
    update( filtertext: filterText);
    });  

Will call execute if a new string was queued into HomePageAppModel._inputSubject which happens in this method:

// Callback function that will be registered to the TextFields OnChanged Event
onFilerEntryChanged(String s) => _inputSubject.add(s); 

Again the event and the reaction are decoupled through a Subject and and Observable which allows further event processing like the debounce operator which makes sure that only an event is emitted if there wasn’t another change within a given period.

So to make your views reactive Streambuilder is the key. So far almost everything besides the debounce could be done too by using Dart Streams instead of Observables.

Step 2 adding RxCommands

To enable the Views to call functions in a reactive way I wrote the RxCommand package which is heavily inspired by the ReactiveCommand class of the .net framework ReactiveUI. To be more correct this enables AppModels to react “reactive” on function calls from the View.

RxCommand takes a function when created through one of its static factory methods. This method can be called by using its execute method or by directly calling the RxCommand object because it’s a callable class. This makes it possible to assign a command directly to an event of a Widget.

Nothing special so far but any result of wrapped function is emitted from the RxCommand over its results property which is you might already expect it an Observable. Especially when wrapping an async function with an RxCommand the .exceute will return immediately but the result will be emitted when the function returns.

Besides moving to RxCommands this iteration adds a busy spinner and a Switchto disable the update functionality. The App now looks like this:

App_Step_2

In homepage_model.dart:

class HomePageAppModel {

RxCommand<String,List<WeatherEntry>>  updateWeatherCommand;
RxCommand<bool,bool>  switchChangedCommand;
RxCommand<String,String>  textChangedCommand;

HomePageAppModel()
{
    // Command expects a bool value when executed and issues the value on its result Observable (stream)
    switchChangedCommand = RxCommand.createSync3<bool,bool>((b)=>b);

    // We pass the result of switchChangedCommand as canExecute Observable to the upDateWeatherCommand
    updateWeatherCommand = RxCommand.createAsync3<String,List<WeatherEntry>>(update,switchChangedCommand.results);

    // Will be called on every change of the searchfield
    textChangedCommand = RxCommand.createSync3((s) => s);

    // handler for results
    textChangedCommand.results
        .debounce( new Duration(milliseconds: 500))  // make sure we start processing only if the user make a short pause typing 
        .listen( (filterText)
        {
            updateWeatherCommand.execute( filterText); // I could omit he execute because RxCommand is a callable class but here it 
                                                        //  makes the intention clearer
        });  

    // Update data on startup
    updateWeatherCommand.execute();
}

No more Subjects and handler functions just clean RxCommands. Let’s look at it step by step beginning with the textChanged command. The function that it wraps doesn’t do anything else than pushing the passed string out of the RxCommand.result Observable, to which the handler below listens.

In other Rx implementations listen is called subscribe. As RxDart is based on Dart’s `Streams’ listen is used.

The switchChangedCommand too just pushes the received bool to its result observable. It will be assigned to the onChanged handler of the Switch widget and issue a new bool value every time the Switch changes its state. This may seem a bit pointless because nobody seems to care about this results.

But looking at the updateWeatherCommand we see that switchChangedCommand.results is passed as a second (optional) parameter. That’s the next feature of RxCommand you can pass am Observable<bool> which determines if the command can be executed or not. In our case this will make the updateWeatherCommand react to any change of the Switch automatically.

On the View’s side the commands are directly used as handler functions which is possible because they are callable classes:

In ‘homepage.dart’

new TextField(
        autocorrect: false,
        decoration: new InputDecoration(
                            hintText: "Filter cities",
                            hintStyle: new TextStyle(color: new Color.fromARGB(150, 0, 0, 0)),
                            ),
        style: new TextStyle(
                    fontSize: 20.0,
                    color: new Color.fromARGB(255, 0, 0, 0)),
-->     onChanged: TheViewModel.of(context).textChangedCommand,),

Special Features:

Not only does RxCommand offer a .results Observable but also this Observables:

  • .isExecuting emits a bool value every time the execution state of the command changes. So after calling execute it will emit true and when the wrapped function returns (even an async one) it will emit a false.
  • .canExecute emits a bool value every time the executability of the command changes. This will emit false while the command is executing but will also reflect the status of the canExecute observable if one was passed to the when creating the command. This allows to effectively set up rules on executability of multiple commands.
  • .thrownExceptions if there is a listener on this observable RxCommand will catch any exception that are thrown by the wrapped function and emit them here.
  • RxCommands can not be called again while they are executing. If you want to disable command A while another command B is executing you only have to pass B.isExecuting when creating A as canExecute parameter. Cool isn’t it? 🙂

Let’s make use of this features in the App. For instance it’s very easy to add a busy Spinner now by using another StreamBuilder that listens on updateWeatherCommand.isExecuting:

From homepage.dart:

new StreamBuilder<bool>(   
    stream: TheViewModel.of(context).updateWeatherCommand.isExecuting, 
    builder: (BuildContext context, AsyncSnapshot<bool> isRunning)  
        {
            // if true we show a buys Spinner otherwise the ListView
        if (isRunning.hasData && isRunning.data == true)
        {
            return new Center(child: new Container(width: 50.0, height:50.0, child: new CircularProgressIndicator())); 
        }
        else
        {
            return new WeatherListView();                                  
        }
    })                                              
    ),

Code for this step

While Brian did some refactoring on the example app he made the point that it would be helpful to have all three states (isExecuting, results, error) in one stream because Flutter updates its UI by rebuilding it. Using separate StreamBuilder might not always be ideal.

I totally agree with him. With frameworks that use bindings and update only single controls through them the separate streams were a good solution. For flutter I want to display alternative Widgets depending on the new state at one place during rebuild. This lead to the introduction of the CommandResult<T> class:

/// Combined execution state of an `RxCommand`
/// Will be issued for any statechange of any of the fields
/// During normal command execution you will get this items if directly listening at the command.
/// 1. If the command was just newly created you will get `null, false, false` (data, error, isExecuting)
/// 2. When calling execute: `null, false, true`
/// 3. When exceution finishes: `the result, false, false`

class CommandResult<T>
{
  final T         data;
  final Exception error;
  final bool      isExecuting;

  const CommandResult(this.data, this.error, this.isExecuting);

  bool get hasData => data != null;
  bool get hasError => error != null;

  @override
  bool operator == (Object other) => other is CommandResult<T> && other.data == data &&
                         other.error == error &&
                         other.isExecuting ==isExecuting;  
  @override
    int get hashCode => hash3(data.hashCode,error.hashCode,isExecuting.hashCode);
}

To get notified of any new CommandResult you can directly .listen to the command itself because RxCommand now also implements the Observable interface.

In the next step we will use that to our advantage.

Making life easier with rx_widgets

Using StreamBuilder is one way to react to AppModel events but it makes the Widget tree a bit messy and because I’m also lazy I wrote the rx_widgets package which contain convenience function to work with Streams, Observables and RxCommands.

You can pass an Observable at any place a Stream can be used because Observables extends the Stream interface

Currently it contains this classes:

RxSpinner a platform aware busy spinner that takes a Stream and builds a running Spinner on trueand on false and alternative Widget.

With this the code from above would look like:

new RxSpinner(busyEvents: TheViewModel.of(context).updateWeatherCommand.isExecuting,
                platform: TargetPlatform.android,
                radius: 20.0,
                normal: new WeatherListView(),) 

As we want to take care of errors and empty data events too now there is also an extended version that takes directly an RxCommand and offers three builders:

RxLoader<List<WeatherEntry>>(
        spinnerKey: AppKeys.loadingSpinner,
        radius: 25.0,
        commandResults: ModelProvider.of(context).updateWeatherCommand,
        dataBuilder: (context, data) => WeatherListView(data ,key: AppKeys.weatherList),
        placeHolderBuilder: (context) => Center(key: AppKeys.loaderPlaceHolder, child: Text("No Data")),
        errorBuilder: (context, ex) => Center(key: AppKeys.loaderError, child: Text("Error: ${ex.toString()}")),
        ),

WidgetSelector builds one of two provided Widgets depending on the bool value the provided Stream emits. In our app I use it to enable/disable the update Buttton based on the updateWeatherCommand.canExecute Observable.

In homepage.dart:

new Expanded(
    child: 
    WidgetSelector(
        buildEvents: ModelProvider.of(context).updateWeatherCommand.canExecute,   //We access our ViewModel through the inherited Widget
        onTrue:  RaisedButton(    
                        key: AppKeys.updateButtonEnabled,                           
                        child: Text("Update"), 
                        onPressed: ()  
                            {
                                _controller.clear();
                                ModelProvider.of(context).updateWeatherCommand();
                            }
                    ),
        onFalse:  RaisedButton(                               
                        key: AppKeys.updateButtonDisabled,                           
                        child: Text("Please Wait"), 
                        onPressed: null,
                        ),
    ),
),

More reactive widget goodies to come soon. If you have an idea for a great RxWidget just open an issue or even better make a PR.

Conclusion

Thanks to Brian Egan our App now looks like this:

App_Step_3

By using Streamsor even better RxDart’s Observables in combination with StreamBuilder and RxCommands and rx_widgets can make your App truly reactive.

If you got hooked on the idea of streams of events, vote for this Flutter issue to make Flutter use Dart Streams for notifications.

Flutter – The new kid on the block

In this post I will have a closer look at Google’s new mobile framework Flutter and compare it to my previous experience with Xamarin forms. This is not a tutorial but more an overview to get you started

A typical day with Xamarin

As most of you know I really like Xamarin Forms. After a break of halve a year I got back to mobile. First thing was updating Visual Studio with Xamarin. When trying to build my App which built fine the last time I was working on it I got a whole bunch of errors. After 3 hours fiddling with the toolchain I was able to build again.
Pretty frustrated because I had hoped that things had improved with Xamarin in the meantime I read that Google just announced the official beta release of its new cross platform mobile framework Flutter. So I decided to have a closer look at it.

What is Flutter

Flutter is not only a framework, it’s actually a whole tool chain for building native Apps for Android and iOS.

  • Flutter promises real write once run everywhere including the UI
  • Flutter doesn’t use any OS UI controls but paints everything with Skia
  • Flutter provides Widgets that exactly mimic the look of Material and iOS Controls
  • Flutter‘s core is written in C++ so it’s really fast
  • You write Flutter programs using the language Dart which is AOT compiled into native code
  • It offers an instant reload function so that you can see any change you make to the App in moments on your device/emulator while the app’s state is preserved
  • You program your UI not in some mark-up language like XAML but completely in code which sounds more cumbersome than it is as we will see.

Taking it to a test

Installation

Following the instruction on the Flutter.io page installation on Windows is pretty straight forward. I only had a complain about some Android SDK licences which could be fixed by creating a blank App in latest Android studio. Additionally I installed Dart Code the Dart and Flutter plugin for VS Studio Code.

If you install on Mac it can be a bit more work, so had I to upgrade to Mac OX High Sierra and also to update several tools which was ok because the Flutter installer tells you what is missing and how to install.

It just works

Opening the first sample and hit F5 in VS code and the app was build deployed and started without any problems. I was really surprised because I was no longer used to something like that.

One thing I should mention: when building for iOS you have to work on your Mac, you cannot remote build like with Xamarin

Let’s write our own first Flutter program

I decided to port a small App that I did before in Xamarin forms. You can find the code here:

Into the Dar(k)t ages

Coming from C# I was surprised how easy it is to get accustomed with Dart the syntax is not so much different and on the Dart website you find all you need. I will point out interesting features of Dart when we get to code.

A Flutter Project

FlutterProjectStructure

This is a typical project structure of a Dart project. All your source files including main.dartare located in the lib folder. For now the only other interesting file is the pubspec.yaml where you register all packages that your project needs as well as all assets. Be careful, yaml files are very picky when you don’t follow the correct indentation.

Widgets all around

Our goal is an UI like this:

mainscreen

Flutter builds it’s UI completely through composition of Widgets that can again contain Widgets.
Yes, in Flutter everything is a Widget, even the App itself. As already mentioned the UI is completely build in code but compared with building a Page in Xamarin Forms this is very straight forward and with a little practice as good readable as a Xaml page.

Every widget has a build method that is responsible to create it’s own subtree of widgets:

class HomePage extends StatelessWidget
 {
  @override
  Widget build(BuildContext context) {
      return 
         new Scaffold(  // A material control with an Appbar and a body
            appBar: new AppBar(title: new Text("WeatherDemo")),
            body: 
              new Column(children: <Widget>
              [
               new Padding(padding: const EdgeInsets.all(5.0),child: 
                      new TextField(
                              autocorrect: false,
                              decoration: new InputDecoration(
                                                  hintText: "Filter cities",
                                                  hintStyle: new TextStyle(color: new Color.fromARGB(150, 0, 0, 0)),
                                                  ),
                              style: new TextStyle(
                                            fontSize: 20.0,
                                            color: new Color.fromARGB(255, 0, 0, 0)),
                              onChanged: TheViewModel.of(context).OnFilerEntryChanged,),
                ),//Padding

                new Expanded( child: 
                      new WeatherListView(),  // Have to wrap the ListView into an Expanded otherwise the Column throws an exception
                    ),//Expanded

                new Padding(padding: const EdgeInsets.all(8.0),child: 
                      new MaterialButton(                               
                              child: 
                                new Text("Update"), // Watch the Button is again a composition
                              color: new Color.fromARGB(255, 33, 150, 243),
                              textColor: new Color.fromARGB(255, 255, 255, 255),
                              onPressed: TheViewModel.of(context).update
                              ),
                ), // Padding

              ],
            ),//Column
          );//Scaffold
  }

So our page is basically made of a Scaffold container with a Column which contains three “rows”: A TextField, a ListView and a Button. The ListView was moved to its own Class so that the structure keeps readable.

As you see this is pretty straight forward. Decomposition in custom classes or just in a function is faster done than creating a custom view in Xamarin Forms.
Another advantage in using code to create your UI is that you can use code to dynamically create elements.

With Dart 2 it won’t even be necessary to use new because the compiler will infer it automatically so that UI code looks nicer.

You may have wonder what this TheViewModel.of(context).update is. That’s Flutter‘s way of providing a DataContext to the Widgets. For this you have to create an InheritedWidget that’s only function is to propagate data down the widget tree from where it is placed in the tree. In this App I placed one at the very root of the tree so that all Widgets have access to my ViewModel.

Flutter Widgets are in principle stateless which means you cannot store any data in it as they will completely (not completely true) new created when refreshing the screen. One consequence is that we don’t have permanent bindings between View and ViewModel that update automatically.

When I wrote in principle stateless this was not completely true. Besides the StatelessWidget above there are StatefullWidgets too that are made of a Widget and a State object. This State object is persistent during rebuilds of the UI and can so store information and subscribe to event handlers of view models.

Building the ListView

 WeatherListView();
    @override
    Widget build(BuildContext context) {
      return new StreamBuilder<List<WeatherEntry>>(   // Streambuilder rebuilds its subtree on every item the stream issues
              stream: TheViewModel.of(context).newWeatherEvents,   //We access our ViewModel through the inherited Widget
              builder: (BuildContext context, AsyncSnapshot<List<WeatherEntry>> snapshot)  // in Dart Lambdas with body don't use =>
                  {
                    // only if we get data
                    if (snapshot.hasData && snapshot.data.length > 0)
                    {
                        return new ListView.builder(
                                    itemCount: snapshot.data.length,
                                    itemBuilder : (BuildContext context, int index) => 
                                                      buildRow(context,index,snapshot.data)                                            
                                );//ListView
                    }
                    else
                    {
                      return new Text("No items");
                    }
                } // Builder function                                              
              );//Streambuilder

    }            

StreamBuilder is a nice Widget which will execute a builder method that rebuilds its widget subtree each time a new item is issued by a given Stream which allows a reactive design of your app. There is even a Dart version of Reactive Extensions that builds on top of Dart Streams.

This means every time the ViewModel pushes new data into the other side of the Stream the ListView will be recreated.

All collection widgets in Flutter exist in two versions. One that takes a predefined List of Items and a builder version that calls a handler every time it needs the data for a new row it wants to display which allows easy data virtualisation.

Moving the creation of the individual Rows into a separate function makes it again more maintainable:

Widget buildRow(BuildContext context, int index, List<WeatherEntry> listData) {
    return 
    new GestureDetector(
        child: 
            new Wrap(spacing: 40.0,
                children: <Widget>
                [
                    new Image(image: new NetworkImage(listData[index].iconURL)),

                    new Text(listData[index].cityName, style: new TextStyle(fontSize: 20.0))
                ],
                ),

        onTap: () => Navigator.push(context, 
                        new MaterialPageRoute( builder: (BuildContext context) => new DetailPage(listData[index])
                ))
    );

I hope this gives you a very first impression how UIs are build in Flutter

Conclusion

Having worked now for three weeks with Flutter I can say

Pros

  • Reliable Tool Chain
  • Designing in Code together with the instant reload is really fun and fast. Refactoring of widgets like decomposing into smaller units is just a cut and paste in a new file. Debugging is easier too because you have no symbolic bindings.
  • Exactly same look of your App on Android and iOS if you want. Soon automatic usage of platform like looking widgets will be available
  • No need for CustomRenders if you want to achieve more ambitious look and feel
  • A really huge and powerful library of Widgets that can be composed endlessly
  • Virtualized CollectionViews
  • Animations are very very easy. And they look on all platform the same.
  • Compared to a mark-up based framework the learning curve seems not as steep but this might come from my experience with Xamarin.
  • Non UI code of the app can be shared with web versions of it.
  • Fast build time
  • Very fast start-up time in release mode <2s
  • Runs as native compiled code
  • Very good API docs, examples and tutorial videos.

Cons

  • You cannot access native APIs directly from Dart. For that you have to write a plugin in either Java and Swift/Objective-C that communicates with your App through message channels
  • Currently not all device functions are available as plugins
  • The package library of Dart is nothing compared to the nuget universe
  • Currently no packages to use Azure, Firebase is there but who would have expect differently
  • Dart doesn’t support reflection which is good for performance but make a lot of tasks tedious. For instance there is nothing compared to json.net or refit luckily for JSON there is a generator library that creates serialize and deserialize code for your classes.
  • Currently there are no established application frameworks like MvvmCross or similar. Overall there are only little resources on App architecture at the moment.
  • No remote building for iOS from a PC

Overall my subjective impression is that I’m much faster in creating appealing pages than in Xamarin Forms. It feels a bit more raw the way you code but also with more control because not so much happens automagically in the background.

Currently there is a huge hype around Flutter (20.000 stars on github) and if Google really launches Fuchsia it will be the default framework there. Which lets hope that missing plugins will soon be available.
On the other side it’s still in beta and nobody know if Google may kill it before release.

My main reason for continuing with it is that I don’t get continuously frustrated by the toolchain and the fast build times.

I can only recommend give it a try and see for yourself. Especially try the Flutter Gallery sample in the Flutter repo.

More information on [fluttering] (https://flutter.io)

On Gitter: gitter.im/flutter/flutter

Let me know what else do you want to know about Flutter!

The Xamarin Project Mystery

In this post I will try to clear up some missconceptions about the Xamarin Forms project structure, have a closer look at the differences between PCL and Shared Projects and explain some tricks that you can do with both of them.

First there was confusion

I recall when I started with Xamarin the wizard created solution looked pretty alien to me. At this time I started with a PCL based solution because that’s what was recommended everywhere. We’ll have closer look ate this later in this post

pcl_project_structure

There was a (portable) subproject and one with .Android and one with .iOS extension. After reading some docs I understood that the PCL part is a platform independent library and in the other two are the platform specific code. Still I did not understand how are these projects connected to each other. I got further confused reading that I cannot call any platform specific code from the PCL project unless I use the Xamarin Dependency Service

This left the feeling that there must be some black magic going on under the hood that brings all together which left me a bit uncomfortable but it seemed to work somehow.

No Magic in here

The most confusing part was that all my Apps important code like the App class and all my pages were in the PCL project. So I thought that’s the project that will generate the final App and that the other two just get linked somehow.

What I did learn while already happy coding was that the .Android and .iOS projects are the so called Platform Projects which will result in our final App when compiled and linked. This projects will just link in the PCL part which just a dll, that’s all to it. So in reality it was exaclty the oposite that I first thought.

PCL_project_schema

This has some interesting consequences. Although code in the PCL cannot access code inside the platform projects the other way round is indeed possible.

This suddenly also explained how the DependencyService could work. It’s code is located in the Xamarin Forms (XF) library which is a PCL itself and which is referenced from our PCL project and from the Platform Project which makes it possible for the Platform Project to register instances of platform dependent classes inside the XF code which then can be retrieved via it’s platform independent interface from inside our PCL project.

We don’t need magical attributes and Services

to access platform specific code. All it takes is a static property in a class in our PCL project and a platform independent interface like

public interface IFileStorage
{       
    string ReadAsString(string filename);
    byte[] ReadAsBytes(string filename);
}

In each of the Platform projects we implement this interface with a platform specific implementation.

Android:

namespace XamarinSampleSolutionPCL.Droid
{
    public class FileStorage : IFileStorage
    {
        public string ReadAsString(string filename)
        {
            var bytes = ReadAsBytes(filename);
            return Encoding.UTF8.GetString(bytes);
        }

        public byte[] ReadAsBytes(string filename)
        {
            AssetManager assets = Android.App.Application.Context.Assets;
            using (Stream stream = assets.Open(filename))
            {
                using (var memStream = new MemoryStream())
                {
                    stream.CopyTo(memStream);
                    return memStream.ToArray();
                }
            }
        }

    }
}

iOS

namespace XamarinSampleSolutionPCL.iOS
{
    public class FileStorage : IFileStorage
    {
        public byte[] ReadAsBytes(string filename)
        {
            var data = File.ReadAllBytes(filename);

            return data;
        }

        public string ReadAsString(string filename)
        {
            var data = ReadAsBytes(filename);

            if (data == null)
                return string.Empty;

            return System.Text.Encoding.UTF8.GetString(data);
        }

    }
}

In our App class in the PCL Project I added a static property:

namespace XamarinSampleSolutionPCL
{
    public partial class App : Application
    {
        public static IFileStorage FileStorage;

To make everything working together we have to create an instance of the platform specific classes and assign it to this static property and we can use it inside the PCL over this static property.

Here is the example how to do it in Android:

protected override void OnCreate(Bundle bundle)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(bundle);

    global::Xamarin.Forms.Forms.Init(this, bundle);

>>  App.FileStorage = new FileStorage(); // Thats the interesting line

    LoadApplication(new App());
}

I don’t say that this is an optimal solution! But it should give you a better understanding of how this projects play together. Using a ServiceLocator like the XF DependencyService has the advantage that your PCL code does not use a static property of any of your classes and you can access the instance from anywhere in your code. If you want to use a ServiceLocator I personally prefer Splat which gives you much better control and does work without magical class attributes.

What are these other files for?

This might seem trivial for some of you but from my experiences in the Xamarin Slack not everyone knows. Stay tuned we will get more interesting stuff in a minute.

  • package.config: nuget packages that you add to your project are stored in here. But don’t think you can just edit it to add or remove packets because they are also referenced in your .csproj files. So always use the nuget Manager or the console

In the PCL

  • App.xaml and App.xaml.cs: if you have read my previous post (if not do it now) you know that the combination of .xaml and .xaml.cs just creates a class. In this case your Appclass which has the responsibility to create your first page in it’s constructor. Although it has a .xaml part this is not a page. In the .xaml part you can define global styles and the like. If I don’t need the xaml part I often replace this combination with a simple App.cs class like
public class App : Application
{
    public static IFileStorage FileStorage;

    public App()
    {
        InitializeComponent();

        MainPage = new XamarinSampleSolutionPCL.MainPage();
    }

    protected override void OnStart()
    {
        // Handle when your app starts
    }

    protected override void OnSleep()
    {
        // Handle when your app sleeps
    }

    protected override void OnResume()
    {
        // Handle when your app resumes
    }
}

In the Android project:

  • MainActivity.cs: OnCreateis the first method that is called when your App starts up. So all platform specific initialization should go there.

In the iOS project:

  • AppDelegate.cs: here FinishedLaunchingis the first Method to get called when our App starts up.

Shared Projects, the black sheep of the family

If you ask in the community which one of the two you should choose you almost for certainly will hear Shared Projects are bad which actually almost got to some sort of dogma.

But first what are Shared Projects anyway? So lets have a look what the structure of a shared project looks like:

shared_project_structure

Looks pretty similar but what’s that strange symbol:

shared_part_symbol

This is actually a pseudo project which means it’s not a real project at all but a trick of Visual Studio (That’s the reason why you cannot add a nuget to it).

All files that you add to this “project” will be added to all platform projects at the same time by using file links.

shared_project_shema

I left out the link step intentionally

So if all files get compiled to the same binary this means that all files could access platform specific code. But to be able to compile the files in the shared part in both platform projects they should not do that because what knows an iOS compiler about Android APIs.

The idea is that you only put classes in the shared part that don’t use any platform specific code.

But (and here comes the critique of the people that think shared projects are bad) you can use #if __ANDROID__ and #if __IOS__ in the shared part to still use platform dependent code which makes a mess of your code and is bad style.

That you can do this does not means you have to or you should do and doesn’t make Shared Projects bad. Although it somehow comforts me to know that I have this possibility as last resort 🙂 .

As long as you follow this rule there is really nothing bad about Shared Projects and fact is the core App code will seldom reused in another project.

Put all code you want to reuse somewhere else in a separate PCL project and reference that from the Platform Projects and you are fine.

Advantages of Shared Projects

If you ever used a PCL project you will earlier or later have encountered the moment where a nuget that you want to use does not match the PCL profile of your PCL project which is pretty annoying especially because you cannot change your PCL profile without uninstalling all nugets first. Even worse as more and mode nugets are migrated to netstandardthe successor to PCL you will get more conflicts.

A shared project can consume any nuget independent from it’s PCL profile. So for now I actually recommend Shared Projects if you start a new one. This might change when netstandard tooling gets more mature and with the release of netstandard 2.0.

Accessing Platform code from the shared part of Shared Project

As we should not use #if what else can we do. Actually you have two possibilities.

  1. You still can use a ServiceLocator like Splat and register your platform specific interface implementations in the Platform project classes and access them via the interface and the Locator in the Shared part.

  2. You can use partial classes what someone called the poor man’s bait and switch. This makes especially sense if the class contains platform independent and dependent code.

Let’s implement the same service as in the PCL Solution in the Shared project:

In the Shared Part we add a file named FileStorage.cs

    public partial class FileStorage
    {

        // This is a stupid example for a platform independent method
        string ReadUpperString(string filename)
        {
            return ReadAsString(filename).ToUpper();
        }

        string ReadAsString(string filename)
        {
            return ReadAsStringImplementation(filename);
        }

        byte[] ReadAsBytes(string filename)
        {
            return ReadAsBytesImplementation(filename);
        }

    }

In the Android Part we add a file named FileStorage.Android.cs

Please note that we cannot use the same file name

public partial class FileStorage 
{
    public string ReadAsStringImplementation(string filename)
    {
        var bytes = ReadAsBytes(filename);
        return Encoding.UTF8.GetString(bytes);
    }

    public byte[] ReadAsBytesImplementation(string filename)
    {
        AssetManager assets = Android.App.Application.Context.Assets;
        using (Stream stream = assets.Open(filename))
        {
            using (var memStream = new MemoryStream())
            {
                stream.CopyTo(memStream);
                return memStream.ToArray();
            }
        }
    }

}

This part can fully access the Android APIs

And in iOS:

public partial class FileStorage
{
    public byte[] ReadAsBytesImplementation(string filename)
    {
        var data = File.ReadAllBytes(filename);

        return data;
    }

    public string ReadAsStringImplementation(string filename)
    {
        var data = ReadAsBytes(filename);

        if (data == null)
            return string.Empty;

        return System.Text.Encoding.UTF8.GetString(data);
    }

Our Solution now looks like this:

shared_project_structure_partial_class

You can find both solutions on my Github Repository:

PCL Solution

Shared Solution

The secret life of a Xaml Page

Disclaimer: Post describes Xaml Pages used in Xamarin Forms

If you are like me the first time when confronted with a Xaml page they look sort of really alien to an old school programmer who has never did dirty web stuff before.
After reading some articles about using them you finally grasp what you can do with them but still there is a sort of magic around them or at least if feels like a strange sort of animal that you have learned how to ride following all the examples but still you are not really sure what it really is and how does it work and if you can trust it.

Xaml Pages are just classes

OK not completely true but at least partial (pun intended). They are one part of a page class, the other one is normally declared in your xxx.xaml.cs file. Visual Studio only knows that they belong together and displays them linked together so that they look like some special thing.

If you have a Xaml Page like

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FormsTest.Pages.BasicPage">
  <Label Text="Hello Forms" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

with it’s counterpart

using Xamarin.Forms;

namespace FormsTest.Pages
{
    public partial class BasicPage : ContentPage
    {
        public BasicPage()
        {
            InitializeComponent();
        }
    }
}

it is basiscally the same as if you write in code:

class BasicCodePage : ContentPage
{
    public BasicCodePage()
    {
        Content = new Label() {Text = "Hello Forms", HorizontalOptions = LayoutOptions.Center,
                                VerticalOptions = LayoutOptions.Center};
    }
}

The most important part in the Xaml header x:Class="FormsTest.Pages.BasicPage" tells the compiler to which partial c# class this Xaml belongs.

The magical part

How does this work? Basically your Xaml definitions get included in your assembly as embedded resource. When creating an instance of the page Forms parses the Xaml and instantiates the there defined classes like <Label>, <Grid>, <ScrollView> any set attributes get assigned to the same named properties of this classes.

You can see it yourself checking the objfolder of you project where you find temporary generated files of your pages like:

    public partial class BasicPage : global::Xamarin.Forms.ContentPage {

        [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
        private void InitializeComponent() {
            this.LoadFromXaml(typeof(BasicPage));
        }
    }

InitializeComponent();

If you look at the constructor of the partial class you find a generated call of InitializeComponent. This call instantiates and initializes all of the objects defined in the XAML file, connects them together in parent-child relationships, attaches event handlers defined in code to events set in the Xaml file, and sets the resultant tree of objects as the content of the page.
Taking this into account it now get’s clear why you NEVER EVER SHOULD TRY TO ACCESS ANY CONTROL of your page before this call because they just don’t exist at this point and you will get an exception.

Quite often you will get compiler errors that tells you that InitializeComponentdoes not exist. Looking at your partial C# class we have to admit that indeed there is no such method. So it must be defined somewhere in the from Forms generated second half of our page class. So if you get this kind of error in most cases the link between the code-behind file (how your partial class is often been called) and the Xaml definition is broken. You first stop is therefore checking the x:classdefinition in your Xaml header if the name there matches the class name of your c# class.
Another reason can be that VS or XS did not set the correct build tool for the Xaml page. Checking the Xaml files properties Custom Tool should be set to MSBuild:UpdateDesignTimeXaml and Build Action to `Embedded Resource.

Named Controls

In a lot of tutorials you see that the code is accessing the controls of the page just by there name which was set with the x:name attribute on the Xaml control.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pages="clr-namespace:FormsTest.Pages;assembly=FormsTest"
             x:Class="FormsTest.Pages.BasicPage">

  <Label x:Name="MyLabel" Text="Hello Forms" VerticalOptions="Start" HorizontalOptions="Center" />
</ContentPage>

How does this work? The answer is that the Xamarin compiler will create a field for every named element in your Xaml definition inside your Page class. This is the code the compiler generates for the Xaml page:

    public partial class BasicPage : global::Xamarin.Forms.ContentPage {

        [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
        private global::Xamarin.Forms.Label MyLabel;

        [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
        private void InitializeComponent() {
            this.LoadFromXaml(typeof(BasicPage));
            MyLabel = this.FindByName<global::Xamarin.Forms.Label>("MyLabel");
        }
    }

If you want to dig deeper into this please check out: Anatomy_of_a_XAML_Class

Custom Controls

Recalling that

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FormsTest.Pages.BasicPage">
  <Label Text="Hello Forms" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

The <Label> directive instantiates an Object of the class Label you could get the idea if it would be possible to use any class inside Xaml. And actually you can. Ok, not any class everywhere but you can use any from `VisualElement derived class as controls. So if you need a custom controls, you can just derive your class from an existing control and use it on your page.

E.g. if we want to have an control that capitalizes every input we could do this like so:

class CapitalEntry : Entry
{
    public CapitalEntry()
    {
        TextChanged += CapitalEntry_TextChanged;   
    }

    private void CapitalEntry_TextChanged(object sender, TextChangedEventArgs e)
    {
        Text =   e.NewTextValue.ToUpper();
    }
}

This might be a pretty naive solution but works for this example.

and use it in our Page just like this:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pages="clr-namespace:FormsTest.Pages;assembly=FormsTest"
             x:Class="FormsTest.Pages.BasicPage">
  <StackLayout>

    <Label Text="Hello Forms" VerticalOptions="Start" HorizontalOptions="Center" />

    <pages:CapitalEntry VerticalOptions= "Start"/>

  </StackLayout>
</ContentPage>

The only thing to be able to use our own classes is to tell forms in which assembly they are to find. That’s why we need this line

 xmlns:pages="clr-namespace:FormsTest.Pages;assembly=FormsTest"

It defines Xaml namespace so that we now can reference classes from external assemblies. You only need “assembly=XXXX” if the control is in a different assembly to the page you’re referencing it from.

This also means that you can easily reuse parts of your page by defining them as separate classes and use that in your pages.
When doing this and define your “page parts” as ContentView or ViewCell derived classes you can define them in Xaml too and get even more flexibility because you can let it handle their own events in their own code-behind files to create more complex self contained custom controls.

Now I moved the content of the previous Page to a custom View class:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pages="clr-namespace:FormsTest.Pages;assembly=FormsTest"
             x:Class="FormsTest.Pages.PagePartView">
  <ContentView.Content>
    <StackLayout>

      <Label Text="Hello Forms" VerticalOptions="Start" HorizontalOptions="Center" />

      <pages:CapitalEntry x:Name="capitalEntry" VerticalOptions= "Start" TextChanged="Entry_OnTextChanged"/>

    </StackLayout> 
  </ContentView.Content>
</ContentView>

with it’s own code-behind file:

namespace FormsTest.Pages
{
    public partial class PagePartView : ContentView
    {
        public int MaxLength { get; set; } //Will be accessible as Xaml Attribute

        public PagePartView()
        {
            InitializeComponent();
        }

        //Limit the entry to MaxLength characters 
        private void Entry_OnTextChanged(object sender, TextChangedEventArgs e)
        {
            if (e.NewTextValue.Length > MaxLength)
                capitalEntry.Text = e.OldTextValue;
        }
    }
}

Then we can use it in our page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pages="clr-namespace:FormsTest.Pages;assembly=FormsTest"
             x:Class="FormsTest.Pages.BasicPage">

  <pages:PagePartView MaxLength="10"/>

</ContentPage>

As you see we can pass values to properties of our custom view as Xaml attributes.

Deriving Pages

You can derive Pages but with some limitations.

  • It’s possible to derive a Xaml Page from a Page defined in code that does not create any controls but only provides other functionality.
  • You can derive a code defined Page from a Xaml defined page that can access the Xaml defined controls of it’s parent page.
  • You cannot derive a Xaml defined Page from another Xaml defined page (unless they only define resources and no content)

If you want to derive a Xaml page from some outside defined base page the definition looks a bit strange as you have to use the base classes namespace before it is even declared:

Here an example that derives from ReactiveContentPage defines in the ReactiveUI library package.

<?xml version="1.0" encoding="utf-8" ?>
<rxui:ReactiveContentPage x:TypeArguments="pageModels:SettingsFilerPageModel" xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
             xmlns:pageModels="clr-namespace:FormsTest.PageModels;assembly=FormsTest"
             x:Class="FormsTest.SettingsFilterPage" BackgroundColor="Black">

This example is even more interesting because it shows that it’s possible to derive a Xaml Page from a generic base class. The generic type parameter is passed by using the x:TypeArgumentsdeclaration.

Why can’t I bind my Xaml Controls to Properties of my Page class?

A lot of developers when starting using MVVM as design principle try to bind attributes or command of their controls in the Xaml definition to properties defined in the code-behind file of the page and are surprised that this doesn’t work.

Besides that it makes no sense at all to bind to elements of your code-behind file, the reason is that the {Binding}
markup extension tries to make link between the Attribute it is set with an object assigned to the BindingContextproperty of the Page class and not to the Page itself.
Now you could get the idea and assign this.BindingContext = this inside the constructor of the page, but it really makes no sense if you recall that the compiler fuses the Xaml Definition together with the code-behind file to one single class. Binding inside one class does not make any sense at all.
If you want want access your pages controls just give them names with the x:name attribute and access them directly. And if you want to handle events in the code behind, don’t try to use commands, just use the Xaml exposed events.

Should I use the code-behind file at all?

Many MVVM purists will tell you that your code-behind files should only contain the InitializeComponentcall and nothing else.
I’m not that dogmatic. Actually if you are not using the Xamarin Forms bindings you might need to define bindings manually inside the constructor.
Second if we are talking about custom views it might not make sense to bind that to a ViewModel if it acts as a self-contained control. Think of a complex DateView that only exposes a property selected date but handles user interaction inside. This could be completly handled in the code-behind file. Another example is if you have to change some components dimensions based on the physical screen size. It makes much more sense to do this after the ‘InitializeComponent` call in the pages constructor than with a binding from the ViewModel because screen dimensions are something inherently connected to the View and not to the ViewModel.
As so often the answer is it depends 🙂

XamlCompile

You have seen before that Xaml pages are added as Resources and parsed at runtime, so many of you might have thought if this isn’t a bit slow. And indeed it is. Luckily there is a way out of it you can tell Xamarin to compile your Xaml classes directly into IL by simply setting an attribute on your class or on your whole assembly. As I don’t want to just copy the offical documentation, you can find here how to use Xaml Compilation

Advanced ListView Bindings

The traditional Binding

When first making contact with ListViews in an Xamarin Forms MVVM design you usually publish an ObservableCollection as a property of the ViewModel of your Page, bind the ItemSource of the ListView to it and then bind to the items in´the collection in your Datatemplate. Like this:

    [ImplementPropertyChanged]  //I use Fody here to not have to bother with INotifyPropertyChanged
    public class DemoListViewPageModel
    {
        public ObservableCollection<Dog> DogList

        public DemoListViewPageModel()
        {
            DogList = new ObservableCollection<Dog>();

            DogList.Add(new Dog() { Name = "Rex", Race = "German Sheppard" });
            DogList.Add(new Dog() { Name = "Barney", Race = "Poodle" });
            DogList.Add(new Dog() { Name = "Jimmy", Race = "Beagle" });
            DogList.Add(new Dog() { Name = "Rob", Race = "Labrador" });
        }
    }

    // Should be something that makes a bit of sense, so why not dogs
    [ImplementPropertyChanged]
    public class Dogs
    {
        public string Name {get; set}

        public string Race {get; set;}
    }

And in the Page then

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Examples.DemoListViewPage">
  <ContentPage.Content>
    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="Center">
      <ListView ItemsSource="{Binding DogList}" HasUnevenRows="True">
        <ListView.ItemTemplate>
          <DataTemplate>         
            <ViewCell>
              <StackLayout HorizontalOptions="Start" >
                <Label x:Name="Name"  Text="{Binding Name}"  TextColor="Navy" FontSize="20"/>
                <Label x:Name="Race" Text="{Binding Race}"/>
              </StackLayout>
            </ViewCell>           
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

That’s fine but

  • It violates MVVM in exposing the model behind it because the DataTemplate binds to model objects
  • The moment we want to store additional data for each item or execute a command from an ViewCell it get’s difficult

While the first might seem be an academic reason it really couples the model tightly to the view which makes changes in the model layer propagate to the view.

Let me elaborate on the second drawback.

  • Imagine we add a check mark (let’s asume we have such a control) to the ViewCell. Now we have to keep track of it’s state somewhere. We could bind its Toggle command to a Command in our ViewModel and also add a List<bool> checkedItems where we store the state for each item in the ListView.
  • We want to add a Add to Shopping Cart Button to our ViewCell. Again we could bind all Buttons of the ListView to a Command in our ViewModel that calls a WebService to add the item to the shopping cart. (Ok this example might be somewhat contrived)

Both both enhancements need additional code in the ViewModel to figure out which item the Command should be exceuted on which should not be the job of the ViewModel. The real reason for the problem is that our ViewModel is the ViewModel for the whole Page. The ListView is a container that holds a list of ItemViews that are defined in the DataTemplateof the ListView. So the consequence should be: Give each ItemView its own ViewModel. Which means our page’s ViewModel no longer exposes a ObservableColletion<Dogs> but ObservableColletion<DogsItemViewModel>

Introducing ViewModels for each ListView item

public class DogsItemViewModel
{
    private Dog DogObject;
    ICommand AddToCartCommand;

    public DogsItemViewModel(Dog theDog)
    {
        DogObject = theDog;
        AddToCartCommand = new Xamarin.Forms.Command(AddToCart);
    }

    public string Name => DogObject.Name;
    public string Race => DogObject.Race.ToUpper();
    public bool IsChecked { get; set; }

    void AddToCart()
    {
        WebService.Instance.AddToCart(DogObject);  // Whatever this will do ;-) 
    }
}

Now the DogsItemViewModel can handle all interaction with the ItemView on it’s own. You can even do conversions on the model data without the need to write an ValueConverter like I did with the Race property.

Now we refactor our ViewCell and make it a custom class. From it’s code behind file you can now even access it’s elements using x:Name

<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             x:Class="YourNameSpace.DogItemView">


  <StackLayout HorizontalOptions="Start" >
    <CheckBox State = "{Binding IsChecked}" />
    <Label x:Name="Name"  Text="{Binding Name}"  TextColor="Navy" FontSize="20"/>
    <Label x:Name="Race" Text="{Binding Race}"/>
    <Button Text="Add to Cart" Command="{Binding AddToCartCommand}"/>
  </StackLayout>
</ViewCell>

and our Page like this:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Examples.DemoListViewPage">
  <ContentPage.Content>
    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="Center">
      <ListView ItemsSource="{Binding DogList}" HasUnevenRows="True">
        <ListView.ItemTemplate>
          <DataTemplate>         
            <DogItemView BindingContext = "{Binding}" />
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

Looks cool, doesn’t it?

Virtual ObservableCollection

Virtualised collection views like ListView or CarouselView are great as they generate their views on the fly based on a DataTemplate. The problem is they need a collection that contains all elements that you want to display. Sometimes this is not feasible because the collection would be too big or it would take too long to load it completely from a remote location.

After some research I found out that the ItemViews as minimum need  an object that implements IReadOnlyList<T>, INotifyCollectionChanged as Itemsource and even there they only use the [int index] and Count property. So I came up with this handy class:

using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;

namespace Helpers{
    public abstract class VirtualObservableCollection<T> : IReadOnlyList<T>, INotifyCollectionChanged
    {
        public IEnumerator<T> GetEnumerator()
        {
            throw new System.NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public int Count {
            get { return ItemCountRequest(); }
        }

        public T this[int index]
        {
            get { Debug.WriteLine("Index: {0}",index);
                 return OnDataRequest(index);
            }
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;


        public void SignalCollectionChanged()
        {
            CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        protected abstract  T OnDataRequest(int index);
        protected abstract int ItemCountRequest();


    }
}

You only have to derive your own class from it and override OnDataRequest and ItemCountRequest. OnDataRequest has to return the item that should be displayed for a given index. ItemCountRequest must return the maximum number of items that will be displayed.

 

How to Distribute Files with your App

Often we need to distribute some files together with our App like a prepopulated database, settings files, image etc. To do this there are basically three methods:

Embedded Resoures

  • Quite good for Images like icons
  • read only
  • not directly accessable for file IO
  • Can be accessed from PCL Files
  • App has to be rebuilt

https://developer.xamarin.com/guides/xamarin-forms/working-with/files/#Loading_Files_Embedded_as_Resources

As Android Assets / iOS bundled Resource

  • read only, so you have to copy them somewhere else if you want to have  write access
  • not accessible from PCL without Dependency Service
  • App has to be rebuilt
  • Has to be added to each platform project differently

 

Android
  • read only
  • not directly accessable for file

Example of reading a JSON File:

using (var reader = new StreamReader(assets.Open("SampleData.json")))
{
   var json = new JsonSerializer();
   list = (List)json.Deserialize(reader, typeof(List));
}

 

iOS
  • read only
  • directly accessible for file
using (var reader = new StreamReader(File.Open("./Samples/SampleData.json", FileMode.Open,FileAccess.Read)))
{
   var json = new JsonSerializer();
   list = (List)json.Deserialize(reader, typeof(List));
}
return list;
 The path corresponds to the Folders below the Resoures folder of your iOS project.

Download from server at first startup

IMHO the most flexible solution.

  • App does not have to be rebuilt
  • writeable
  • directly accessable for file IO
  • can also be used to update an installed App

Often people shy way from this as it seems a lot of effort especially if you have a lot of files.

Luckily I happen to have published just yesterday a class calles FileStorage which offers a needful function called PopulateDataFolderFromZipUri

public async Task PopulateDataFolderFromZipUri(string uri, 
                                               string outFolder)
which will download a ZIP file from uri and extract it to outFolder which path is relative to your app’s data directory

 

What you always wanted to know about Gorilla Player….

One of the most requested features of Xamarin Forms is a visual Xaml Editor. Sure, it would be nice, but it would never show you how your App will look on different devices. So I think the way that the developers of Gorilla Player choose is the right one. It’s not too difficult to write a Xaml Page. After some time you do a good piece by copy and modify existing code or create your own custom views for reuse.  But it’s annoying to compile and deploy your App to see even minor design changes. Here comes Gorilla player into play.

Brand logo

So what is it? Gorilla Player let’s you preview your Xaml Files in real time on multiple devices or Emulators in parallel. Any change to your Xaml files are reflected immediately on all devices.

To make this work you have to install a Player App which is available in the App Stores and the Gorilla Server App on your PC. After starting the Server App you can connect as many devices as you want to the Server by starting the Player App. If you then open a Xaml File in VS or XS it will be automatically displayed on the devices.

Tip:
If the page is not displayed try opening another file in your IDE and then switch back to the Xaml file. If this don’t help go to the Tools->Gorilla menu and disconnect / connect your IDE.  Sometimes your Player App will not connect if you click on the discovered server. In this case switch to manual to connect.

This is how it looks like previewing  the same page on iOS on the VS iOS emulator in parallel to MS Android emulator.

monkey

This sounds pretty easy, but there are some pitfalls on your way:

  • If you use custom renderers and markup extensions and resources  will not be displayed.
  • Any bindings will not work 🙁

The solution for this is using the Gorilla SDK this actually allows you to include the Gorilla client into your App and therefore access all your assemblies including renderers, markup extensions, custom page base classes and resources. Sound great, BUT getting this set up is not as easy as it sounds:

  • Biggest problem, the documentation on the Gorilla Website is not up to date. There is a more complete one on their github page
  • Registering your assemblies can be tricky

I won’t repeat the content of their SDK documentation on github here. Instead I will add some things that I found important while working with gorilla:

  • Make sure that you add all assemblies that contain renderes etc. to the gorilla.json file AND register it in your App startup code using RegisterAssembyByType with types from all assemblies that you want to use.
  • Important include also the main PCL assembly of your App
  • Gorilla recommend adding the SDK to your App project. I personally prefer to have a separate GorillaDesign solution which loads and deploys fast to your device because you will have to deploy it every time you want to add a new assembly.  When I’m satisfied with the look I will copy the Xaml back to my App project.
  • You can provide Sample Data to your databindings using a json file that is also updated in real time. When I tried this I had problems to get this working together with the SDK. What I did is adding a static item source to my Xaml file. This way you can use all your Custom classes in bindings:

staticitemsource

Important: To make this work you have to include the name space containing your custom classes to the xaml file.

  • One general tip when tweaking Xaml design is to use the BackgroundColor that almost all visual Elements and Layouts have to see which dimensions these Elements really have like this here

gorilla

If you still have problems getting Gorilla to work, drop leave a comment or mention me on Slack and I will try to update this post with more information.

 

Hello world!

Hi,

after long thoughts I decided to start a blog too. My I have two goals with this blog.

  1. Share experiences that I made while developing, perhaps saving others time making not the same mistakes
  2. Write up information that I myself always forget while developing.

I hope you will enjoy reading.

Best

Thomas

P.S.: I’m not a native speaker so please have patience with my writing. I also will not spend a lot of time polishing the design  of my posts. I hope the content will make up for it.