Quantcast
Channel: TMS Software
Viewing all 1008 articles
Browse latest View live

TMS iOS showcase demo app

$
0
0

In the past couple of weeks, we have done extensive work on TMS iCL, the native iOS Delphi RAD controls set and TMS Cloud Pack for iOS, the components that offer seamless access to various cloud services.

As a proof of concept, we wanted to create a showcase application for iPad that demonstrates the power of combining these two component sets with Delphi XE4. Goal of this application was to demonstrate that a 100% native iOS look and feel can be achieved combined with high performance, that Delphi RAD methodology can be used for this and that various cloud services can be consumed with very little code.


The showcase application offers the capability to share photo album pictures or pictures taken by the iPad camera on up to 5 different cloud services: Twitter, Facebook, Google Drive, DropBox and Flickr with a single click.
We have made the full source code of this showcase demo available as well as a video presentation. When you have TMS iCL v1.5 or later as well as TMS Cloud Pack for iOS v1.1 or later with Delphi XE4, you can build this application. Note that you will need to register the application you create with the various cloud services to get the keys & secrets.

The article, video and source download can be found here.



TMS XData is coming

$
0
0

A new framework named TMS XData is cooking in the TMS labs. It's hard to define what a framework is with a few words, especially if such framework is modular and many pieces of it can be used separately. Nevertheless, using a very broad definition I could say that TMS XData is a framework that allows you to provide and consume application data through Rest services. But maybe instead trying to define it, I should give you a small sample.

XData can be strongly integrated with TMS Aurelius, our ORM framework. I have posted some articles here about Aurelius and some very simple samples, so in case you still don't know about it, you can check how to getting started or, related to this article, how to create simple associations with it.

Now let's build a very simple XData server that serves Aurelius objects:

program SimpleXDataServer;

{$APPTYPE CONSOLE}

uses
  Aurelius.Drivers.Interfaces,
  Aurelius.Engine.ObjectManager,
  XData.Http.Server,
  XData.Aurelius.EntityServer,
  Utils,
  Customer;

procedure CreateCustomer(const CustomerName, CountryName: string);
var
  Manager: TObjectManager;
  Customer: TCustomer;
  Country: TCountry;
begin
  Manager := TObjectManager.Create(SQLiteConnection);
  Country := TCountry.Create;
  Country.Name := CountryName;
  Customer := TCustomer.Create;
  Customer.Name := CustomerName;
  Customer.Country := Country;
  Manager.Save(Customer);
  Manager.Free;
end;

var
  Conn: IDBConnection;
  Server: THttpServer;
begin
  ReportMemoryLeaksOnShutdown := true;
  Conn := SQLiteConnection;
  BuildDatabase(Conn);
  CreateCustomer('Paul', 'United States');
  CreateCustomer('Jonas', 'Germany');
  CreateCustomer('Hiroto', 'Japan');
  CreateCustomer('Jian', 'China');
  CreateCustomer('Sergei', 'Russia');

  Server := THttpServer.Create;
  Server.RegisterHandler(
    TAureliusEntityServer.Create(
      'http://aurelius:2001/tms/xdata', SQLiteConnection));
  Server.Start;

  WriteLn('Running Simple XData Server');
  ReadLn;
  Server.Free;
  DestroyDatabase(Conn);
end.
The code above uses the classes TCustomer and TCountry defined in the blog post "Associations (foreign key)". They are simple classes and I'm not showing them again here for simplicity. Also, be aware that try..finally blocks were removed also to make code cleaner.

The above application is a regular TMS Aurelius application, that connects to a database, creates needed tables and insert some data. The different part is the one that creates a THttpServer instance and register a request handler under the address "/tms/xdata". What happens here is that Aurelius objects are now being provided through a very well defined Rest API.

XData uses by default the OData protocol, which makes it very compatible with other clients and platforms. It also makes everything automatic for XData: your TCustomer objects, for example, are available at the address "http://aurelius:2001/tms/xdata/TCustomer" (Naming can be configured as well).

Another interesting thing is how this data is easily accessible from everywhere. As an example, here is the full source code of a .NET C# console application that connects to such server and retrieves the customer objects from it, using Linq:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;

namespace DotNetClient
{
    class Program
    {
        static void Main(string[] args)
        {
            DataServiceContext context = new DataServiceContext(new Uri(@"http://aurelius:2001/tms/xdata"));
            IQueryable<TCustomer> customers = context.CreateQuery<TCustomer>("TCustomer");
            foreach (TCustomer customer in customers) 
                Console.WriteLine("Customer {0} from {1}", customer.FName, customer.FCountry.FName);
            Console.ReadLine();
        }
    }

    public class TCustomer
    {
        public int FId { get; set; }
        public string FName { get; set; }
        public TCountry FCountry { get; set; }
    }

    public class TCountry
    {
        public int FId { get; set; }
        public string FName { get; set; }
    }
}
And here is the output generated by this C# application.



More info coming soon!



Might be of interest for your next software developments ...

$
0
0

A short post this time with a tip for something that might be of interest to you in the near future for your software developments.
Everyone who's been using the Android emulator on Windows machine will know that it can be (unbearable) slow. Help is offered by Intel though with HAXM. The description reads:
The Intel Hardware Accelerated Execution Manager (Intel® HAXM) is a hardware-assisted virtualization engine (hypervisor) that uses Intel Virtualization Technology (Intel® VT) to speed up Android app emulation on a host machine. In combination with Android x86 emulator images provided by Intel and the official Android SDK Manager, HAXM allows for faster Android emulation on Intel VT enabled systems.
The download for HAXM can be found here.
Some more information on using HAXM is at : http://fizzylogic.nl/2012/08/21/run-your-android-apps-in-highspeed-on-the-emulator/.
We wish you happy Android coding!

TMS software platinum sponsor of Be-Delphi + Delphi Developer Days

$
0
0


