Sunday 21 October 2018

Flutter Mobile UI Framework

Flutter is a new mobile UI framework from Google, that allows you to create native applications on iOS and Android. At the time of writing this blog post, it's still in beta but apparently will hit 1.0 soon!

Now, I gotta say, when I first learned about Flutter, and what it was all about, I was very intrigued!

You see, Flutter is the equivalent of a game-engine but for everyday apps!! I'll let that sink in. It's got an OnDraw function just like a game engine's loop would call (they call it the build function). Under the covers it uses the C++ library Skia to draw pixels directly on the screen. And because its C++ underneath, that means Flutter is cross-platform. Needless to say, this warrants a closer look from anyone who is writing mobile applications.

I'll say it up top! - Flutter looks very cool.

Stepping back a bit, I've always thought that as C++ is the lingua franca of languages, which all systems support, could it be possible for someone to write a cross platform mobile UI framework using SDL or SFML. It was a fleeting thought of course because that's no simple undertaking. Yes, I know we already have the C++ Qt library and QML but the masses aren't exactly flocking to use it.

Then there are game-engines like Unity that can run on all platforms. Again, I have always wondered if it would be be feasible/possible to use it to write a line-of-business app? I mean, it uses C# (which is a win) and the app would run everywhere Unity runs! That's a lot of places. But again, you would have to write the GUI widgets/controls yourself. The amount of work involved would be massive!

Enter Flutter.

Turns out Google was thinking the same thing, because that's what Flutter is all about. It's written in both C++ & Dart. C++ is used for the heavy lifting and the OpenGL calls (via skia), but the core Flutter library is written in Dart. Yes, that means we will be writing Dart code to write the Widgets/Components on the screen.

Incidentally, I first came across Skia when I found SkiaSharp. Skia itself is a C++ open source 2D graphics library and is used in Chrome, Firefox, Android etc and SkiaSharp is a C# port which is used in Xamarin Forms. But I digress...

So what about the GUI elements? Well, the framework calls them Widgets and provides you with containers, buttons, Forms, List Views, Srollers, etc. It's from these foundational Widgets that you create your own custom controls.

Why dart?

Ughhh. Dart? That was my first thought... Why didn't they choose Kotlin. The last mobile app I wrote used Kotlin which is a very nice language and because it is built on the JVM means you can interface with the large set of existing Java libraries out there.

So, at first I was a little disappointed to learn that flutter uses Dart as its primary language. But you know what? After playing with Dart a bit, it's actually a pleasant language.

Now there have been some changes to Dart, since it first came out that I was not aware of. For example, when Dart 1 originally shipped it had optional typing. But thankfully Google saw the error of their ways and for Dart 2 strong mode has been adopted. As Flutter uses Dart 2, this means our code is like C# & TypeScript in that types are required or inferred. This is good news as it means you get all the benefits of static typing.

There are some weird things to get used to though. For example Dart does not have public or private keywords!! Yes, classes can't have private variables!! Coming from other languages where the keywords "public, protected & private" are the norm, these keyword omissions just seems weird to me. There are other oddities like multi-threading that I won't get into here. However, for the most part, if you're coming from JavaScript, Java or C# then Dart is a pleasant language to code in.

I still kinda think it's a shame they didn't go with a more powerful language like Kotlin, especially as JetBrains are working on Kotlin Native which would have solved the iOS side of the story. However I suspect the choice to use Dart was a political one as Google own and control Dart so there won't be any nasty surprises further down the road (cough Oracle)!

Code Sharing versus UI Sharing

Here's the really cool thing I love about Flutter. And that's the fact that the user-interface you design and write, is shared across Android and iOS. Which, when you think about it, makes sense... I mean all it is doing is spitting out the same pixels to the screen. The framework doesn't care that the screen in question just happens to be an iOS screen with a notch on the top! The frameworks game-loop is just calling its OnDraw function.

If you want the same brand theaming across iOS and Android this is great, however Flutter is also platform-aware so if you want to have apple style widget on iOS you can! The choice is yours!

