Objective-C for Delphi users: Property Setters and Getters

Even though Embarcadero did a great job in abstracting the RTL and FireMonkey from iOS specifics in their latest Delphi XE 4 release, there will sometimes be the need to access iOs APIs directly – just like we did with the Windows API. In contrast to the Win32 API, many iOS APIs (not all though) are object oriented. For example there is a UIView class which is the base class for all visual elements. One other prominent class is NSString, which obviously handles strings. (“NS” btw. originates from “NexXTSTEP”, Steve Job’s Operating System that he developed, before he came back to Apple) iOS / Objective-C have (like Delphi) a concept of properties, accessing their values is a little uncommon though: Lets assume we have a Delphi TFoo class, which has a String property name, then you can read and write a Foo’s name like this: LFoo.Name := 'Joe'; LName := LFoo.Name; Once you have an instance of an iOS class and you want to access some property, intuitively you would try like this: var LView: UIView; LMode: Cardinal; begin ... //instantiating UI classes will ... //be covered in a later blog post LMode := LView.ContentMode; //works LView.ContentMode := UIViewContentModeScaleAspectFit; //Does not work The compiler will say “nay” though and it looks like we had a read only property here, which is not the case. The point is that Objective-C has a different syntax for properties. Access to a property ALWAYS goes through its corresponding setter and getter methods. The getter usually has the same name as the property itself. Here we actually call a Getter function ContentMode() : LMode := LView.ContentMode; The setter method is usually named like the property with a “set” as prefix and of course needs to be called like a regular method with one value parameter, like this: LView.setContentMode(UIViewContentModeScaleAspectFit); You will find this pattern in basically all iOS classes that have properties. One might think “why didn’t they add some Delphi magic here?”, but I believe it is better to be close to iOS when accessing their API, so that samples etc from the iOS docs can be applied more directly. Tweet This! Share this on del.icio.us Digg this! Share this on Reddit Get Shareaholic
Read More

Cross platform anonymous threads and progress notification

Reading Anders Ohlsson’s latest blog post about using iOS APIs we don’t wrap reminded me of another couple of helper classes that I created, and which ship with the RAD Studio XE4 samples. The first of these is the TAnonymousThread<T> generic class (in <samples installation directory>Delphi\RTL\CrossPlatform Utils\AnonThread.pas), and is designed to make it easy to create and consume anonymous threads for any activities that will return some kind of result (e.g. fetching data from a remote service). The public API for it is as follows :- TAnonymousThread<T> = class(TThread) public   constructor Create(AThreadFunc: TFunc<T>; AOnFinishedProc: TProc<T>;     AOnErrorProc: TProc<Exception>; AStartSuspended: Boolean = False;     AFreeOnTerminate: Boolean = True); end; As you can see, the interface is pretty straightforward. It takes a series of procedure and function pointers to allow you to specify a function to be run in the thread, a callback procedure which will be run in the main thread so you can process the result, and a callback procedure which will run in the main thread if an exception occurs during thread processing. By default it will not start the thread suspended, and will free the thread on termination (for platforms that don’t have ARC implementations). Here is an example of using this class:- var   lThread: TAnonymousThread<TDataSet>; begin   lThread := TAnonymousThread<TDataSet>.Create(     function: Boolean     begin       //Runs in separate thread       Result := SomeLongRunningMethodReturningADataSet;     end,     procedure(AResult: TDataSet)     begin       //Runs in main thread       SomeMethodToProcessDataInMainThread(AResult);     end,     procedure(AException: Exception)     begin       //Runs in main thread       ShowMessage(AException.Message);     end); end; The second class is the TAsyncProgress<T> generic class (in <samples installation directory>Delphi\RTL\CrossPlatform Utils\Xplat.Utils.pas). Like the TAnonymousThread<T> class, it is designed to run a method returning a result in a separate thread, but has the added functionality of showing notification of a long running process. The public API for this class is as follows:- TAsyncProgress<T> = class   public     class procedure Execute(AFunc: TFunc<T>; AOnFinished: TProc<T>;       AOnError: TProc<Exception>);   end; As you can see, it has a similar interface to TAnonymousThread<T>, and accepts callback methods to handle a threaded function, and methods running in the main thread to process the result, or any exception that may occur during thread processing. Here is an example of using this class:- TAsyncProgress<Boolean>.Execute(   function: TDataSet;   begin     //Runs in separate thread     Result := SomeMethodReturningADataSet;   end,   procedure(AResult: TDataSet)   begin     //Runs in main thread     SomeMethodToProcessData(AResult);   end,   procedure(AException: Exception)   begin     //Runs in main thread     ShowMessage(AException.Message);   end); If you look at the implementation of TAsyncProgress<T> in Xplat.Utils.pas, you’ll see that it leverages the FMX.Platform.TPlatformServices class to register and consume an IPleaseWaitService interface. This interface has the following signature:- IPleaseWaitService = interface   procedure StartWait;   procedure StopWait; end; I have created an implementation of this interface for iOS in iOS.Services.pas, and for OSX in Mac.Services.pas. The iOS implementation uses the technique that Anders blogged about to show the network activity indicator in the iOS status bar, but it also uses the UIActivityIndicatorView class to show a spinning progress indicator in the centre of your application view. Similarly the OSX implementation uses the NSProgressIndicator class to show a spinning progress indicator in the center of your main OSX application view. To register an implementation for a given platform, simply add the relevant *.Services.pas file to your project. In addition to leveraging the IPleaseWaitService interface via the TAsyncProgress<T> class, you can also interact with this service directly using helper methods in XPlat.Utils.pas, by utilizing the following:- //Returns an instance of the IPleaseWaitService registered for the current platform function PleaseWaitService: IPleaseWaitService; //Runs the specified procedure (unthreaded), using the IPleaseWaitService interface to //indicate execution progress. procedure ProgressProc(AProc: TProc); //Wraps a call to IPleaseWaitService.StartWait, if the service has been registered procedure StartWait; //Wraps a call to IPleaseWaitService.StopWait, if the service has been registered procedure StopWait; There are sample applications for iOS showing how to consume the TAnonymousThread<T> and TAsyncProgress<T> classes located in <samples base>Delphi\RTL\CrossPlatform Utils\AsyncProgress/AnonymousThread.dproj and <samples base>Delphi\RTL\CrossPlatform Utils\AsyncProgress/AsyncProgress.dproj respectively. Share This | Email this page to a friend
Read More

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