We're pleased to announce TMS software is platinum sponsor of the upcoming Be-Delphi conference on November 21 in Antwerpen, Belgium and the Delphi Developer Days on December 4,5 in London, UK.
The Be-Delphi conference in Antwerpen has its third edition this year with an impressive roster of speakers and ditto technical content. From Embarcadero, Marco Cantu will be present to introduce the new Delphi XE5, from USA, Ray Konopka from Raize software has an in depth session about generics. Delphi gurus from day 1, Brian Long, Jeroen Pluimers and Bob Swart are present as well. Brian Long talks about developing for Android, Jeroen Pluimers about the MVVM pattern in Delphi and Bob Swart about (dis)connected mobile datasnap.
But there is more, Mathias Dellaert talks about TVirtualInterface / TVirtualMethodInterceptor, Detlef Overbeek from the Blaise Pascal magazine talks about Leap Motion and we have Anton Vogelaar giving a session about Delphi for industrial control.
The TMS software team will be present with a booth and Bruno Fierens gives a session on consuming GEO services from Delphi.
As you can see, Be-Delphi 3.0 will be again a top technical conference packed with interesting talks and exciting subjects. The TMS software team looks forward to meet you there!


Shortly after, on December 4 and 5, Carry Jensen and Bob Swart bring the Delphi Developer Days and an extra day on December 6 devoted to a Delphi Mobile development workshop. No new technical subject is left untouched on the Delphi Developer Days. FireMonkey, FireDac, Gestures and touch, debugging, Datasnap, XML, JSON, threads, Android, iOS, ...
If you want to update yourself to the latest knowledge about Delphi, don't hesitate to register for the Delphi Developers Days as places are strictly limited!

TMS Aurelius session at CodeRage 8

$
0
0


Join Embarcadero and software development experts from around the world this week at CodeRage – the totally free, totally technical, online conferences dedicated to technology and development.

On Thursday Oct 17, our colleague Wagner Landgraff is giving a presentation on our Delphi ORM TMS Aurelius and this introduction will help you quickstart using the TMS Aurelius framework for writing effective database driven Delphi applications in a productive way.

TMS software speaks at, exhibits at and sponsors Embarcadero Conference Brasil

$
0
0

The Brasil Delphi developer community is one of the biggest in the world. Many of our smartest and most enthusiast customers are based in Brasil and come up all the time with very innovative and creative Delphi solutions. Therefore, we're pleased that TMS software can be present at the Brasil Embarcadero Conference on October 31, 2013 in São Paulo. This conference is also one of the biggest, if not THE biggest with over 600 attendees.
Our TMS Aurelius lead, Wagner R. Landgraf will have a session there about the use the TMS Aurelius ORM in combination with the upcoming TMS XData product. We will also have a booth where you can learn more about our products for VCL Windows application development and meanwhile also our increasing number of tools and components for mobile cross platform application development for iOS and Android.
Finally, we will provide 15% in our products for all attendants.
We look forward to meet you at the Brasil Embarcadero Conference and hear about your projects, your needs and answer your questions!

We'll be at the Embarcadero Event at Argentina

$
0
0


This November 14 we'll be present on the Embarcadero Event at Buenos Aires, Argentina.

The event is focused in mobile development with the new Embarcadero Rad Studio XE5. Along with many other interesting speeches, I will be giving a session about dealing with files in iOS and Android, and how to use TMS FlexCel to generate xls, xlsx, pdf or html files in a mobile device. If you are near Buenos Aires on this date, make sure come and say hello.

Two lines of code to add QR, UPC, EAN code scanning in iOS Delphi applications

$
0
0

For an internal project, we looked at integrating QR code scanning in an iOS application. As we didn't feel like reinventing the wheel and deal with the complexities of deciphering a QR code, we searched for existing code and after trying out several solutions, found ZBar to be one of the most solid libraries. The project is at : http://zbar.sourceforge.net/

After doing this evaluation in XCode with ObjectiveC, the next duty was to find out how we could use an ObjectiveC library from a Delphi FireMonkey project. There are several important details to pay attention to when doing this, but finally this also proved to work and in the typical Delphi RAD philosophy, we decided to create a wrapper Delphi component for this. With this wrapper component, scanning a QR, UPC or EAN code from Delphi is as simple as two lines of code:

procedure TForm1136.Button1Click(Sender: TObject);
begin
  // line1: activate the code scanner. This shows the camera that should be aimed at the QR or UPC code
  TMSFMXZBarReader1.Show;
end;

procedure TForm1136.TMSFMXZBarReader1GetResult(Sender: TObject;
  AResult: string);
begin
  //line 2: the OnGetResult event is triggered when the code was retrieved and this returns it as a text
  ListBox1.Items.Insert(0, AResult);
end;
You can download the sample project and the package with full source code to install the TTMSFMXZBarReader component here: http://www.tmssoftware.net/public/TMSFMXZBarReaderPkgDXE5.zip
Open the package file TMSFMXZBarReaderPkgDXE5.dproj from Delphi XE5 and compile & install this package. This will add the component TTMSFMXZBarReader on the tool palette. Then you can drop this component in an iOS Delphi appplication and start using it in 1,2, 3 ...

   


The year 2013 at TMS

$
0
0

When you go home in the evening after working hard all day, do you also often have the feeling you have achieved much less than you had expected or hoped for that day? If so, join the club.
But now that I sit back at the start of a new year and retrospectively look at what 2013 brought for TMS, I hope you'll agree with me that we nevertheless achieved quite a lot. Actually, 2013 was quite a rollercoaster.

To start with, our VCL development continued relentlessly.

TMS Component Pack
We have seen 4 major releases, going from v6.7.0.0 to v7.1.6.0. with support for RAD Studio XE4 and XE5 added but also with 7 new components, 206 new features and numerous improvements added. For 2014, new components & new features are already in development. Be in touch with our development team to express your desires & comments so we can integrate these also in future updates.