When Xamarin first came out their selling point was that you wrote the business-logic once but then had to write the UI layer twice. In the early days the benefit to developers was more about the "Code Sharing" aspect of the platform rather than the "UI sharing". Of course, since then, Xamarin have introduced Forms which aims at helping developers also write the UI code once.

In comparison, it seems to me that the biggest benefit of Flutter is the "UI sharing" aspect of the framework and the code sharing is secondary. This nicely brings me on to API's...

Accessing Android & iOS APIs - Plugins!

One of the big selling points of Xamarin is that they give you access to the "full spectrum of functionality exposed by the underlying platform". Basically, any APIs you can call from a native iOS or Android app, you can call with Xamarin. It exposes all those native APIs from C#. From a developers point-of-view, you gotta say, that's pretty cool.

The Flutter folk have gone down a different path. Instead of exposing every conceivable API you could call, they allow you to write plugin packages that you can share with the community, These plugins allow you to write dart code that interfaces with a specific set of APIs. This means you can always open up the iOS or android sub-folders and write as much Obj-C/Swift or Java/Kotlin code as you like.

I think anyone who takes even a cursory glance at Flutter will agree that they have got the UI side down. But I think the crucial part of the Flutter story is going to be the interop with the native APIs. For example, if you choose Xamarin, you know the platform APIs are exposed and available for you to call from C# but with Flutter, you are either going to have to rely on the community to provide a plugin that interfaces with the APIs you want or roll up your sleeves and write the platform specific code yourself (and potentially twice).

It's going to be interesting to watch how this side of the story unfolds for Flutter.

Reactive Views & Hot Reloading

Flutter uses the same model as React for building UI. If you think about visual designers like we have had with the likes of Winforms, WPF, Android & iOS, they all focused on the visual layout of the UI alone. One thing that stood out for me straight away was that there isn't a visual designer for flutter. No XAML or XML layout editor.

With Flutter though, you write your UI directly in code! Now before you throw your teddy-bear out the pushchair, it turns out that this isn't a problem because of the fast hot-reload. Essentially the code you change is instantly reloaded in the Emulator which means you get instant feedback.

Here is the obligitory screenshot from the main Flutter website, showing the hot-reload in action:

There is also something called the Widget Inspector which is very cool. Whatever part of the screen you touch, it will tell you what class that region of the code relates to. It allows you to jump straight from the UI to the code!

Building Blocks of an App

There are lots of great articles on how to get started with Flutter, (like these ones here, here & here) but once you have got to grips with all the Widget aspects of the framework, you start to think and have questions about the other building blocks of a mobile app, like I did.

Here are some of the things I have noticed after reading up on Flutter.

Coming from C# / Java where we have great JSON libraries like Json.Net or Gson, I was a little taken aback to realise there was nothing equivalent in Dart. Also, because the official docs mention that runtime reflection is disabled in Flutter the chances of getting a library like Json.Net or Gson are slim to none! Instead, this article explains what it is like to perform JSON serialization/deserializtion in Flutter.

For network comms, the last app I wrote made use of the excellent OKHttp library. Of course, there is no equivalent in Dart. If you intend to do anything like certificate pinning you can make use of this plugin or write the plumbing code yourself.

If you want to make use of a local database, thankfully SQLite is available via the sqflite plugin. This is great write-up on how to incorporate it in your app.

If you are familiar with MVVM pattern, then this article here could be a useful read which uses the ScopedModel plugin. This allows you to automatically update the Widgets in the tree when the model is updated.

If you plan on writing an app that makes use of background notifications, then the latest beta version of Flutter now has a solution. The sample code for background execution of Dart code can be found here.

If you are looking at integrating a map in your application then using Leaflet could be an option until the Google Maps plugin is properly supported. (At the moment, it does not support iOS). There is a good write-up on how to use Leaflet here, and here. The plugin is available here.

