Monday, November 6, 2017

CodeRage XII: How to develop a simple recommender system






Tomorrow November 7th will see the 12th edition of Embarcadero's yearly online conference, called "CodeRage".

The conference, as always, respects the high quality standards:
Furthermore two guess industry luminaries will be giving sessions, Robert Martin (aka Uncle Bob) is speaking on "The Clean Coder - An Introduction to Software Professionalism" and Steven McConnell (of "Code Complete" fame) is speaking on "Managing Technical Debt".

You cannot miss it!!


You can see the full program at:  https://community.embarcadero.com/blogs/entry/coderage-xii-sessions-and-schedule.
I'm very excited because it's the first time that I will participate in the conference as speaker!
I’ll be talking at CodeRage XII about "How to develop a simple recommender system". What do Netflix, Amazon, Google and Facebook have in common? An efficient system of recommendations.
In this session I'll show how to implement a simple system of recommendations with Delphi and Redis ... in a very simple way!

Based on this work, a new product is coming to predict what you customer want! Because knowing users to propose the right product for each of them is crucial in all types of sales.
If you are interested contact me or stay tuned on bit Time Professionals.

Sunday, September 3, 2017

Delphi Entities Validators

How many of you use business objects in your applications?
How many of you use an ORM ?
In this case... how do you validate entities in your applications ?
  1. In a not very elegant way 
  2. The classic is IsValid() method on BO
  3. Something else?
  4. Validation inside or outside entities?
  5. How about different context?
Entity validation can be a tricky beast! From bit Time Professionals Lab... Delphi Entities Validators ! It is a small framework that provides an easy and ready-to-use interface for entities validation.
You can achieve Entities validation in three ways:

  1. Simple validation
  2. Attribute validation
  3. Container validation
The innovative solution of this framework is the Context: in the most case when you have to validate an Entity you have a class explosion for different situations. For example if you have to validate an entity that represents a User you have different Object classes for different context: one class for Login, one for registration etc... because the field that you have to validate are different in these different situations. With Context, the things going to get easier because you can maintain one Object Class and choose wich fields and when to validate them.
So let's go see the code!

Simple Validation

In Simple Validation mode you have to implements the IValidator interface, that use generics, replacing the placeholder with your class. The interface provides Validate method that you must implement, and here you have to write your validation logic. This method returns an IValidationResult wich is composed by:
  • IsValid - returns a boolean that represents the success or failures validation
  • BrokenRules - returns an array of string that represents the broken rules



Attributes Validation

In Attributes Validation you can use a ready-to-use attributes to validate the field of your BO (or create yours). This is first example where Context avoids you a lot of code:


In this case the affected fields are the only that have the context 'AttributesValidation'.

Container Validation

In Container Validation you can use the Simple Validation mechanism adding all the benefits of using a container and context mechanism:


Delphi Entities Validation can be a great ally in writing code, saving you time and code!

Sunday, August 27, 2017

Delphi Event Bus and MVVM

In last ITDevCon, I held a speech on how to build modern applications with Delphi. In the speech I showed what are the good programming techniques and how to reach them in Delphi. The path was completed by presenting the MVVM pattern as solution. For more info about this pattern I suggest you these books:

  1. John Kouraklis, MVVM in Delphi
  2. Syromiatnikov, A., A Journey Through the Land of Model-View-* Design Patterns.

MVVM intents is to separate the domain logic from the presentation logic in three modules with distinct responsibilities:

  • handle the domain data (Model)
  • View state and business logic (View Model) 
  • Handle user interaction and rendering of the visual user interface (View)
The hardest part ( as in any software development ) is the Separation of Concerns (SOC), to keep separate layers so future changes do not interfere with each other. High cohesion and loose coupling, precisely! 
MVVM can manage UI Synchronization in two ways:
  1. Flow synchronization
    • uses direct calls between user interface components and domain. It is based on sequential command: read user input from text box A, processing it with method B, and write the result to text label C 
  2. Observer synchronization
    • the domain layer must implement a notification mechanism to which components of the user interface layer can subscribe. This allows the user interface components to update the state of the user interface when relevant changes in the domain occur
Both solutions keep the layers separated, but the Flow synchronization forces you to write an enormity of boiler plate code and write an Observer framework from zero ( why reinvent the wheel ? ) would be expensive in terms of developments.
Delphi Event Bus comes in our help! For those that doesn't know Delphi Event Bus (for short DEB), it is a publish/subscribe Event Bus framework for the Delphi platform.
DEB is designed to decouple different parts/layers of your application while still allowing them to communicate efficiently.
Simply put the Subscribe attribute on your subscriber method you are able to receive a specific event, and by specifying the TThreadMode in attribute you can choose the context where to deliver the event.
For example, if you have to interact with the UI EventBus can deliver events in the main thread or If your subscriber does long running tasks (HTTP request), EventBus can also use background threads to avoid UI blocking. Regardless where an event was posted the EventBus will manage Thread synchronization, so you can deliver an Event in the MainThread and the subscriber will receive it on a background thread and viceversa.
Look this demo (you need DMVC for server side part) to check how I resolve UI Synchronization in client/server context with REST request in background!