TMS Aurelius
Our flagship ORM for Delphi, TMS Aurelius continued to be highly appreciated by customers and several exciting capabilities were added. There is now integrated database schema update and validation. There is iOS support with full native access to SQLite. There is the new TExpression/TLinq for stronger querying capabilities. TMS Aurelius is also being readied for seamless integration with TMS XData that will be released in 2014.

TMS Cloud Pack
This was another rapidly growing product in 2013. TMS Cloud Pack now comprises seamless access to the worlds most popular cloud services like Twitter, Facebook, LinkedIn, FourSquare, iCloud Calendar, iCloud Contacts, Google Calendar, Google Contacts, Live Calendar, Live Contacts, Flickr, Picasa, Instagram, Google Drive, SkyDrive, DropBox, Box.NET and more... But this is only the start. Watch 2014 for some exciting new capabilities to be added.

GEO mapping components TWebGMaps and TWebOSMaps
In 2013, we extended our component for Google Maps, TWebGMaps with directions, directionlist, waypoints and also introduced a new component TWebOSMaps that offers similar functionality but using Open Street Maps. We also made our GEO mapping components available for web application development with an IntraWeb version and for mobile development.

TMS Advanced Chart
This year also saw some major new features added in TMS Advanced Charts. 3D pie charts and the funnel chart type were added along with several smaller enhancements that make the every day programming with TMS charts easier.

With the releases of RAD Studio XE4 and XE5 this year, bringing us cross platform development targetting iOS and Android, there was without a doubt also much activity at TMS in the area of FireMonkey development!

TMS Flexcel
The strongest VCL solution on the market for native XLS/XLSX file manipulation with included PDF & HTML report generation on Windows, TMS Flexcel now makes its power also available for Mac OS-X, iOS and Android. No matter what operating system you target, TMS Flexcel offers a versatile, feature rich and high performance solution for dealing with XLS, XLSX, XLSM files.

TMS Pack for FireMonkey
With RAD Studio XE4 and XE5 bringing native iOS and Android support, it is evident that our team had its hands full with ensuring TMS Pack for FireMonkey components work flawlessly on all four platforms and on top of that we added new components and numerous new features. There is a new syntax highlighting memo in the TMS Pack for FireMoney, the included feature-rich grid was extended with new functions and improvements, a VCL listview interface compatible wrapper was added, live bindings support was added in the TTMSFMXTileList and support for it was improved in several components.

TMS Cloud Pack for FireMonkey
TMS Cloud Pack for FireMonkey is a new product that saw the light in 2013. Developers can now easily integrate the consumption of popular cloud services from Delphi iOS or Android applications via ready to use Delphi classes that wrap all the functionality. TMS Cloud Pack for FireMonkey development is closely tied to TMS Cloud Pack for VCL development, so expect new features and improvements to become available in both.

In 2013, we also saw the creation of a new category of components: the 100% native iOS and Mac OS-X components. For those instances where it is really needed to get the maximum performance and maximum UI look & feel consistence out of your applications, we created TMS iCL targetting iOS and TMS mCL targetting Mac OS-X. TMS iCL and TMS mCL bring more than just thin Delphi class wrappers around iOS or Mac OS-X APIs. Our focus is on easy to use, feature-rich Delphi components designed with RAD in mind.

TMS iCL
This suite of components targets iOS. It contains nearly all native iOS UI components like buttons, edit, switch, pickers etc... but also rich Delphi classes giving access to complex iOS controls such as the collectionview, rich text editor, tableview, mapview, toolbar etc... For 2014, we have several new components in research and development that go far beyond simple iOS API wrapping.

TMS mCL
Similar to TMS iCL, TMS mCL targets Mac OS-X. This component set is designed with the same philosophy as TMS iCL. Also here, there is a rich text editor, a tableview, toolbar, PDF viewer, web browser and much more.

Not only for Delphi developers we added a huge array of components for cross-platform / mobile application development, also in the area of .NET, TMS Flexcel for .NET entered in the mobile area with new support for Xamarin. Via Xamarin, TMS Flexcel .NET now also targets iOS and Android!

In the area of web development, the focus was on new products like TMS IntraWeb WebGMaps, TMS IntraWeb WebOSMaps, TMS IntraWeb Cloud Pack as well as continuously improving our products for cross browser compatibility and adding support for the latest versions of IntraWeb 12.2 and IntraWeb 14.0. For this year, we have some exciting new developments underway for your web development.

Of course, this list is just a summary of some major component developments that happened here in 2013 at TMS. It would make this article far too long to list everything in detail. Check the version history tab on each product page to have a look at what was recently added! Other than component development, in 2013 we had several other major events. One such event was the first TMS developer day we organized with the support of the Be-Delphi organisation in April. From the feeedback of attendees, it was clear this day was very much appreciated and we plan a new TMS developer day this year but most likely at a different location. The second major event this year was the release of our completely restyled website. And finally, we have also introduced feature-request voting this year. With this tool, we cannot only capture what you would like to see us develop but also measure interest and steer our development to what you need most. Since its introduction this year, we have already handled more than 20 such requests.

So, we hope you'll agree with us that 2013 was quite an exciting year. Our batteries are recharged to bring more excitement for 2014. Our team is ready to listen and respond to all your inputs, feedback, comments, questions and suggestions to create together great software development solutions.

Get device independent, put your settings in the iCloud

$
0
0

On the road, we carry a smartphone, in a couch we grab the tablet and in the office we sit behind the desk and use a desktop computer. In all scenarios though, we want to use applications that give us access to the same data and functions. Therefore, it is also logical that when we change our parameters for access to this data and functions via the desktop machine application, these same parameters and settings will be reflected (automatically) when we use the smartphone or tablet specific application and vice versa. In the Apple world, the answer to this scenario is persisting our parameters / settings on the iCloud.