At some point you might want to include a webview as part of the app. Yes, there is a plugin for that! This article has a good write-up here and the plugin can be found here .

Finally, I've been looking at what is available with regards to client-side encryption. If you have a need to encrypt/decrypt data using AES/SHA25 then this plugin library uses native platform implementations on both Android/iOS.

Wrapping Up

I am not sure when Flutter is going to hit 1.0. There is still over 4,000 open issues on Github so I guess there is a way to go before they iron out all the remaining severe issues, however, the framework has a lot of promise and is very exciting. Flutter is definitely one to watch!

hit counter

Contact Me:  ocean.airdrop@gmail.com

Sunday 7 October 2018

Installing RabbitMQ on Windows

I really like RabbitMQ!

If you have not come across RabbitMQ before, it's a messaging system that enables you to seperate your system out to communicate and send data between services or even other systems. If you want to ensure your system meets your reliability, scalability and performance requirements for today but also for tomorrow, then a messaging system like RabbitMQ is a great shout.

In a nutshell, RabbitMQ provides a way of architecting your system so that you can write small services that focus on one job that are scalable to meet your performance requirements.

What does that mean?

Well, when you are designing a large system, there are going to be different parts of the system that will want to communicate with each other. For example, sending commands/actions from one system to another or even just sending notifications.

So, instead of writing your traditional, monolithic application, which is just one big codebase, message queues enable you to write small services. These services are usually lightweight and focus on one job! So, for example, you could have a ProcessOrder Service and an AlarmHandler Service, etc.

But how do these services talk to each other? Well, that’s where message queues and RabbitMQ comes in.

RabbitMQ is the glue that enables asynchronous communication between each of our business layer components. At its core, RabbitMQ is a FIFO (First in, First out) message queue and its fast! - The messages are transient meaning they are not stored forever and at some point are picked up for processing. In addition to all this, RabbitMQ can guarantee that messages will be delivered to the destination no matter what happens!

Writing software this way has got lots of benefits. If one of the services is under heavy load, we can spin up extra copies of the service (even across more machines) to cope with the load (scalability). This is called horizontally scaling and means each service can scale independently of one another.

More importantly, because these services are independent from one another (and not in some monolithic application), we can alter the functionality of one service in isolation of the others knowing our change will only affect this service. This makes for a more maintainable system.

If you need to connect lots of things together, have great performance and need something which is robust and production-ready you can't go wrong. As I said, I really like RabbitMQ!

Best of all, and this is the amazing bit... it's free!

Installing RabbitMQ on Windows

RabbitMQ is available for install on both Linux and Windows. As I have recently installed RabbitMQ on a Windows system, I thought I would write up the installation process while it was still fresh! My perception is that RabbitMQ is better supported on Linux than it is on Windows and there are a couple of gotchas when installing on Windows.

Step 1 - Set Base Directory

Okay, before even installing RabbitMQ, the first thing we need to set up is the RABBITMQ_BASE environment variable. The reason for this, is by default the RabbitMQ database/queues are saved to disk on the C: drive, in the directory %APPDATA%\RabbitMQ. As I mention in this StackOveflow answer, this just seems wrong to me. So, just to make sure we have space, we set this variable up to force the database to be held on the D: drive.

Step 2 - Installation

With the RABBITMQ_BASE environment variable setup, we can now actually kick off the installer process. Now, RabbitMQ depends on Erlang which means we are going to need to install Erlang fist before RabbitMQ.

At the time of this blog post, I am downloading RabbitMQ Version 3.7.8 and this version supports Erlang 19.3.6 up to 21.0. You can find out which version of Erlang RabbitMQ supports by going here.

Once installed, you will be able to fire up the RabbitMQ Command Prompt

To confirm everything installed fine, run the status command from the RabbitMQ command line

rabbitmqctl status

Step 3 - Setup Admin User

By default, RabbitMQ comes with the guest/guest credentials. Let's first take the time to setup an administrator account. From the RabbitMQ command line run the following commands:

