EDN Mobile: Maintenant avec la localisation française!

Thanks to a totally unsolicited email from EDN community member Whiler, I am pleased to announce that EDN Mobile now supports the French locale.

I now invite other community members to provide localizations in any of the supported languages. As of Android 4.0.3, this list is available here. The localization process is pretty simple, and involves […] … Read More

Read More

Last Chance for Delphi Developer Days 2012

If you haven't already signed up for this year's Delphi Developer Days with Marco Cantù and me, your opportunity is quickly slipping away. We begin the last leg of our six city tour in just two weeks, and the Frankfurt event is already sold out. This means that our event in Rome, on May 17th and 18th, is your last chance to attend Delphi Developer Days this year.As in the past, the response this year has been fantastic. It has been especially fun given all the new features that shipped with Delphi XE2. Marco's extensive exploration of the new FireMonkey component library has been one of the most favored tracks, and I have received a lot of positive feedback about my sessions on LiveBindings and DataSnap. Our attendees have also given high marks to our examinations of Delphi's wide range of database capabilities and options for building Internet-based applications. There's also a healthy dose of iOS development, with examples of applications built for iPads (and iPhone) as well as Android devices.But just because there's a lot of new features in Delphi doesn't mean that we're ignoring earlier versions. I have had consistently large audiences for my ClientDataSet and Unicode sessions. Likewise, Marco's session on RTTI (runtime type information) and Attributes, as well as his dbExpress Deep Dive session have also been high on many of our attendee's lists.If you've been to one of our Delphi Developer Days events in the past, you already know about the course book that each attendee receives. The book contains papers for every one of the sessions that we present, which is especially valuable when you consider that half of our sessions are breakout sessions, meaning that you have two choose between Marco's presentation or mine. The extensive course book means that you don’t miss a thing.This course book is almost 450 pages in length, and we're not talking about slide reproductions here. Each paper is narrative in style and contains detailed explanations and code samples. Indeed, the course book is larger than most Delphi books you can buy. Consider this, my last book, Delphi in Depth: ClientDataSets, which is 350 pages in length, contained around 85,000 words. Our Delphi Developer Days course book is almost 150,000 words in length. That's a big book, and its only available to attendees.As I said, the response has been terrific. Not only have we sold out Frankfurt, but Chicago was sold out as well, and Amsterdam got close. The Rome location is very convenient. It is a short 200 meters walk from the Termini Train station in central Rome, and there are trains from Roma Ciampino Airport (15 minutes travel time) and Leonardo da Vinci-Fiumicino Airport (30 minutes travel time) throughout the day.In case you need additional reasons to come to Rome, here are two more. Daniele Teti of BitTime is our guest speaker in Rome. There he will present his talk titled "Improving Code Testability Through Dependency Injection," a talk I am looking forward to with great anticipation. And if that weren't enough, Marco Cantù will personally guide a walking tour of Rome for all who are interested after the first day of sessions.For more information on Delphi Developer Days, and to register for Rome, please visit http://www.DelphiDeveloperDays.com. I hope to see you there!
Read More

FireMonkey Development Setup for iOS: Delphi XE2 Update 4

Introduction

This topic shows how to setup FireMonkey Development environment for iOS – Apple’s mobile device platform for iPhone, iPAD or iPod touch.

To continue installation, Xcode 4.2 should be ready in Mac OS X machine.

Install FireMonkey – iOS SDK

The FireMonkey iOS SDK is available in Delphi XE2 folder FireMonkey-iOS.  The following folder is a shared folder from VMware machine: %ProgramFiles(x86)\Embarcadero\RAD Studio\9.0:

Locate FireMonkey-iOS.dmg disk image in the folder:

Open or mount the disk image:

Install both packages in the following sequence:

  1. fpc-2.6.0.intel-macosx.pkg
  2. FireMonkey-iOS-XE2.pkg

A new folder: Embarcadero should be created in Developer folder:

The FireMonkey iOS SDK is ready for Xcode to compile FireMonkey iOS project now.

Reference

  1. FireMonkey Development Setup for iOS. URL: http://docwiki.embarcadero.com/RADStudio/en/FireMonkey_Development_Setup_for_iOS

Read More

Read More

DataSnap iOS Mobile Connectors and case sensitive file names

Delphi XE2 Update #4 was released a few weeks ago, and actually introduced a new features: adding Mobile Connectors support for FreePascal for iOS 4.2 and 5.0, although not without a little issue that may confuse some people (and demos)... DataSnap REST Applications that export mobile connectors, can be used to download an archive with proxy source code and support units.
Read More