As a Delphi developer, we typically like it when we can persist this information with a minimum amount of code so we can focus on the business logic instead of all technical complexities of using the iCloud. Delivering this promise, we've now released two new non-visual components: TTMSFMXNativeiCloud and TTMSFMXNativeMaciCloud. With these components, putting key/value pairs on the iCloud and retrieving them becomes as simple as using a method

 procedure AddKey(AKeyName: String; AKeyValue: TValue);
to create a key/value pair and using the property:
 
 property KeyValues[AKeyName: String]: TValue
to get and set the value of the key.

So, when in one application, the user would change a setting, this can be done with:
var
  FName: strring;

FName := 'TMS';
TMSFMXNativeiCloud.KeyValues['MyAmount'] := 1234;
TMSFMXNativeiCloud.KeyValues['MyName'] := FName;
Thanks to the magic of the iCloud and these non-visual components, the key/value pairs will now automagically be synchronised between applications on different devices coupled to the same iCloud account. If the app wants to react immediately to iCloud pushed value changes, the event TTMSFMXNativeiCloud.OnKeyUpdate is triggered and can be handled like:
procedure TMSFMXNativeiCloud.KeyUpdate(Sender: TObject; AKeyName: String; APreviousValue, ACurrentValue: TValue);
begin
   if (AKeyName = 'MyName') then
     FName := ACurrentValue;
end;
Note that the value is of the type TValue and supports strings, booleans, integers, double and a TMemoryStream. Of course, the component offers several more options like deleting a key/value pair, programmatically forcing a synchronisation of the values on the iCloud, receiving events when iCloud pushed updates to values etc...

TTMSFMXNativeiCloud is available now in the newest TMS iCL update and TTMSFMXNativeMaciCloud is available now in the newest TMS mCL. A FireMonkey iOS demo in TMS iCL and a FireMonkey Mac OS-X demo in TMS mCL demonstrate this concept by having a customizable set of key/value pairs shared via the iCloud between these applications as shown in the screenshot above.

Hello, TMS Sparkle

$
0
0

TMS Sparkle is a brand new product released by TMS Software. It is a Delphi framework for network, Internet programming.

As stated in the online documentation, TMS Sparkle is the core building block for several other TMS products and technologies, such as upcoming TMS RemoteDB and TMS XData. Such products needed to be built from scratch, and to rely on a robust framework for which TMS could have 100% control and also responsibility. For such products to work flawlessly, we needed to be sure to build such products in a framework that must be properly tested, and have fast response in performance improvement and bug fixing.

It is trustworthy, fresh, modern, cross-platform (Windows, Mac, iOS, Android) and most of it, as much platform native as it can be.

TMS Sparkle is part of TMS Business Subscription, which contains many other products, like TMS Aurelius and TMS Scripter, and will also receive the mentioned upcoming products TMS RemoteDB and TMS XData.

For detailed information you can refer to TMS Sparkle product page and online documentation. In the meanwhile, to illustrate its usage, here is the full source code for a minimal Http Server using TMS Sparkle:

program HelloWorldServer;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Sparkle.HttpServer.Context,
  Sparkle.HttpServer.Module,
  Sparkle.HttpSys.Server;

type
  THelloWorldModule = class(THttpServerModule)
    public procedure ProcessRequest(const C: THttpServerContext); override;
  end;

procedure THelloWorldModule.ProcessRequest(const C: THttpServerContext);
begin
  C.Response.StatusCode := 200;
  C.Response.ContentType := 'text/plain';
  C.Response.Close(TEncoding.UTF8.GetBytes('Hello, World!'));
end;

const
  ServerUrl = 'http://localhost:2001/tms/business/hello';
var
  Server: THttpSysServer;
begin
  Server := THttpSysServer.Create;
  try
    Server.AddModule(THelloWorldModule.Create(ServerUrl));
    Server.Start;
    WriteLn('Hello World Server started at ' + ServerUrl);
    WriteLn('Press Enter to stop');
    ReadLn;
  finally
    Server.Free;
  end;
end.



The story of a teenage scripter

$
0
0

Last week I was just browsing the TMS site, looking at the version numbers of existing products, when I saw TMS Scripter current version: 6.3. I see those numbers often and I’m used to them, but this time, I was a little bit shocked. Just like a father whose son is born and, in the blink of an eye, watches this son going to college in his eighteen, I was astonished to see how far TMS Scripter went, and for so long. It’s true that my oldest son is just about to turn 5 years-old, but for that my eyes didn’t even have to blink – they were wide open – so I can imagine how it might be for a father of a grown-up son. My second son is only 12 days old, and got me so worried last week to the point I went to the gym with a different tennis shoe in each foot and only noticed it when I came back home. I’m trying not to blink an eye. But I digress.

Thing is TMS Scripter is already a teenager. I have to face it. First version was released in 2001, but it was being already used in internal projects for at least three years. It’s interesting to see old family pictures, and the following one shows version 1.5 from November, 2001, when it was still called TatPascalScripter and had just a new featured added: COM interfaces support.



Since then, it had fourty-six – fourty-six! – releases, which added the following main features (in chronological order) that transformed TMS Scripter over the years:

  • Support for COM Interfaces
  • Basic Syntax
  • Delphi classes import tool
  • Debugger
  • Syntax highlight memo with breakpoints, etc.
  • Events support
  • Code completion
  • WebScripter
  • Watches
  • Thread support
  • Script-based libraries
  • DLL importing from script
  • Source explorer
  • Script-based forms
  • Complete IDE with form designer and object inspector
  • Automatic class import using new RTTI
  • Parameter hints
  • Script-based classes
  • Undo/Redo in form designer
  • Windows 64-bit support
  • Firemonkey Forms
  • Mac OS support


Besides, of course, constant language improvements, introduced over the releases, and support to all the new Delphi versions released, until the latest one, XE6, with no exception.

Over all those years and versions, full backward compatibility was kept, regression bugs were minimized and fixed, and I believe most of TMS Scripter users had a safe and peaceful life like, with full support and compatibility – including the famous migration from ANSI to UNICODE.