rabbitmqctl add_user adminuser password1
rabbitmqctl set_user_tags adminuser administrator
rabbitmqctl set_permissions -p / adminuser ".*" ".*" ".*"

You will be able to change the password from the web interface, but if you need to change the password from the command line, type:

rabbitmqctl change_password adminuser password2

Step 4 - Enable the Web Management Interface

By default RabbitMQ gets installed with everything off. Next, we need to enable the web interface.

rabbitmq-plugins enable rabbitmq_management

From the same machine you should now be able to log onto the management interface by visiting http://localhost:15672 and logging on with the admin user we previously created.

If at any point you need to disable the web interface, you can do so with the following command:

rabbitmq-plugins disable rabbitmq_management

Step 5 - Open Ports on Windows Firewall

To be able to access the management interface externally, we need to open some ports on the firewall. Run the following commands:

netsh advfirewall firewall add rule name="RabbitMQ_15672" dir=in action=allow protocol=TCP localport=15672
netsh advfirewall firewall add rule name="RabbitMQ_15672" dir=out action=allow protocol=TCP localport=15672

Whilst we are here, we also need to open port 5672 to allow clients to access RabbitMQ and add or remove work to the queues:

netsh advfirewall firewall add rule name="RabbitMQ_5672" dir=in action=allow protocol=TCP localport=5672
netsh advfirewall firewall add rule name="RabbitMQ_5672" dir=out action=allow protocol=TCP localport=5672

If you need to delete these rules at a later date, run the following command:

netsh advfirewall firewall delete rule name="RabbitMQ_5672"name protocol=TCP localport=5672

The next thing you need to do is open the management port 15672 on the Windows firewall, so that you can access the management interface from an external machine.

Step 6 - Setting up the config file

The next thing I did was to setup the config file. By default, RabbitMQ doesn't come with a config file so you will have to set one up yourself. You can find an example of the new rabbitmq.conf file here. If you read the documentation, it talks about setting up a new environment variable named RABBITMQ_CONFIG_FILE. However, it looks like there is a bug in the windows version of RabbitMQ as I could not get it to pick up the config file from this location.

So, as a work-around copy the config file to the RABBITMQ_BASE directory (which in my case is D:\RabbitMQBase).

Now, to get RabbitMQ to pick up the config file on Windows, we also need to additionally stop and restart the RabbitMQ windows service using the following rabbit commands:

rabbitmq-service stop
rabbitmq-service remove
rabbitmq-service install
rabbitmq-service start

When we then take a look at the log file after our restart, we can see that it has picked up our config file:

Now that we have the config file setup, we can specify things such as maximum memory usage and disk limits. For example, the following config setting pins the maximum memory usage to 1GB of RAM.

vm_memory_high_watermark.absolute = 1024MB

At this point, that's it! We have successfully installed RabbitMQ on our windows system!

RabbitMQ Diagnostics & Monitoring

Now, because a messaging system such as RabbitMQ is such a crucial component of the system, it would be good if we could be notified when there was a problem.

For example:

  • One of the Rabbit MQ nodes goes down
  • One of the queues stops receiving data
  • There are no consumers moving messages off a queue
  • The number of messages in a queue exceeds a certain number

That kinda thing. Thankfully, RabbitMQ has an API that allows you to query the service. In a browser, you can query the interface and get JSON data back about the service. For example:

Here is an example of the different endpoints you can programmatically call:

http://adminuser:password1@127.0.0.1:15672/api/
http://adminuser:password1@127.0.0.1:15672/api/queues
http://adminuser:password1@127.0.0.1:15672/api/queues/%2f/queue-name
http://adminuser:password1@127.0.0.1:15672/api/connections
http://adminuser:password1@127.0.0.1:15672/api/consumers

For a full list of all the available API endpoints, see this page a href="https://pulse.mozilla.org/api/">here/a>


Wrapping Up

That's it! Job done!


Contact Me:  ocean.airdrop@gmail.com

Popular Posts

Recent Posts

Unordered List

Text Widget

Pages