Using InterBase Lite and InterBase ToGo in Delphi iOS Applications – Step by Step Guide

Using InterBase Lite and InterBase ToGo in Delphi iOS Applications – Step by Step Guide With RAD Studio XE4 a new InterBase edition has been rolled out. The existing InterBase edition family (Server, Desktop, Developer and ToGo) has been enhanced by an edition called “IBLite”. This edition may be deployed for free with your applications. …
Read More

Read More

Read More

Using ARC with non iOS compiler – possible?

Did you ever have the situation with 2 lists sharing the same objects and possibly one or both had the OwnsObjects property set to true? Especially when using interfaced lists like in Spring4d or DSharp you want to make use of reference couting and automatic memory management. But what if some instances are shared between different lists or moved from one list to the other. You cannot use the Delete or Remove method and then add the object to the other list of vice versa if the first list has OwnsObjects true because it will destroy the instance when it gets removed. That is why there is the Extract method which removes the instance but does not destroy it. This can get complicated and possibly leading to memleaks or exceptions quickly.Using interfaced objects for simple data storages might not be a very good idea. It requires you to write interfaces with the properties just for that purpose and if you use some kind of RTTI based binding you cannot do that as there is no RTTI for interface properties (which are just syntax sugar anyway).So what would we give for some easy memory management in these cases. How about using the concept we know from interfaces and other types for objects?Of course we could write some TRefCountObject and inherit our data classes from that base class and handle these in our Notify method inside the list when items get added or removed. But that would be to easy and not magic at all. ;) And more seriously it does not always work to change the base type due to several reasons.So what do we need? Basically just a new field inside our object to keep track of the reference count. Keep in mind we cannot do a full ARC implementation because that would include assignments and parameter passing which would need compiler support. We just want it for when objects are put into lists.The method that is responsible for allocating the memory of new instances is TObject.NewInstance. So we need to replace that:procedure InitializeARC;var  Buffer: array[0..4] of Byte;begin  Buffer[0] := $E9  // redirect TObject.NewInstance  PInteger(@Buffer[1])^ := PByte(@NewInstance) - (PByte(@TObject.NewInstance) + 5);  WriteMemory(@TObject.NewInstance, @Buffer, 5);end;What this code does is place a jump instruction at the very beginning of the TObject.NewInstance method that redirects it to our NewInstance routine which looks like this:function NewInstance(Self: TClass): TObject;begin  // get additional memory for the RefCount field  GetMem(Pointer(Result), Self.InstanceSize + SizeOf(Integer));  Result := InitInstance(Self, Result);end;It does basically the same as the original except that it allocates 4 bytes more for our RefCount field and then calls our version of InitInstance (which is responsable for initializing the object):function InitInstance(Self: TClass; Instance: Pointer): TObject;const  Buffer: Pointer = @BeforeDestruction;begin  Result := Self.InitInstance(Instance);  // initialize the RefCount field  GetRefCountFieldAddress(Instance)^ := 0;  // replace TObject.BeforeDestruction  if PPointer(NativeInt(Self) + vmtBeforeDestruction)^ = @TObject.BeforeDestruction then    WriteMemory(PPointer(NativeInt(Self) + vmtBeforeDestruction), @Buffer, SizeOf(Pointer));end;Since TObject.InitInstance just zeroes the memory the RTL knows about (obtained by calling InstanceSize) we need to set our field which sits on the last 4 bytes in our instance:function GetRefCountFieldAddress(Instance: TObject): PInteger; inline;begin  // the RefCount field was added last  Result := PInteger(NativeInt(Instance) + Instance.InstanceSize);end;Along with the reference couting we want to make sure that the instance is not getting destroyed when it is still managed by the RefCount (because it sits in some list). That is why the BeforeDestruction method gets replaced. Why not detour like NewInstance? The implementation in TObject is empty so there are not 5 bytes of available that we can overwrite to jump to our implementation. But as it is virtual we can replace it in the classes VMT. Like its implementation in TInterfacedObject it will raise an error when the RefCount is not 0.procedure BeforeDestruction(Self: TObject);begin  if GetRefCount(Self) <> 0 then    System.Error(reInvalidPtr);end;Implementing the actual AddRef and Release routines is pretty easy aswell:function __ObjAddRef(Instance: TObject): Integer;begin  Result := InterlockedIncrement(GetRefCountFieldAddress(Instance)^);end;function __ObjRelease(Instance: TObject): Integer;begin  Result := InterlockedDecrement(GetRefCountFieldAddress(Instance)^);  if Result = 0 then    Instance.Destroy;end;The most important thing: You need to add the unit which contains this as the very first unit in your project  (or after ShareMem) so the NewInstance method gets patched as soon as possible.Time to test if it does what it should:implementation{$R *.dfm}uses  DSharp.Collections,  DSharp.Core.ARC;type  TList<T: class> = class(DSharp.Collections.TList<T>)  protected    procedure Notify(const Value: T; const Action: TCollectionChangedAction); override;  end;procedure TList<T>.Notify(const Value: T;  const Action: TCollectionChangedAction);begin  case Action of    caAdd: __ObjAddRef(Value);    caRemove: __ObjRelease(Value);  end;end;procedure TForm1.Button1Click(Sender: TObject);var  list1, list2: IList<TObject>;begin  list1 := TList<TObject>.Create;  list2 := TList<TObject>.Create;  list1.Add(TObject.Create);  list1.Add(TObject.Create);  list2.AddRange(list1);  list1.Delete(1);end;initialization  ReportMemoryLeaksOnShutdown := True;end.When we click the button both objects get added to both lists and the last list containing an object will cause it to get destroyed when removed (which happens if the list gets destroyed aswell).So far this is more of a proof of concept but I think this can make some code easier and less complicated especially when working a lot with lists and moving around objects without knowing what list at the end owns the objects.You can find that code in the svn repository and as always your feedback is welcome.
Read More