But what brings more satisfaction is to see the different way TMS Scripter affects many users. Yes, TMS customers are overall satisfied, enjoy the high number of features in our products, and appreciate the support we provide. But TMS Scripter is, of the products I manage, the one that receives more “emotional” comments. Users mention to be surprised every day with it, and comment how it constantly opens new doors in their applications. I believe one of the reasons for that is the fact that TMS Scripter is an “open” product, with so many different ways to use and applications, that it often requires (and allows) a great amount of creativity from its users, making them a kind of “artist” of their own software.

Yes, TMS Scripter is already a teenager. But more exciting things will come and its story doesn’t end here.


Finding memory leaks in Delphi for iOS

$
0
0

Introduction

Delphi has a very high degree of compatibility between desktop and mobile code: with some little differences, code written for Win32 will run fine in iOS and Android.

Many of those differences are in strings, like not having UTF8 strings (which I hope they'll finally see the light and re-add some day), or having zero-based strings instead of 1-based (which if you are writing code for both mobile and desktop, and you are not into self infringed pain, you'll just want to make all strings 1-based by writing {$ZEROBASEDSTRINGS OFF} everywhere in your units).

But on this post I wanted to focus in what is probably the biggest difference between Delphi mobile and Delphi desktop: Automatic Reference Counting (ARC). As you will probably know, ARC is a "light" kind of garbage collection which works by keeping the number of objects which have a reference to another object. When the reference count drops to 0 (nobody is using the object), it is automatically destroyed. Most of the time ARC works fine and allows you to replace of thousands of lines like:

  Whatever := TWhatever.Create;
  try
     DoSomething(Whatever);
  finally
     Whatever.Free;
   end;

by simply
  DoSomething(TWhatever.Create);

Delphi will take care of destroying whatever for you when it is not used anymore, and generally this is a good thing (™), since in most cases the more work the compiler does for you the better. The compiler will never forget to free an object. But ARC comes with some disadvantages too: Not only it will be slower since it has to increase and decrease the reference counting of the objects in a thread safe way (most likely involving locks), but even worse, code that runs without leaks in "Classic Delphi" might start to leak when compiled with ARC.. This is a very serious problem, because it won't manifest itself immediately. The converted desktop code will work fine in mobile, but under the hood memory usage will grow continually until the app crashes because it runs out of memory. So we need a way to catch and fix those memory leaks.

ARC and Circular References

The problem with ARC is simple: Classes that directly or indirectly reference themselves (think in double linked lists, or any cache scheme where the main objects keep a reference to the cache, and the cache to the main object). In those cases you have a situation like the following:


"Parent" has 2 references (one from the root object which created it, the other from the child). Child has 1 reference from the parent. When we exit the method, "Parent" reference count will drop to 1 and child reference count will stay at 1 too. Neither parent or child will be destroyed, and they will leave forever happily ever after: each one of them keeping the other alive.

And note that even if you explicitly call Parent.Free, it still won't be destroyed. In ARC, Free just sets the object to nil, breaking the reference from Root to Parent and decreasing the reference count to 1, but the reference from the child will still be there, keeping the Parent alive. You would have to call Parent.DisposeOf to explicitly call the parent destructor, and in the parent destructor set Child to nil. Code that used to run fine in Desktop (where you call Parent.Free) stops working when you use it in ARC. And this is a problem. For this particular case, ARC not only didn't remove any existing leak, but it introduced one.

So how do we fix it?Delphi has a [WEAK] attribute that you can use to "break" those reference loops. By marking the child reference as weak, it won't count towards the parent's reference count.



With the [weak] reference now parent reference count will be 1 and not 2, and when the reference from root is broken, parent and child will be destroyed. And this should be enough theory for now: time to get our hands dirty with some real code.

Creating the memory leak

Let's start with two simple classes that reference themselves:
type
TChild = class;

TParent = class
  public
  FChild: TChild;
  constructor Create;
  destructor Destroy; override;
end;

TChild = class
  public
  FParent: TParent;
  constructor Create(const aParent: TParent);
  destructor Destroy; override;
end;

The classes do just the bare minimum: When you create a TParent it will create and keep a reference to a TChild, and the Child will keep a reference to its parent. Just to know when those classes are being destroyed, we'll add messages in the destructor:
{ TParent }

constructor TParent.Create;
begin
  FChild := TChild.Create(self);
end;

destructor TParent.Destroy;
begin
  ShowMessage('Parent destroyed!');
  inherited;
end;

{ TChild }

constructor TChild.Create(const aParent: TParent);
begin
  FParent := aParent;
end;

destructor TChild.Destroy;
begin
  ShowMessage('Child destroyed!');
  inherited;
end;
And finally, let's add a button on the form, and create an instance of the parent class:
procedure TForm1.Button1Click(Sender: TObject);
var
  Parent: TParent;
begin
  Parent := TParent.Create;
end;
Let's try and run the application. Launch it and press the button. If everything goes as expected, no message "Parent destroyed!" or "Child destroyed!" should appear. Even when we have ARC, Parent and Children aren't being destroyed.

If we aren't fully convinced yet, one way to verify it is to place a breakpoint under the Parent := TParent.Create line, and look at the reference count of the object:


As you can see, refcount is 2: One for the "Parent" variable and the other from the child. When we exit the method, refcount will go down to 1, but it will never be 0 and the object will never be destroyed.

So now the question is: How can we find leaks in a big project? We can't go logging all destructors and we can't check all the refcounts of all the objects. When writing Win32/Win64 code, we have an invaluable tool: FASTMM. Either by writing ReportMemoryLeaksOnShutdown := True; in your app startup code, or by using the full FASTMM debug options, you can easily find the objects that have leaked in your app.

But there is no FASTMM for iOS; iOS memory allocations requests go directly to the iOS memory allocator. One idea could be to target "Win32" for our mobile application and try to use our Win32 leak detection techniques there:



