Earlier this year I wrote a simple iOS client for Delphi Feeds RSS and Embarcadero blog RSS feed. The program I showed to some live events and webinars, uses the IdHTTP client component to retrieve the data and the XMLDocument component to parse it and populate a ListBox with details on each line (using the proper FireMonkey style).
Here you can see the application at design time (with the Android layout enabled):
The source code is rather long as it has shared code and some alternative options for the two incompatible feeds. I think it is worth listing it, because while nothing big it manages HTTP connections, strings, XML data, parses the XML, populates user interface controls directly, and more:
procedure THeaderFooterForm.RefreshFeeds (fSource: TRSSFeedSource); var strUrl: string; strXml: string; title, author, pubDate, url: string; I: Integer; ChannelNode, ItemNode: IXMLNode; ListBoxItem: TListBoxItem; TargetList: TListBox; LabelStatus: Tlabel; begin case fSource of fsDelphiFeeds: begin strUrl := 'http://feeds.delphifeeds.com/delphifeeds'; TargetList := ListBoxDelphi; LabelStatus := LabelStatusD; end; fsEmbarcaderoBlogs: begin strUrl := 'http://blogs.embarcadero.com/feeds/wpmu-feed/'; TargetList := ListBoxEmbt; LabelStatus := LabelStatuse; end; end; try strXml := IdHTTP1.Get (strUrl); except on E: Exception do begin ShowMessage ('Error: ' + E.Message); Exit; end; end; XMLDocument1.LoadFromXML(strXml); XMLDocument1.Active := True; LabelStatus.Text := 'Processing RSS'; LabelStatus.Repaint; TargetList.BeginUpdate; try TargetList.Clear; ChannelNode := XMLDocument1.DocumentElement.ChildNodes.FindNode ('channel'); for I := 0 to ChannelNode.ChildNodes.Count - 1 do begin ItemNode := ChannelNode.ChildNodes[I]; if ItemNode.NodeName = 'item' then begin LabelStatus.Text := 'Processing Node ' + I.ToString; title := ItemNode.ChildValues ['title']; pubDate := ItemNode.ChildValues ['pubDate']; case fSource of fsDelphiFeeds: author := ItemNode.ChildValues ['author']; fsEmbarcaderoBlogs: author := ItemNode.ChildValues ['creator']; end; url := ItemNode.ChildValues ['link']; ListBoxItem := TListBoxItem.Create(TargetList); ListBoxItem.Text := title; ListBoxItem.ItemData.Detail := author + ' - ' + Copy(pubDate, 1, 11); ListBoxItem.TagString := url; TargetList.AddObject(ListBoxItem); end; end; finally TargetList.EndUpdate; end; LabelStatus.Text := 'RSS Processed'; end;
Again, while nothing particularly complex there is some serious code in this snippet. The code happens to work and compile perfectly also on Windows, but the user interface looks quite ugly (good for debugging, though). This program could be compiled and run on iOS with Delphi XE4, producing an output like the following:
Now comes the interesting part. I opened this project in the current internal build of the coming version of Delphi, which includes Android support, added the Android target, changed the design time view to Android (as in the first screen shot above), opened the Project Options, enabled the Internet permission for the app, compiled and executed the app on my connected device (a Google Nexus 4). And I got the image below, not quite identical in the UI to the iOS one (as expected):
The user interface is distinctively different and the app does look and behave differently, but I didn't have to change a single line of source code in the application logic or in the user interface of my application (form design included). Let me repeat this, as it seems a few people are having a hard time understanding: I didn't have to change a single line of source code in the application logic or in the user interface of my application (form design included) to move it form iOS to Android. Now which other development tool (save for those based on JavaScript, which don't produce exactly native apps) can do this?
Single source development for iOS and Android, with natively compiled code, and including the user interface design, is going to happen real soon. And you can still compile the same for Windows and Mac as a bonus. And the tool in question is indeed Delphi!
Stay tuned.