iOS 5.1 device upgrade gotchas

Earlier this week, I used a Mac Mini with OS X 10.6.8 (Snow Leopard) and Xcode 4.2 with iOS SDKs and devices support ranging from 4.2.1 and 4.3 to 5.0 - before my iPhone alerted me that a minor software update to iOS 5.1 was ready to be installed. This blog post is mainly meant to "warn" Delphi XE2 FireMonkey for iOS developers who have not yet upgraded their iOS devices to 5.1.
Read More

Flotsam and Jetsam #57

I asked this on Twitter, and I’ll ask it here as well:  Does this sound right to everyone? You put things into a list/collection, but you always get them out with an IEnumerable.  (Delphi Spring has such a beast, in case you were wondering…) Apparently Dr. Evil can’t use JSON, as the license – literally – doesn’t allow it.  I wonder if the Wikipedia Patrol will let the last entry on this page stand.  In my experience, the denizens of Wikipedia can be……rather zealous.  So far so good. Hey, I’d like to give a shout out to a staunch Delphi supporter and good guy,  Eko Indriyawan. He’s an Embarcadero Partner and provides RAD Studio training.  If you are in the Southeast Asian region, look him up. DevExpress has published their roadmap for 2012, and of course, it includes information about what they are planning for their VCL controls.  I for one appreciate DevExpress’s continued support of VCL. Make sure you get Update 4 to the RAD Studio Help. As noted above, I have a love/hate relationship with Wikipedia – mostly love – but this kind of entry makes it all worthwhile: Rubber Duck Debugging I myself have solved many a problem by merely typing up a question for StackOverflow or a forum, but the image of a guy talking to the rubber duck is just priceless. (Tip of the cap to Coding Horror) And it seems that RAD Studio’s Update 4 caused some problems with the rendering of fonts in FireMonkey, so it looks like a Hotfix to Update 4 (Update 5?) is in the works.  Here’s an interesting little tidbit that happened to me this week.  I did a “deep system cleansing” on my machine, and decided to change email clients for my nickhodges.com address.  I downloaded and installed Thunderbird, but it absolutely refused to connect to my mail server. Neither the auto-detect nor manual entry would fetch my mail.  So I downloaded Eudora Open Source Edition – which is apparently the same codebase as Thunderbird somewhere back in the history of things – and that worked like a charm.  Eudora OSE detected my settings and had me up and running in about a minute.  Huh.
Read More

FireMonkey Fonts and Native Look & Feel

Since XE2 Update 4 was released, there have been a few online complaints (1, 2) about FireMonkey's fonts on Windows.  I had most of a blog post written explaining why it actually was fine, when I read that there will be a hot fix targeting this and other issues.  I guess it is an issue after all, then! But when it comes to FireMonkey's text, there are more important things than antialiasing or
Read More

Test Driven Development in Delphi: The Basics