But alas, the "Win32" target doesn't have ARC, so no objects will be destroyed at all. We'll have to try a different approach: We'll try the native OSX tools instead. XCode comes with a very helpful tool not so helpfully named "Instruments", which can be used to profile and look at leaks in objective-C apps. Given that Delphi in OSX uses the same LLVM backend and Debug information as XCode, it would be expected that we can use the same tools as in XCode. And it turns out we can.

Finding the leak

First steps first, we'll start by launching Instruments. You can do it by launching XCode, then go to Menu->XCode->Open Developer Tool->Instruments:



Of course, once it opens you might want to keep it in the dock to be able to open it faster next time. While in this post we will be only showing how to find memory leaks, Instruments is a very powerful tool which includes a CPU profiler, memory diagnostics, I/O activity and much more. If you are doing serious iOS work, you are likely to spend a lot of time in Instruments.

You should be greeted by a screen similar to this one:



From here, we will select "iOS" at the left (Leak detection won't work in the iOS simulator), and then "Leaks" at the right. Once in the main Instruments screen, we need to choose the app to profile. We'll select the iOS device (again, leak detection won't work in the simulator) and then select our app from the "Choose target" menu inside the "Choose target" combobox:



In the short video below, I'll show how profiling the app looks like. I've marked some interesting parts on it:

1) Choose a target. This is where we select the app that we have previously deployed to the device. Make sure to deploy it in DEBUG mode so symbols are loaded.

2) Record. When we press "Record" the app starts in the device, and the profiler starts running. At first the "Allocations" profiler is selected, and while it has a lot of interesting information on its own, for this article we are interested in the leaks. So we select "Leaks" from the left sidebar.

3) Snapshot. On the lower left pane, we have the "Snapshots" section. By default it takes a memory snapshot every 10 seconds, but we can select the interval or manually trigger one. In this video we pressed the button on the device, then pressed the "Snapshot Now" button in Instruments, and a memory leak is shown. After that we pressed the button twice more, and then "Snapshot Now" again. You can see the leak count increases to 3. You can also see the red bars in timeline showing when the leaks where created.

4) Inspect the call stack. By pressing the button to show the right pane in Instruments, we can take a look at the stack trace that lead to the leak. You can see that even when this is a delphi app, the debug information is all there, and you can see the actual delphi class names like "TParent", and the method names like "Button1Click". This makes it really easy to pinpoint the troubling parts.

5)Inspect the cycles. Finally, we can also look at a view that is helpful to see the cycles. In this case the cycles are very simple so the diagram doesn't add much, but in a more complex case this can also help finding the element that is leaking.



Fixing the code

Now that we have find the offending code, the last step is to fix it. To do that, just add a [WEAK] attribute to the child reference to the parent.

The child class will end up as follows:

TChild = class
  public
  [Weak]FParent: TParent;
  constructor Create(const aParent: TParent);
  destructor Destroy; override;
end;


If we run the application now, we should finally be able to see the messages in the destructor:



And Instruments should show no cycles or leaks. Also if you debug the application and inspect the reference count for parent, it should never be 2.
Ok, I think this should be it. Have a happy leak hunting, and don't forget to explore the other "Instruments" available in "Instruments" like the allocation or cpu profilers. Most instruments work just fine with Delphi apps, and there are a couple of jewels waiting for you on there.

TMS XData v1.0 released

$
0
0

We're pleased to introduce today TMS XData, another important part in the TMS Business Subscription line-up of tools & components to let you write better & faster business logic for local, Windows-only, cross-platform and multi-tier solutions, in short, the entire spectrum of Delphi applications you can develop.

TMS XData is a full-featured Delphi framework that allows you to create HTTP/HTTPS servers that exposes TMS Aurelius, our Delphi ORM, objects through REST/JSON calls. With JSON being the defacto language for data communication via internet, these objects can be consumed by Delphi desktop or mobile clients but also any other client written in other languages.

TMS XData builds upon TMS Sparkle, the framework that offers classes for high performance HTTP/HTTPS client and server services for Windows, Mac-OSX, iOS, Android. TMS Sparkle is fully cross-platform but uses behind the scenes platform native APIs for the best possible performance.

To see how TMS XData can help you build multi-tier applications that consume TMS Aurelius ORM objects, suppose you have an Aurelius class mapped like the following.

[Entity, Automapping]
  TCustomer = class
  strict private
    FId: integer;
    FName: string;
    FTitle: string;
    FBirthday: TDateTime;
    FCountry: TCountry;
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
    property Title: string read FTitle write FTitle;
    property Birthday: TDateTime read FDateTime write FDateTime;
    property Country: TCountry read FCountry write FCountry;
  end;
With just a few lines of code you can create an XData layer to expose those objects. Creating the XData HTTP server module is explained here. You could retrieve an existing TCustomer with id equals to 3 using the following HTTP request, for example:
GET /tms/xdata/Customer(3) HTTP/1.1
Host: server:2001
And the JSON representation the customer will be returned in the body of HTTP response:
{
  "$id": 1,
  "@xdata.type": "XData.Default.Customer",
  "Id": 3,
  "Name": "Maria Anders",
  "Title": "Sales Representative",
  "Birthday": "1980-05-20",
  "Country": null
}

You can perform changes to objects through the REST interface, using POST method to create new objects, DELETE to remove objects, and PUT or PATCH to update the objects. The following example will change the value of Title property of the customer resource specified in previous example:
PATCH /tms/xdata/Customer(1) HTTP/1.1
Host: server:2001
 
{ 
  "Title": "Marketing Manager" 
}
You can also perform queries on existing objects. The following example will retrieve all customers with country name equals to "USA", ordered by customer's name.
GET /tms/xdata/Customer?$filter=Country/Name eq 'USA'&$orderby=Name&$top=10 HTTP/1.1
Host: server:2001
And server will return with a JSON array of objects containing all the filtered objects. You can use query paging to restrict the number of objects returned in each request.

There is much more to explore in this exciting new framework. You can get started by downloading the trial version for Delphi XE2.. XE6 at http://www.tmssoftware.com/site/xdata.asp and check out the full documentation