Persisting settings in Delphi iOS applications

I thought I’d celebrate the release of RAD Studio XE4 by climbing back on the article writing horse. My first article is about persisting settings in iOS applications written in Delphi, and can be found on EDN. As always, all feedback is greatfully received. And I’ll see if I can conjure up a few more over the coming weeks (no promises though :-)). Share This | Email this page to a friend
Read More

Today we honor You, the App Developer

We dedicate today’s launch of RAD Studio XE4 to you, our user, the developer, the miracle worker who is asked to achieve greatness on a day to day basis.  Today’s launch is the culmination of many months of long hours building an entirely new tool chain for an entirely new platform, iOS.  Our developers have dedicated the last many months and in some cases years to bring you a product that allows you to build true native apps for Windows, Mac OSX and iOS, something no other company offers.  We do this because it’s fun, exciting and we know you’ll love it! For the first time in many years we’ve released a major version of RAD Studio in a month not called September, how cool is that?  As the rate of technological change continues to accelerate, you can expect Embarcadero to accelerate it’s efforts and releases as well.  Watch for more exciting technology in the months and years ahead. Thank you for your support and we look forward to hearing your thoughts on this exciting new XE4 release. Best regards, Tony
Read More

Delphi Developer Days 2013 Course Book

Over the past month and a half, Bob Swart and I have been writing the material for Delphi Developer Days 2013 (http://www.DelphiDeveloperDays.com). In all we produced seven chapters each. Bob and I each wrote two of the joint sessions, and we each wrote our own four individual sessions. We also each wrote our half of the Tips, Tricks, and Techniques session. This is why the course book has 14 chapters while Delphi Developer Days includes 13 unique sessions.

Loy Anderson, who manages Delphi Developer Days, had given us an early April deadline in order to have the course books printed in time for Chicago. It was a lot of work, but we did it, and Loy worked hard to compile our chapters into a unified book as we finished each chapter. She submitted the book for printing on April 7th, and we fully anticipated getting the books in time for our Chicago event, which begins on May 6th.

To our amazement, the books arrived this week, both those intended for Chicago as well as a European delivery of books for our Frankfurt and Amsterdam events. The book is over 400 pages in length, and we are not talking slideshows here. As you can see in the following picture, our chapters are detailed, and include screenshots and code samples.

Of course, this detail is necessary for our individual sessions. During these sessions, Bob and I break out into separate rooms to present our specific topics. If you decide to go to Bob’s presentation, you can always catch up on my presentation by reading my chapter on the topic in the book. But we feel that detailed chapters are also important for our joint sessions, giving you something to refer back to long after Delphi Developer Days is over.

I am especially pleased this year with our content. Like I have done in the past with Marco Cantù, Bob and I worked hard to create a solid selection of topics that should be of interest to almost every Delphi developer. Some of our sessions cover the absolute latest information on Delphi, including Delphi XE4, which was announced just over a week ago. These talks include iOS development, Delphi’s new NextGen compiler, and FireDAC, the new data access component framework.

There is also plenty of material to engage developers using older versions of Delphi. For example, there are talks on multithreaded development, DataSnap, debugging, browser-based clients, and Windows services. When appropriate, these talks discuss features added in recent versions of Delphi. However, the bulk of the information in these chapters applies to older versions of Delphi (some going back as far as the original Delphi).

In addition to working to find a balance of topics, Bob and I also worked to organize the talks intelligently. For example, talks on data access (including FireDAC) and multithreaded development are presented prior to those on DataSnap (which assumes knowledge about data access and multithreaded programming).

Likewise, we tried to pair our individual presentations in a meaningful way. When one of us is speaking about one of the most recent versions of Delphi, the other is presenting a topic that appeals to developers using older versions. Likewise, we tried to match an Internet-related presentation with one that applies to traditional workstation applications.

Although the book is printed (and in our hands), we all continue preparing for the actual events. Loy has a lot of organizational details to complete, including the printing of name badges and onsite signage, as well as arranging for lunches and our various guest speakers. Bob and I continue to work on our talks, creating our slideshows, and adding to, and improving, the demo projects that we’ll use.

We are really looking forward to this year’s event, and I am looking forward to this first year presenting with Bob Swart. For those of you who have already registered, we look forward to seeing your there. While Chicago has sold out, we still have space available in both Frankfurt and Amsterdam, but we expect these cities to sell out as well. Furthermore, at the time of this posting we still have a 10% discount for early registration in Europe, which ends April 30, 2013. See http://www.DelphiDeveloperDays.com for details and pricing.

Delphi Developer Days is fun, and we are looking forward to it. We hope you are, too.

Read More

Read More

Initial thoughts on Delphi XE4 – iOS development

So the main thrust of my blog entries in the past few years have been about how I've wanted to make the leap from Delphi 6 to the latest version, currently Delphi XE3. As you may have read so far, we're now there and it has brought us so many benefits that I have promised I'll post about later. In the meantime, because of purchasing XE3, I've also been allowed to take part in the beta testing of
Read More

Using sqlite.net with POCO classes

SQLite has become one of the most pervasive embedded databases around.  It's built into Android, iOS and OSX and is a part of many applications.  It has also become the recommended client side database for WinRT applicationsThe go-to solution for using SQLite in .net is sqlite.net.  It’s a simple ORM that comes as one (or two if you want async support) source files.  You can get the full source from github or just the main files from Nuget.  Sqlite.net lets you store nearly any object in the database without needing to descend from a specific type.  However to make it work well, you need to decorate your objects with data attributes denoting primary keys, indexes and so on.For example:       public class Valuation       {             [PrimaryKey, AutoIncrement]             public int Id { get; set; }             [Indexed]             public int StockId { get; set; }             [Indexed]              public DateTime Time { get; set; }             public decimal Price { get; set; }       }On startup, you register your class with SQLite as follows:       var myConnection = new SQLiteConnection ("Stocks.db");       myConnection.CreateTable<Valuation> ();This will check to see if the table exists in the database and create or update it if required.  You can then start using the database in your code.       var valuations = myConnection.Table<Valuation>().Where(...);However for my use case (cross platform application with data objects defined in a portable class library and used in WPF, WinRT and MVC applications), the attribute approach didn’t work.  The nice thing about open source though is that you can always change things…The latest github version of sqlite.net now has an optional argument for CreateTable that allows defining indexes by convention.   Acceptable values are:    [Flags]    public enum CreateFlags    {        None = 0,        ImplicitPK = 1,    // create a primary key for field called 'Id'         ImplicitIndex = 2, // create an index for fields ending in 'Id'          AllImplicit = 3,   // do both above        AutoIncPK = 4      // force PK field to be auto inc    }So to define and register a class, we can now use something like the following:    public class Valuation    {        public int Id { get; set; }        public int StockId { get; set; }        public DateTime Time { get; set; }        public decimal Price { get; set; }    }And then        myConnection.CreateTable<Valuation>(CreateFlags.AllImplicit | CreateFlags.AutoIncPK);This will create the table, make Id into an auto incrementing primary key and add an index for StockId.  To explicitly add additional indexes, use the CreateIndex methods.  E.g.        myConnection.CreateIndex<Valuation>(v => v.Time);The main advantage of this approach is that it lets you separate storage details of the object from it's definition.  This is great for cases when you don't want to, or can't, use the sqlite attributes in the main class.  The main disadvantages are that you have now separated storage from definition, and currently there is no way to set the field size.Sample applications demonstrating both approaches can be found on github.  The sqlite.dll binaries can be downloaded from here.
Read More

SOURCE – DataSnap Photo Album Server & Admin Client

Intro With my previous blog post (http://mathewdelong.wordpress.com/2013/01/24/datasnap-photo-album-server-admin-client/) I shared with you a sample application written in Delphi XE2 using DataSnap to make a client/server application for sharing albums of photos. With this post I want to show you the code and explain parts of it to you. First off, this is where you can download […] … Read More

Read More

More on FireDAC

I’ve yet to pull down and start playing with FireDAC, but it was featured in an Embarcadero event in London yesterday (Thursday). Some points with it were clarified by DavidI, which I thought were quite enlightening: As well as Embarcadero acquiring the intellectual property and all that goes with AnyDAC from DASoft, the original AnyDAC developer, Dmitriy Arefief, is now on a very long-term contract with Embarcadero to keep the development of the product moving forwards. FireDAC is intended as the replacement for dbExpress (DBX). Ultimately dbExpress will be deprecated, but doubtless will still be available for many versions to come (after all, WebSnap is still shipped in the box and hasn’t been focused on for a long time). DataSnap currently relies on dbExpress and Indy. Over time DataSnap will be worked on to make use of FireDAC instead of DBX. FireDAC was attractive to Embarcadero as it covers a much wider range of databases when compared with DBX: Oracle, DB2, SQL Server, InterBase/Firebird, PostgreSQL, MySQL, SQLite, Sybase SQL Anywhere, Advantage DB and Access, along with support for ODBC and dbExpress drivers. It also has a number of useful features, including a performance monitor (ADMonitor), a database explorer (ADExplorer) and a migration tool to convert BDE apps to use FireDAC components. Additionally, I see in the FireDAC FAQ that if you are not yet an XE3 user you can still make use of FireDAC in older IDEs by installing it with a particular command-line parameter. According to Marco Cantù the command-line for installation into XE2 is /IDE:DXE2. However I’m not sure how many versions back are supported. [ Edit: there is now a support article showing how to install into any IDE using the installer’s /showide command-line switch ] Another change with the AnyDAC –> FireDAC transition is the dropping of support for Lazarus/Free Pascal Compiler, so Linux targeting is now out of the question. If you’re a Delphi customer, this is unlikely to ruffle your feathers, but I guess Lazarus users might be more rightfully irked.
Read More

Rakefiles for Delphi

It’s not a secret that I’m a big advocate of Continuous Delivery and I’ve also found that I’ve been using a lot of Ruby and Python development workflow tooling recently because I like those languages in this setting and I find the tools to be relatively easy to use (I recently wrote about Fabric for push deployments). I wanted a build tool to run the builds of my multi-platform targeted Delphi XE2 application because it was getting tedious to publish. As with any Continuous Delivery pipeline, the first step is to map out the steps involved in getting the application to the customer. For this particular application, there were several steps: Build the application in Release configuration for each platform (Win32 and MacOS32) Compile a zip file for each platform Create a manifest XML file with the version for auto-update purposes Upload the applications binary zip files to Amazon S3 Upload the manifest to Amazon S3 Rake is a fairly mature Ruby based build tool which Martin Fowler has written about in the past. There were a couple of articles about using Rake with Delphi, one from Ed Vander Hoek and another from Shawn Oster but they were both a little out of date for my purposes. So I thought I’d cover enough Rake to get you started with a Delphi Rakefile. The msbuild driven versions of Delphi make building your Delphi project considerably simpler than trying to wrangle the appropriate dcc32 flags. If you’re already familiar with Ruby or Python then you will find building Rakefiles much easier. If you’re not familiar with ruby, I’d suggest RubyMonk. To start with, we define a function which will run msbuild after running rsvars.bat to setup the environment: def release_project(project_file, platform) buildcmd = "msbuild #{project_file} /t:Rebuild /p:Config=Release /p:Platform=#{platform}"; result = `"#{RAD_STUDIO_BIN_PATH}\rsvars.bat"&#{buildcmd_win}` if result.include? 'Build succeeded.' puts "Successfully built Windows 32 project #{project_file}" else puts result puts "Our build failed, there were build errors!" raise "Errors during Windows build" end end We can then call put this into a simple rake task to build the Win32 version like this: desc "Builds MyProject.dproj for Win32 in release configuration" task :build_release do puts 'Building Project MyProject.dproj..' release_project('MyProject.dproj', 'Win32') end We can then call this via: > rake build_release We can also list the tasks that rake has via: > rake -T rake build_release # Builds MyProject.dproj for Win32 in release configuration We can adapt this method to enable us to run any DUnit tests and code coverage tests. In order to find the version of our executable, we need to call GetFileVersionInfo on the Windows API. Luckily, there was a StackOverflow question on calling GetFileVersionInfo with Ruby. This gives us something like this: def get_version(artefact_path) require "Win32API" s="" vsize=Win32API.new('version.dll', 'GetFileVersionInfoSize', ['P', 'P'], 'L').call(artefact_path, s) if (vsize > 0) result = ' '*vsize Win32API.new('version.dll', 'GetFileVersionInfo', ['P', 'L', 'L', 'P'], 'L').call(artefact_path, 0, vsize, result) rstring = result.unpack('v*').map{|s| s.chr if s<256}*'' r = /FileVersion..(.*?)\000/.match(rstring) "#{r ? r[1] : '??' }" else raise "GetFileVersionInfoSize returned 0 for #{artefact_path}" end end We can create our zip file in two different ways, we can either use a zip gem for Ruby native creation or we can shell out to a command line version. This function uses the zip gem and takes an array of files to zip and a name for the zip file. def make_zip_distro(files_to_zip, zip_name) require 'zip/zip' Zip::ZipFile.open(zip_name, Zip::ZipFile::CREATE) { |zipfile| files_to_zip.each { |file_to_zip| if File.exists?(file_to_zip) zipfile.get_output_stream(File.basename(file_to_zip)) { |f| File.open(file_to_zip) do |in_file| while blk = in_file.read(1024**2) f << blk end end } else raise "Could not find #{file_to_zip}" end } } end For the manifest file, we can either generate it using Ruby string interpolation or a template system like erb, depending on how complex your requirements are. The final step is the upload all artefacts (the manifest, the artefacts): # You need to define AWS_ENDPOINT, AWS_BUCKET, AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID def upload_to_s3(file, s3_destination) require "aws/s3" if File.exists?(file) AWS::S3::DEFAULT_HOST.replace AWS_ENDPOINT AWS::S3::Base.establish_connection!( :access_key_id => AWS_ACCESS_KEY_ID, :secret_access_key => AWS_SECRET_ACCESS_KEY ) AWS::S3::S3Object.store(s3_destination, open(file), AWS_BUCKET, :access => :public_read) puts "Uploaded #{file} to #{s3_destination}" else puts "Could not file #{file} to upload to S3" end end You will need to define the access keys, secret keys, endpoints and bucket. The next step is to put it into composite parts and draw up a set of tasks. Rake tasks can be standalone or can have prerequisite dependencies: task :my_task => [:dependent_task_1, :dependent_task_2] do # task implementation end Rake tasks can also have parallel prerequisite dependencies like this: multitask :my_task => [:build_task1, :build_task2] do puts "Built all the things!" end Rake tasks can also have parameters, this might be useful if you wanted to pass in a version number manually at build or publish time. Back to our project pipeline from earlier, here are a selection of tasks that wrap everything together: desc "Builds the Win32 release of MyProject.dproj" task :build_win_release do puts 'Building Project MyProject.dproj for Windows' release_project('MyProject.dproj', 'Win32') end desc "Builds the Mac OS X release of MyProject.dproj" task :build_mac_release do puts 'Building Project MyProject.dproj for Mac' release_project('MyProject.dproj', 'MacOS32') end desc "Writes the manifest out to manifest.xml in the current working dir" task :write_manifest => [:build_win_release] do puts 'Writing the update manifest' v = get_version(get_executable_path(:Win32)) write_update_manifest_to(File.join(get_cwd(), 'manifest.xml'), v) end desc "Uploads the manifest to Amazon S3" task :upload_manifest => [:write_manifest] do puts 'Uploading the manifest..' upload_to_s3(File.join(get_cwd(), 'manifest.xml'), 'myproject/manifests/manifest.xml') end desc "Builds the Windows zip distributable" task :make_win_zip => [:build_win_release] do exe = get_executable_path(:Win32) v = get_version(exe) zip_name = 'MyProject-win-' + v + '.zip' make_zip_distro([exe], zip_name) puts "Create zip: " + zip_name end desc "Builds the Mac zip distributable" task :make_mac_zip => [:build_mac_release] do exe = get_executable_path(:MacOS32) # Call get_version on the Win32 executable. If the Win and Mac OS X version numbers # differ, you will need to extract the version from the generated Info.plist instead. v = get_version(get_executable_path(:Win32)) zip_name = 'MyProject-mac-' + v + '.zip' make_zip_distro([exe], zip_name) puts "Create zip: " + zip_name end desc "Uploads all of the zip files" task :upload_zips => [:make_win_zip, :make_mac_zip] do v = get_version(get_executable_path(:Win32)) win_name = 'MyProject-win-' + v + '.zip' mac_name = 'MyProject-mac-' + v + '.zip' puts 'Uploading the win zip version .. ' + v upload_to_s3(win_name, 'myproject/downloads/' + win_name) puts 'Uploading the mac zip version .. ' + v upload_to_s3(mac_name, 'myproject/downloads/' + mac_name) end desc "Builds, zips and uploads the artefacts and manifests" task :release_all => [:upload_zips, :upload_manifest] You can build your releases, create the manifest and upload all with: > rake release_all Simple, repeatable and easy to extend when you have more steps to your pipeline. Further steps for your project might be adding in your acceptance tests or automatically generating and publishing some release notes from your git logs. Other Links Using Rake – An introduction to Rake by Thoughtworker Martin Fowler. Rake RDocs – The official rake documentation. Using rake to automate tasks – A pretty comprehensive introduction to rake tasks. Building Delphi with Ruby – the EDN article from Ed Vander Hoek, including a generic framework for Delphi Rakefiles but which is limited in version support. A Simple Delphi Rakefile – A straightforward rake file for Delphi apps from Shawn Oster.
Read More

Delphi comes of age

18 years ago today Delphi 1 was launched as a revolutionary way of building native compiled, unmanaged, non-interpreted 16-bit Windows 3 applications using UI-driven RAD principles. Today Delphi targets Win32, Win64, OS X and at some point soon will also target iOS and Android. Happy birthday Delphi! Delphi has come a long way in 18 years, but the basic principles of building Windows applications are just the same today as they were then. The VCL library has expanded and grown considerably, and the IDE has had countless useful features and options added to it over the years. It’s easy to miss some of the IDE features or forget a useful keystroke. To help you remember some of the more useful ones, please refer to any of these resources: My blog post Delphi IDE productivity keystrokes from July 2012 where I run through some of my favourite IDE keystrokes, mainly in the code editor. My CodeRage 7 session IDE Productivity Tips & Techniques from November 2012 where I demonstrate some of my favourite IDE keystrokes, mainly in the code editor. Cary Jensen’s Delphi Editor (Updated) Key Combination Table. I spent quite some time working with Cary on this (hopefully) comprehensive “cheat sheet” of keystrokes available from the Delphi editor’s default keymapping. It’s a big list and many of the supported functions are accessible through more than one keystroke combination, which makes the list even longer. If you want to find how to do something in the editor with a keystroke shortcut, this is the resource to refer to.Note that the online Delphi keystroke documentation is unfortunately deficient and errant in various regards. I made a concerted effort to correct those oversights in this updated shortcut collection. Keep using Delphi for your native Windows applications and we’ll still be celebrating Delphi’s birthday for many years to come!
Read More