I intend to write a Test Driven Development (TDD) series, targeted for Delphi developers. I will use DUnit, the unit testing framework for Delphi.Note folks that the purpose of this is NOT to discuss the Pros and Cons of TDD, Unit Testing or whatsoever. The purpose is just to give a few examples. I would love if you help me when the complexity starts climbing.If needed, for a quick understanding of what TDD or Unit Testing is, refer to the links above, or check out the book at the end of the article.In TDD you don’t write the application code first, instead you write the test cases first. The TDD cycle is as follows:At the beginning you just write one test, and later on, more tests can be added.Make sure the initial test fails; this will validate the test harness. Write some code to pass the test. Important: don’t over-code. Just add the code needed to pass the test and period. The code does not have to be elegant at this point.Run the test: if it fails, then you have to go back to step 3 and fix your code in order to pass the test. When you succeed, then move on to step 5.Improve and optimize your code: make it elegant, more efficient, avoid duplications, etc, etc. This is called code refactoring.When refactoring your code, maybe, by accident, you break the functionality. How can you be sure that everything is working as it should? Just re-run your test and it will tell you if the previous refactoring introduced a failure or not.Go to step 1 and add a new test if needed.The example: let’s consider the chess game. The goal will be to implement the code to verify whether a piece is placed in a valid position within the board. We are only going to implement one test: SetPositionTest.I will number the columns (X coordinate) from 1 to 8 starting at the bottom left-hand corner. In the same way, I will number the rows (Y coordinate) from 1 to 8 starting at the bottom left-hand corner. 87654321 2 3 4 5 6 7 8 For a step by step tutorial of how to use, configure and setup DUnit you can read the English or Chinese versions of the tutorial.Initially, the testing code should look like this:unit ChessPiecesTests;interfaceuses   TestFrameWork;type  TPieceTest = class(TTestCase)  published    procedure SetPositionTest;  end;implementationuses  ChessPieces;{ TPieceTest }procedure TPieceTest.SetPositionTest;beginend;initialization  TestFramework.RegisterTest(TPieceTest.Suite);end.If you run that test, it will succeed since no checks are being performed within the SetPositionTest procedure. Each test is composed by one or more checks. I suggest adding the checks little by little. Every time you add a check, you should add business code to pass the corresponding test.Now, let’s make the test fail on purpose. For that, let’s add one check to the SetPositionTest procedure. procedure TPieceTest.SetPositionTest;begin  Check(True = False, '');end;True is never False. So, this test will fail. If it doesn’t fail, then something is wrong with you test harness. Fix it. You can remove this initial check once you run the test and it fails.Now, let’s add a real check to our test. Something like this:procedure TPieceTest.SetPositionTest;var  Piece: TPiece;begin  Piece:= TPiece.Create;  try    //Test trivial (normal) workflow    Check(Piece.SetPosition(4, 4) = True, '');  finally    Piece.Free;  end;end;If you run this test, you will get a compilation error! Yes, that’s right. You don’t have business code yet. You just have the test. This is what TDD is all about: test first, business code later. Get the point?To avoid the compilation error, we will code a separate unit (ChessPieces) and we will add it to the uses clause of our ChessPiecesTests unit. unit ChessPieces;interfacetype  TPiece = class  private  public    function SetPosition(aX, aY: Integer): Boolean;  end;implementation{ TPiece }function TPiece.SetPosition(aX, aY: Integer): Boolean;beginend;end.Run the test again and now the compilation error is gone. Nonetheless, the test fails, because the Piece.SetPosition(4, 4) evaluates to False. Let’s add the minimum business code possible to pass this test:function TPiece.SetPosition(aX, aY: Integer): Boolean;begin  Result:= True;end;This passes the test. What? Yes, this passes the test, right? OK, what now? Well, we keep adding new checks to the test and every time this happens, we need to add new business code in order to pass it. It is very important to add checks to test the boundaries of whatever we are trying to code. I think you are getting the point, so I will just add a bunch of checks at once:procedure TPieceTest.SetPositionTest;var  Piece: TPiece;begin  Piece:= TPiece.Create;  try    //Test trivial (normal) workflow    Check(Piece.SetPosition(4, 4) = True, '');    //Tests boundaries    Check(Piece.SetPosition(1, 1) = True, '');    Check(Piece.SetPosition(1, 8) = True, '');    Check(Piece.SetPosition(8, 1) = True, '');    Check(Piece.SetPosition(8, 8) = True, '');    //Test beyond the boundaries    Check(Piece.SetPosition(3, 15) = False, '');    Check(Piece.SetPosition(3, -15) = False, '');    Check(Piece.SetPosition(15, 3) = False, '');    Check(Piece.SetPosition(15, 15) = False, '');    Check(Piece.SetPosition(15, -15) = False, '');    Check(Piece.SetPosition(-15, 3) = False, '');    Check(Piece.SetPosition(-15, 15) = False, '');    Check(Piece.SetPosition(-15, -15) = False, '');  finally    Piece.Free;end;The test above is even checking for the attempts of positioning a piece outside the chess board.To pass that test let’s write some business code:function TPiece.SetPosition(aX, aY: Integer): Boolean;begin  Result:= True;  if (aY < 1) or (aY > 8) then Result:= False  else if (aX < 1) or (aX > 8) then Result:= False;end;Run the test and see how it passes. The code above could be refactored or even rewritten. The tests will remain the same, allowing us to catch any bugs introduced with the code change.For instance, we could write the procedure above as follows:function TPiece.SetPosition(aX, aY: Integer): Boolean;begin  Result:= (aX > 0) and           (aX < 9) and            (aY > 0) and           (aY < 9);end;Run the test, and it will tell you if this refactoring (or reimplementation) works ok. It’s important to note that a good test should cover all possible scenarios and workflows. Pay special attention to the boundaries. At this point, a good understanding of the requisites is indispensable. Finally, more and more tests will be needed in a real world application. Each test will have its own checks. Each test will cover one piece of the functionality: this is what unit testing is intended for.I wrote a second article about TDD, code refactoring and design patterns in Delphi (click here). I would appreciate any comments you could provide about it.For further reading I recommend you Test Driven Development: By Example by Kent Beck. Check it out just below:CodeProject
Read More