TMS software at Delphi Tage 2014 in Bonn, Germany

$
0
0

We're looking forward to be present at the Delphi Tage 2014 in Bonn, the community event for Delphi enthusiasts.

For Delphi Tage 2014, TMS software will:

1) Sponsor the community evening on Friday 5 Sept, so you can have more drinks & food.

2) Exhibit on the conference day on Saturday 6 Sept.

3) Bruno Fierens will present a session on using TMS Pack for FireMonkey UI components and TMS Cloud Pack for FireMonkey to create feature-rich cloud enabled cross platform applications.

4) We'll show our latest developments at the booth.

5) Four TMS team members will be present to guide you through our components and assist you when you have questions.

6) We're working on a "social-enabled" prize-draw app all attendees will be able to follow via Twitter. Follow @tmssoftwarenews at Delphi Tage 2014 and see what you have won.

7) We're putting together lots of prizes to win: licenses, T-shirts and several kinds of beer that was locally brewed in our region.

In short, we're excited to be at Delphi Tage 2014 and hope you'll be numerous to join us for this community event! See you in Bonn, Germany in September.


TMS iCL native iOS peer 2 peer communication

$
0
0

We've created a short (8 minute) presentation / demo video to show you how our newest native iOS peer 2 peer communication component in TMS iCL works. It shows how you can send an object and text via Bluetooth or local WiFi to nearby peers. Underlying, everything is done via 100% native iOS APIs, so, no Indy or other libraries are being used.

Check out the video here:


Visualize TMS Planner event relations with arrows

$
0
0

It's already for a longer time that our Planner scheduling components supports linking events. That means that when the start time or end time or both times of an event is changed, the start or end time of a linked event will also change. The change in start or end time of linked event will have the same delta as the source event. The link action of choice can be selected with PlannerItem.LinkType and offers following choices:

  • ltLinkFull: when start time and end time of the event is changed, the start and end time of the linked item also changes.
  • ltLinkBeginEnd: when the start time of an event is changed, the end time of the linked event also changes.
  • ltLinkEndBegin: when the end time of an event is changed, the start time of the linked event also changes.
  • ltLinkBeginBegin: when the start time of an event is changed, the start time of the linked event also changes.
  • ltLinkEndEnd: when the end time of an event is changed, the end time of the linked event also changes.
Now, it may not always be desirable that any type of linking will affect the start or end time of the linked item, a visualization might be sufficient. For this case, we have added the link type: ltNone. At the same time, a better visualization of linked items will also benefit "classic" linked items. Therefore, in the latest version of the TMS Planner, we went one step further and have now optionally visual connections with lines with arrows between linked events. To see how easy it is to set this up, imagine two events were created with the code:
var
  plit1,plit2: TPlannerItem;
begin
  plit1 := Planner1.CreateItem;
  plit1.ItemStartTime := EncodeTime(10,0,0,0);
  plit1.ItemEndTime := EncodeTime(12,0,0,0);
  plit1.ItemPos := 0;
  plit1.CaptionType := ctText;
  plit1.CaptionText := 'item 1';
  plit1.Text.Text := 'link from';
  plit2 := Planner1.CreateItem;
  plit2.ItemStartTime := EncodeTime(14,0,0,0);
  plit2.ItemEndTime := EncodeTime(16,0,0,0);
  plit2.ItemPos := 1;
  plit2.CaptionType := ctText;
  plit2.CaptionText := 'item 2';
  plit2.Text.Text := 'link to';
end;


When applying one link with code:
  plit1.LinkedItem := plit2;
  plit1.LinkType := ltLinkFull;
then moving or resizing the event "item 1" will result in event "item 2" also moving or resizing. Moving or resizing event "item 2" will not cause changes to event "item 1". When we'd want a bidirectional link, we'd initialize the link with:
  
  plit1.LinkedItem := plit2;
  plit1.LinkType := ltLinkFull;
  plit2.LinkedItem := plit1;
  plit2.LinkType := ltLinkFull;
In a next step, we'll visualize the link between items with arrow lines. To enable link visualization in the TMS Planner globally, set Planner.ShowLinks = true and set Planner.LinkArrowShape = asFilled when you want fully filled arrows instead of just arrows (asNormal). To have two events that are linked with an arrow line from one event to the other event without specific link relationship, setup the items with:
  plit1.LinkedItem := plit2;
  plit1.LinkType := ltLinkNone;
  plit1.LinkArrow := laFromTo;
  plit1.LinkColor := clGreen;
To have the arrows go in both directions, simply set the property LinkArrow to laBoth as in this sample:
  plitA.LinkedItem := plitB;
  plitA.LinkType := ltLinkNone;
  plitA.LinkArrow := laBoth;
  plitA.LinkColor := clRed;


We hope you'll find this new feature useful and you can benefit from it to create better applications for your customers. Check out this and more in the TMS Planner.

TMS Day in Denmark on November 4th

$
0
0

We are excited to announce that Jens Fudge, Embarcadero MVP for Denmark, and TMS software are planning a TMS day in Denmark on November 4th.

All day, sessions will be spent on TMS VCL components, TMS cloud components and TMS FireMonkey components with also sufficient session time allocated to handle your specific questions on TMS components. The sessions will be given by Bruno Fierens, Embarcadero MVP in Belgium and CTO from tmssoftware.com.


Tentative session program:


  • 9h00-9h30 : Registration & coffee
  • 9h30-10h30 : Getting the most out of TMS VCL grids
  • 10h30-11h00: Coffee break
  • 11h00-12h00: Embracing the cloud with TMS cloud components
  • 12h00-12h30: Q&A
  • 12h30-13h30: Lunch
  • 13h30-14h30: TMS FireMonkey components including TMS grid for FireMonkey
  • 14h30-15h00: Coffee break
  • 15h00-15h30: An introduction to TMS iCL & TMS mCL
  • 15h30-16h00: Tricks with TMS VCL components
  • 16h00-17h00: Q&A and round-table discussion on Delphi components & Delphi development with TMS components in general