Sunday, June 25, 2017

Simple retry mechanism in Delphi

Hi all,
I want to share with you a nice unit that provide a retry pattern. How many times you want to execute some code and, if that method throws an exception, you want to retry executing it several times? For example when you try to connect to a service or network resource or a database. The operation was something that failed frequently enough that it was necessary sometimes to retry until it succeeded. With this unit you enable an application to handle transient failures by transparently retrying a failed operation.
Here is the RetryHelperU:
The snippet is very simple to understand: you have to specify the number of retries, the milliseconds between each retry and a TProc that represents the operation to do.
I also added this project to my Delphi Demos repository.
I hope it will be useful!

Tuesday, April 11, 2017

Delphi and Firebase: Remote configuration

Hi all,
as you know Firebase is a backend service that include a data storage service. One of common example of this kind of service is Remote Configuration, that allows you to change the behavior or appearance of your app (ex. change the welcome message of your app) without changing the app source code.
I've just updated the Firebase4Delphi repository with a new demo : RemoteConfigDemo.
In this demo I implemented a mechanism to allow to change the behavior and appearance of your app without publishing an app update.
The process is very simple, you have to:
  1. create a JSON Object in your console project that represents the app configuration
  2. Wraps that configuration in your app
  3. Check when configuration change and communicate it to your app
In this demo you have the possibilities to change the style of your application, according to OS, at run time.

Firebase Console 

AquaGraphite.style configured at run-time
RubyGraphite.style configured at run-time




ASAP I'll post a short video to show the power of this feature.

Friday, March 24, 2017

One codebase to rule them all - RAD Studio 10.2 Tokyo is here!

Finally, it's arrived!! The penguin invasion has started! RAD Studio 10.2 Tokyo is here bringing with it support for Linux!
Delphi for Linux is now available delivering support for Linux 64bit server-side and standalone applications for Ubuntu and RedHat Enterprise. Guys, I'm very enthusiastic about this new support! This is a very greats news for Delphi developers and not, everywhere!


By now Delphi can support and generate native code for several platforms (7 to be exact!!!): Linux (64bit), Windows (x86 and x64), OS X (32-bit ), iOS (32 and 64-bit) and Android.
I think that no citation may be more appropriate of this:
one codebase to rule them all
Below a list of the most interesting features available in this release (IMHO):

Delphi Linux Compiler


  • 64-bit Linux platform support
  • Delphi language support
  • ARC-enabled
  • 1-based strings
  • LLVM engine based

Supported Linux Distributions


  • Ubuntu Server (Ubuntu 16.04 LTS)
  • RedHat Enterprise Linux (version 7)

RTL features supported


  • Linux file system access
  • Threading and Parallel Programming Libraries support
  • Memory management
  • HTTP and REST libraries support for HTTP calls

64-bit Linux for Server Applications


  • FireDAC provides Linux support for all Linux-capable DBMS, with the only exception of Informix. See Database Connectivity.
  • WebBroker, RAD Server (EMS), and DataSnap support for Multi-tier servers (standalone and Apache modules).
  • DUnitX support.
  • PAServer support.
  • Indy-based client and server support.

FireMonkey


  • New System Status Bar Options on iOS
    • Two new properties have been added to TForm for changing the behavior of the system status bar on iOS: SystemStatusBar.BackgroundColor and SystemStatusBar.Visibility.


  • Multi-Threading Support for TBitmap, TCanvas and TContext3D
  • Unification of Delphi and Java threads on Android: CallInUIThread has been deprecated. All code is now running in the Java UI Thread, removing the need for thread synchronization

Improvements for Firebird


  • New Direct property to add support for the Direct I/O backup feature.

Improvements for MySQL

  • Support for MySQL v 5.7.
  • Support for MariaDB v 5.5 or later. Use FireDAC's MySQL node to connect to MariaDB.
  • Compatibilty with the recent MySQL versions 5.6.x and 5.7.x.

Database improvements


  • VCL TDBImage direct support for JPEG and PNG graphic formats.
  • Support for display options for BlobFields.
  • Direct GUID access for TField classes.

RTL


  • HTTP Client
  • HTTP Client Library provides support for 64-bit Linux.
  • Improved async support in HTTP client
  • RTL support for 64-bit Linux
  • RAD Studio 10.2 Tokyo provides Linux file system support using standard system functions, streams, and the IOUtils unit. It also provides Standard RTL Path Functions support for 64-bit Linux.

Improved C++ packages for mobile

RAD Studio 10.2 Tokyo links C++ packages for iOS and Android statically. Previous versions of RAD Studio generated a file with the .so extension for C++ packages, but were not actually dynamic libraries. RAD Studio 10.2 Tokyo generates C++ packages with the correct file extension (.a). If you statically link against a .so package, you may need to change to link against the new filename.