Delphi/ C++Builder XE2 Update #4 issues

On Wednesday, February 29th 2012, Update #4 for Delphi XE2 and C++Builder was released, see also http://cc.embarcadero.com/item/28758 for the new ISO (which unfortunately is only available for those who already registered XE2, and not for "new" users who need a first install). It is great that Embarcadero is still using a frequent update schema, especially for FireMonkey issues, so I always welcome these updates.
Read More

LiveBinding Expression Can Produce Side Effects

I’ve been looking for a simple LiveBinding example that would forever change the way we perceive LiveBindings, and I think I found it. But let me start with a little background.

I’ve been interested in LiveBindings since RAD Studio XE2 shipped. One obvious reason is that LiveBindings is important if you want to easily bind your FireMonkey controls to traditional Delphi DataSets. But there was something else, something that I had a hard time putting my finger on.

I had a conviction, one that I shared publicly, that LiveBindings represented a fundamentally different way of doing things, and that we, as developers, just needed to see some examples of this new usage. Once we did, I thought, we would collectively come to a new way of looking at LiveBindings. These examples, however, have been elusive.

I remember David Intersimone (David I) asking me, prior to my 24 Hours of Delphi broadcast, to show LiveBindings used in a new and different way. I would have loved to, but I had yet to see such an example. I even blogged about this last month (http://caryjensen.blogspot.com/2012/01/whats-your-favorite-livebindings.html), asking readers to submit their favorite LiveBinding example that would open our eyes to the new way of doing things.

The response to that blog was interested. First of all, not one reader submitted a LiveBinding example. What I did get were some thoughtful comments about the limitations of LiveBindings, and these were similar to comments that I heard following my 24 Hours of Delphi presentation, as well as after a talk I gave at the Software Development Event in the Netherlands this past December.

Of these comments, the most common was that LiveBindings simply provide us with another way of doing something we already do, but in a more complicated way. Once again, I really felt like this opinion simply reflected the fact that we had not yet seen LiveBindings used in that way that would redefine, in our minds, what LiveBindings can do and how they can be used.

I recently wrote a white paper for Embarcadero on LiveBindings for their RAD in Action series. While doing so I had the time to reflect extensively on LiveBindings, including their limitations as they currently stand in this first release.

It was after I submitted the first draft for review that the example I am going to show came to me. In his technical edit, Jim Tierney pointed out that I failed to recognize that LiveBinding expressions could invoke methods of objects accessible in the input or output expression scope. I don’t know why I overlooked this. He had mentioned this fact in one of his CodeRage 6 talks. I had simply forgotten. (And there is a trick. The method must uses parentheses, even if it has no parameters.)

As I re-wrote that particular section of the paper I had an inspiration. To be honest, this inspiration came at 2:00am in the morning, as inspirations often do. That pretty much ruined my night’s sleep, as I could not wait to try what I now imagined a LiveBinding doing.

Here is the basic concept, and then I will show you a simple application. LiveBindings can produce side effects. That’s it.

Sure, even this notion is not unique. I’ve seen several LiveBindings that assign a value to the ControlComponent’s target property (the output expression), and that property has caused side effects (side effects being one of a property’s magical features). But my idea, one that I had not seen before, was that you could invoke in your SourceComponent’s SourceExpression (the input expression) a method that could, as part of its execution, produce a side effect.

Here is my simple example for your consideration. Take a look at this form, which is available in the code sample that accompanies my LiveBinding white paper.

Notice the Button on this form, the one whose Caption reads Close. This button, and another on another TabSheet of the PageControl, are associated with an ActionItem. This ActionItem has associated with it a BindExpression LiveBinding, which is a managed LiveBinding. Since it is a managed LiveBinding, there must be some code that triggers the expression engine to evaluate the LiveBinding expressions, and here is that code, associated with the ActionItem’s OnExecute event handler.
procedure TForm1.Value1EditChange(Sender: TObject);
begin
BindingsList1.Notify(Sender, '');
end;

Let’s now look at the Object Inspector, which shows the properties of the BindExpression LiveBinding.

The ControlComponent and the SourceComponent properties are both set to the ActionItem. The ControlExpression (the output expression) is Caption, a property of the ActionItem. The magic occurs in the input expression (SourceExpression). In this expression is a method invocation, which I’ve associated with the form (the ActionItem’s owner). This method, OpenCDS, produces a side effect, the opening and closing of a ClientDataSet, as you can see in the following implementation.

function TForm1.OpenCDS(Open: Boolean): string;
begin
if Open then
begin
ClientDataSet1.Open;
ClientDataSet1.LogChanges := False;
exit('Close');
end
else
begin

ClientDataSet1.SaveToFile;
ClientDataSet1.Close;
exit('Open');
end;
end
;

As you can see, when the user clicks the button, the expression engine is notified to evaluate the LiveBindings associated with Sender, which is the ActionItem in this case. The SourceExpression calls the OpenCDS method, which returns a new value for the Caption property of the ActionItem. This, in turn, causes the two buttons that are using this action to likewise adopt the caption. It also performs the rather simple side effect of closing or opening the ClientDataSet. However, there are really very few limits to the side effects that could have been implemented.

I am sure that more than a few people will be thinking to themselves that this is just another example of a LiveBinding that does something we can already do (open and close a ClientDataSet). For example, couldn’t we have simply used the following OnExecute event handler?

procedure TForm1.Value1EditChange(Sender: TObject);
begin
if
TActionItem(Sender).Caption = 'Open' then
begin
ClientDataSet1.Open;
ClientDataSet1.LogChanges := False;
TActionItem(Sender).Caption := 'Close';
end
else
begin

ClientDataSet1.SaveToFile;
ClientDataSet1.Close;
TActionItem(Sender).Caption := 'Open';
end;
end
;

My response to has three parts. First, the second event handler, the one that explicitly opens and closes the ClientDataSet, needs to have intimate knowledge of what operation has to be performed. By comparison, the first event handler simply notifies the expression engine that something about the Sender has changed. The first event handler has no details about the change, nor does it specify what should happen in response. The expression engine does the actual assignment based on the LiveBinding, and the LiveBinding, not code, defines what happens.

Second, not all LiveBindings require that you notify the expression engine. Many of RAD Studio’s LiveBindings, including Lists and Links, require no event handlers at all.
Third, for those LiveBindings that do require an event handler, all of them could potentially refer to this one, simple event handler, the one that calls the Notify method of the BindingsList. As a result, a form that uses LiveBindings to perform its various tasks may have zero or just one event handler. By comparison, if you performed those tasks using code, there would have to be many different event handlers, each one invoking its specific task and requiring specific knowledge about the operation they were designed to produce.

Basically what I am getting at is that this usage of a LiveBinding is profoundly different than normal event handler usage. The OnAction event handler is completely agnostic, as far as the operation that will result from its invocation. All of the behavior is defined declaratively in the LiveBinding, along with the actions defined in any methods that are invoked during the evaluation of the SourceExpression. What’s even more exciting is that in the future this type of effect might be achieved without any event handlers at all.

But please do not get me wrong. I am not advocating that we should start replacing traditional event handlers with LiveBindings. That would be completely missing the point. LiveBindings have their place, and event handlers have their place as well.

Successful use of LiveBindings requires us to look at our goals from a different perspective. LiveBindings can do things that really don’t fit into the event-driven model of traditional event handlers. Sure, in this version of RAD Studio they are somewhat limited, but that will change over time.

I have one final comment. Earlier in this posting I noted that invoking a method that produces side effects from a LiveBinding expression is similar to the power of side effects produced by property accessor methods. Actually, these two techniques are more closely related than you might think. When designing a new class, you might actually implement a side effect in a property accessor method, and a LiveBinding could then produce that side effect as a result of its assignment of data to the associated property.

On the other hand, side effects produced by property accessor methods are often associated with keeping the internals of that component consistent. By comparison, the types of side effects that you can introduce in methods invoked through LiveBindings can have a much more global impact, keeping many elements of a form, or an entire application, synchronized.

The white paper is available from Embarcadero’s Web site at http://edn.embarcadero.com/article/42076.

I am also giving a Webinar on LiveBindings in the RAD in Action series on March 14th. You can learn more about this Webinar at http://www.embarcadero.com/rad-in-action/livebindings.

I am also doing a session on LiveBindings during my Delphi Developer Days 2012 tour with Marco Cantù. Learn more at http://DelphiDeveloperDays.com.

Read More

Read More