Sign-up now for the TMS Day in Denmark in Videnpark Trekanten, Fredericia, Denmark on November 4, 2014. The cost of the TMS Day is only a small fee 20EUR (150DKK) for the food during this day. The price of food will be deductible from any future purchase from TMS software. Don't delay your registration as the number of seats is limited. During sign-up please also express your interests for topics during this day and possibly questions you might have so we can fine-tune the session program as much as possible to your needs. A few weeks in advance, we will then present the final session program.

Signup here via the online registration form


Hands-on TMS Business Subscription training day

$
0
0

TMS software organizes on Wednesday November 19th a hands-on training day on our TMS Business Subscription line of tools in Kortrijk, Belgium.
All day, sessions will be spent on our ORM, data modeling and remoting tools TMS Aurelius, TMS Data Modeler, TMS RemoteDB, TMS XData, ... with sufficient time for your questions and room for interaction to help you getting the maximum out of these TMS tools. The sessions will be given by Wagner Landgraf, the product Manager of TMS Business Subscription. Bring your laptop if you want to follow the samples live or if you want our expert to have a look at your implementations


Tentative session program

  • 09h00-09h30: Registration & coffee
  • 09h30-10h30: TMS Aurelius
  • 10h30-11h00: Q&A
  • 11h00-11h30: Coffee break
  • 11h30-12h00: TMS Data Modeler & TMS Aurelius
  • 12h00-12h30: Q&A
  • 12h30-13h30: Lunch
  • 13h30-14h30: TMS XData
  • 14h30-15h00: Q&A
  • 15h00-15h30: Coffee break
  • 15h30-16h15: TMS RemoteDB & additional tools
  • 16h15-17h00: Discussion, architecture approaches, Q&A
Registrations until October 31st
The cost of the hands-on TMS Business Subscription training day is 75EUR for TMS Business Subscription users and 125EUR for non TMS Business Subscription users. This includes a full day access to the sessions and coffee/lunch during this day. The extra 50EUR for non TMS Business Subscription users will be deductible from any TMS Business Subscription purchase. Don't delay your registration as the number of seats is limited to 10 persons for a maximum interactivity!

Signup here via the online registration form

Location

  • Kennedy Hotel, Pres. Kennedypark 1, B-8500 Kortrijk
  • Free parking
  • Nearby highway (E17) exit
  • Facilities for hotel rooms at the event are available for international attendees


TMS XData Service Operations

$
0
0

The latest TMS XData 1.1 version introduces a major feature: Service Operations. In addition to having your objects published as REST resources automatically, you can now add server-side logic in a very easy and straightforward way.

Service operations are defined as interfaces. Any interface can become a set of operations, all you need to do is add the [ServiceContract] attribute to the interface:

type
  [ServiceContract]
  IMyService = interface(IInvokable)
  ['{BAD477A2-86EC-45B9-A1B1-C896C58DD5E0}']
    function HelloWorld: string;
    function FindOverduePayments(CustomerId: integer): TList<TPayment>;
  end;
The nice thing is that in addition to sending and receiving values of scalar types, you can also send and receive Aurelius entities. You can also use TStream for low-level operations.

The next step is to write the server logic, which is done just by implementing the interface in some class, and adding the attribute [ServiceImplementation] to that class:
type
  [ServiceImplementation]
  TMyService = class(TInterfacedObject, IMyService)
  private
    function HelloWorld: string;
    function FindOverduePayments(CustomerId: integer): TList<TPayment>;
  end;
 
implementation
 
function TMyService.HelloWorld: string;
begin
  Result := 'Hello, World';
end;

function TMyService.FindOverduePayments(CustomerId: integer): TList<TPayment>;
begin
  Result := TXDataOperationContext.Current.GetManager.Find<TPayment>
    .CreateAlias('Customer', 'c')
    .Where(TLinq.Eq('c.Id', CustomerId) and TLinq.LowerThan('DueDate', Now))
    .List;
end;
And that's it. When you create the XData server module, it will find the interfaces and implementations automatically through the attributes, and will make the operations available through the server.

The FindOverduePayments method implementation illustrates how smooth is the integration with TMS Aurelius. The TXDataOperationContext class provides you with some useful properties to implement your server logic. The main property is GetManager, which provides you with an Aurelius TObjectManager.

All you have to do is use the manager to persist objects, or to query objects using the Aurelius full query API. When implementing the server logic, you don't have to deal with database connections (XData uses its connection pool), you don't need to instantiate the object manager, you don't need to deal with memory management and also with JSON serialization.

To invoke the service operation from any client using HTTP, you just POST to the operation address, passing the parameters in JSON format:
POST /tms/xdata/MyService/FindOverduePayments HTTP/1.1
 
{
  "CustomerId": 10
}
XData will parse the parameters, invoke your method, which in turn will use Aurelius to query the database, retrieve all TPayment objects that match the criteria, and return a plain JSON array with the payment objects in JSON format.

Another great thing is if your client is written in Dephi, you can use the TXDataClient class. You can then benefit from the interface you declared and use it at client side as well. Use the TXDataClient to retrieve the interface, and call the interface method. XData will do all the HTTP requesta and JSON conversion for you, and will give you the TPayment objects:
var
  Client: TXDataClient;
  MyService: IMyService;
  Payments: TList<TPayment>;
begin
  Client := TXDataClient.Create;
  Client.Uri := 'http://myserver/tms/xdata';
  MyService := Client.Service<IMyService>;
  Payments := MyService.FindOverduePayments(10);
  // add your logic that deals with TPayment objects
end;
You can even pass your Payments list to a TAureliusDataset to easily show them in a TDBGrid or any other control that is data aware or using Live Bindings.

You can learn more about XData using the official online documentation. Or you can refer directly to the Service Operations chapter.

Viewing all 1008 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>