RAD Server Multi-Tenancy Support

With Multi-Tenancy support, a single RAD Server instance with a single RAD Server database connection can support multiple isolated tenants. Each tenant has a unique set of RAD Server resources including Users, Groups, Installations, Edge Modules, and other data. All tenants have custom resources that are installed in the EMS Server. Also, as an administrator you can create new tenants, edit existing ones, add, edit, or delete details of your tenants, specify if the tenant is active, and delete the tenants that you do not need.

iOS 10 Simulator, device, and macOS

Full support for iOS 10, including iOS 10 32-bit and 64-bit debugging on device, Simulator support (Delphi only) and macOS Sierra support.

The news are not only these, for the complete list of all news of this release go here.

Thursday, March 2, 2017

Intercept KeyEvent on Android with Delphi

Some days ago, I had the needed to intercept the KeyDown Event on Android. In particullary the App have to respond to FormKeyDown Event. After some work I found out that there is an opened issue about this topic (https://quality.embarcadero.com/browse/RSP-10111 - vote it if you need its resolution). So I set to work to find a solution/workaround to solve my need. I studied Android SDK and Delphi internal mechanism and I found out a way to resolve it:
  • By adding a JFMXTextListener to JFMXTextEditorProxy
JFMXTextEditorProxy is an object provided by the JFMXNativeActivity (The activity for all your Android application in Delphi) and provides the method addTextListener to register a JFMXTextListener.
JFMXTextListener is an interface that supply 3 methods to manage text event:

  1.    procedure onComposingText(beginPosition: Integer; endPosition: Integer); cdecl;
  2.    procedure onSkipKeyEvent(event: JKeyEvent); cdecl;
  3.    procedure onTextUpdated(text: JCharSequence; position: Integer); cdecl;
I created a new class TCustomAndroidTextListener that implements JFMXTextListener so I can intercept the KeyEvent in these methods:

TCustomAndroidTextListener = class(TJavaLocal, JFMXTextListener)
  private
    FForm: TCommonCustomForm;
    FLastStr: string;
  protected
    function TryAsKey(const aChar: Char; var Key: Word): Boolean;
  public
    constructor Create(aForm: TCommonCustomForm);
    procedure onComposingText(beginPosition: Integer;
      endPosition: Integer); cdecl;
    procedure onSkipKeyEvent(event: JKeyEvent); cdecl;
    procedure onTextUpdated(text: JCharSequence; position: Integer); cdecl;
  end;

Now I had to add my TextListener, TCustomAndroidTextListener, to JFMXTextEditorProxy so that implemented method can be invoked when the characters are typed:

procedure RegisterTextListener(const aForm: TCommonCustomForm);
var
  FFMXTxp: JFMXTextEditorProxy;
begin
  if Assigned(FTextListener) then
    exit;
  FTextListener := TCustomAndroidTextListener.Create(aForm);
  FFMXTxp := FMX.Platform.Android.MainActivity.getTextEditorProxy;
  // the code below should be equivalent to INPUT_ALPHABET
  // FFMXTxp.setInputType(TJInputType.JavaClass.TYPE_CLASS_TEXT or
  // TJInputType.JavaClass.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD or
  // TJInputType.JavaClass.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
  FFMXTxp.setInputType(TJFMXTextEditorProxy.JavaClass.INPUT_ALPHABET);
  FFMXTxp.addTextListener(FTextListener);
end;

I created a new sample, AndroidKeyEvent, and added it to my demos repository.
In the sample, if you look the code in onTextUpdated method you can notice a solution to understand what the user is typing and propagate keydown event on the form object passed in constructor. This solution is not complete to 100% because is very hard to figure out a way to understand what user is typing if autocomplete mode is on keyboard. It seems to work fine if autocomplete is off, this is why is set the input type to TJFMXTextEditorProxy.JavaClass.INPUT_ALPHABET.
In the coming days I will continue to work on the issue to achieve a better and complete solution. In the meantime I wanted to share the code with you so if you want to contribute you can do it.

Sunday, February 19, 2017

How-To implement 2 finger pan gesture in Delphi Firemonkey

In Firemonkey, as you know, there is a great support for gestures: standard and interactive. The most important interactive gestures as Zoom, Pan, Rotate, DoubleTap (with an amazing description in dockwiki ), etc... are provided by the framework. See here for a full documentation. In a recent project I had the need to implement 2 finger pan gesture, that is not present in the provided gestures. But Firemonkey is a very great framework, and you can implement an event handler to manage custom actions when OnTouch occurs to specify what happens when a user touches the form using a finger or a similar device (not a mouse). So I wrote a little snippet of code that simulate the 2 finger pan gesture, I created a new demo and moved it into my Delphi Demos repository on Github.
I tried it on Android and works fine and very smoothly. It should works fine on all Firemonkey supported platforms: Windows, Android, iOS and OSX.