RAD Studio XE4 World Tour – Canadian Dates

In case you've missed it, Embarcadero's Rad Studio XE4's launch tour will be in Montreal and Toronto on June 5th and 6th. Montreal, QC Wednesday, June 5, 2013 @ 6:00-8:00PM Hôtel Europa Register for Montreal Toronto, ON Thursday, June 6, 2013 @ 6:00-8:00PM Northern District Library Register for Toronto Welcome to this RAD Studio event focusing on iOS development.RAD Studio is the
Read More

XE Plus Pack – Release 12 (XE4 Support)

Release 12 of XE Plus Pack is now available for download which includes XE4 support. Users can download the required version from the download page. To try XE4 Plus Pack download the trial version. Users of XE2 Plus Pack and XE3 Plus Pack can use their existing registration details to unlock XE4 Plus Pack. New in Release 12 (for all) Smart Desktops Allows you to synchronize your desktops between computers and installations. This is just the first part of the Smart Desktop feature, with additional features being added in future releases. http://www.jed-software.com/help/SmartDesktops/SmartDesktops.html New in Release 12 (for XE4 only) - Component editor for the TTabControl FireMonkey component that allows you to switch between pages using the form designer context menu, or a link at the bottom of the object inspector.
Read More

Konopka Answers The FireMonkey Question At Code Rage 7

I did not attend Code Rage 7 but I just learned that Ray Konopka is working on a set of FireMonkey tools. He has not published a date as to when this tool set will be available but I'm glad to hear he's working on one. Here is the Code Rage 7 video that loads at 36 minutes and 2 seconds right where the FireMonkey question gets asked:Ray Answers The FireMonkey Question At Code Rage 7Semper Fi,Gunny Mike
Read More

More APNS info (in pictures)

A little bit of clarification on my APNS blog post(s) comment threads…
Deployment tab – notice IDE maintained file UNCHECKED – your file – CHECKED – remote name – Entitlements.plist:

Provisioning tab (specify the first two, hit Load ID):

Version Info tab:

Anders.entitlements file:
<?xml version=”1.0″ encoding=”UTF-8″?>
<plist version=”1.0″>
<dict>
<key>application-identifier</key>
<string>XZ9AC2Q82Q.com.AndersOhlsson.FMX.01</string>
<key>aps-environment</key>
<string>development</string>
<key>get-task-allow</key>
<true/>
</dict>
</plist>
Enjoy!
Share […] … Read More

Read More

XE4 Upgrade Decision

I'm currently using Delphi 2010 Professional and it's time to make that upgrade decision . . . again. The first decision I had to make was should I upgrade to Rad Studio XE4 or Delphi XE4. I've decided to upgrade to Delphi XE4. Now I have to decide which version of Delphi XE4 should I go with, Professional Upgrade ($494.10) or the Enterprise Upgrade ($1,349.10).  That's a difference of $855. So I decided to study the Delphi XE4 Feature Matrix.The Professional version has three different Optional features:1 Requires purchase of Mobile Add-On Pack for Professional2 Requires purchase of FireDAC Client/Server Pack for Professional3 Requires purchase of Mobile Add-On Pack for Professional for use with mobile apps. Requires purchase of FireDAC Client/Server Pack for Professional for use in Windows and Mac apps.Each one of Optional features requires a separate purchase:1. Mobile Add-On Pack for Professional ($494.10)2. FireDAC Client/Server Pack for Professional ($399.00)3. Both of the above ($848.10)For me, Chances are I'd have to purchase the above tems if I went with XE4 Professional. However, the above items are included in the Enterprise version of XE4. So that makes the difference a whopping $6.90.With XE4 Enterprise you also get Additional UML MODELINGdbExpress drivers available for 64-bit Windows InterBase, Firebird, Oracle, MySQL, SQL Anywhere, Informix, and SQLitedbExpress drivers available for OS X InterBase, Firebird, Oracle, MySQL, SQL Anywhere, Informix, and SQLiteTSQLMonitor support for SQLiteDataSnap Mobile Connector support for latest versions of iOS, Android and BlackBerrySeveral dbExpress server connectivity versionsDataSnap capabilityA couple additional BizSnap piecesSome IntraWeb piecesSo, given my track record for slow upgrades it looks like the best choice for me is the upgrade to Delphi XE4 Enterprise.Note: The prices quoted came from embarcadero's website store on 05/19/2013. Semper Fi,Gunny Mike
Read More

DX.Library : Utility functions for iOS (and other platforms) available via SVN

I just created a DX.Library SubVersion repository at Google and uploaded our DX.Apple.Utils.pas unit as first action. As a start three functions are available: Note: there is a dependency to Apple.Utils.pas (and later maybe to other units in the same directory), which ships with XE4, but is NOT in the default library path. That unit can usually be found here: C:\Users\Public\Documents\RADStudio\11.0\Samples\Delphi\RTL\CrossPlatform Utils /// <summary> /// Logs to the console /// </summary> procedure NSLog2(const AMessage: string); /// <summary> /// Retrieves the vendor specific device ID - DO NOT USE UIDevice.uniqueIdentifier - this would lead to AppStore rejection since May 1st, 2013! /// </summary> function VendorIdentifier: string; /// <summary> /// checks if the given URL can be openend by any App on the device /// This is for custom URL schemes like fb://profile/omonien, which would open /// the Facebook app - if installed on the device - and navigate to the given profile /// </summary> function CanOpenURL(AURL: string): boolean; Contributions are welcome. All code is licensed under The MIT License. Tweet This! Share this on del.icio.us Digg this! Share this on Reddit Get Shareaholic
Read More

iOS OpenURL – Not just for HTTP URLs

Anders just recently blogged about how to open Safari from your iOS Delphi app and showed how to incorporate Cleggy’s Apple.Utils.pas unit to make it just as simple as: OpenURL(‘http://www.embaracdero.com’); The interesting point is now, that this would also work for other apps. If you want to open the iPhone Messenger for example, then just do this: OpenURL(‘sms:1-408-555-1212′); This also works with 3rd party Apps, you can open the Facebook app like this: OpenURL(‘fb://profile’); But what if the App is not installed or not available (like on the iOS simulator)? OpenURL will do just nothing, which is kind of stupid, you might want to do something as alternative probably. For that reason there is CanOpenURL (which is not yet in Cleggy’s unit). That just returns true or false indicating if the required app is available. This is how you would implement/call it - Update: CanOpenURL is now in DX.Library uses Apple.Utils; function CanOpenURL(AURL: string):boolean; begin result := SharedApplication.canOpenURL(StringToNSUrl(AURL)); end; Here are a couple of links where you find information about available URL schemes: Apple URL Schemes Misc URL Schemes from AKOSMA Wiki Tweet This! Share this on del.icio.us Digg this! Share this on Reddit Get Shareaholic
Read More

iOS: Identifying Your Users Devices – A Recipe How to Import iOS Classes

You might want to identify your users devices, for example to bind that information to some licensing mechanism. In earlier iOS days, you would have used UIDevice.uniqueIdentifier for that. That ID is unique for every iOS device out in the wild (well maybe except jail broken ones). Due to privacy concerns usage of that ID has been deprecated with iOS 5.0, and since May 1st, 2013 Apple imposes a no-usage policy. In other words if you use that id in your apps, apple will just reject your app from App Store  approval. The new way to identify your users devices is to use UIDevice.identifierForVendor. That is still a unique identifier, but it is also unique per vendor. In other words your Apple Developer Account gets tied into that ID’s calculation, so that your own apps can identify all your users devices, even between apps. Other vendors/developer get different ids for the same device though. Ok, so far so easy. If you want to use identifierForVendor from Delphi XE4 though, you will find, that it has forgotten to be imported. UIDevice as declared in iOSApi.UIKit.pas just doesn’t know about that function. This made me try to import it on my own, and that worked pretty easy for me. There was an additional obstacle (the required class NSUUID does also not exist in XE4), but that was also easy to fix. I started with a DX.Apple.Utils.pas helper unit, which will grow over time and for now does exactly two things: Provide a Delphi NSLog2 function, which directly maps to Apple’s NSLog function, which will log to the console. Provide a VendorIdentifier function which does what its name says The most current version can be checked out anonymously from a SubVersion repository hosted at Google. Below is the full source, which I will probably put into a public SVN –  eventually. That source basically contains the recipe how to import (even partial) classes from iOS into Delphi. unit DX.Apple.Utils; interface /// <summary> /// DX.Apple.Utils is a helper library to get easier acces to certain Apple Mac/iOS functions. /// </summary> /// <description> /// This library also imports certain classes or parts of them which have been "forgotten" by EMBT /// The code is intended to be used with Delphi XE4 only. Other versions may or may not work. /// There is a dependency to AppleUtils.pas, which ships with XE4 and can usually be founc here: /// C:\Users\Public\Documents\RAD Studio\11.0\Samples\Delphi\RTL\CrossPlatform Utils /// Make sure use the most recent version - that samples folder above /// is connected to an SVN repository of Embarcadero. /// </description> /// <remarks> /// <para> /// DX.Apple.Utils is Copyright 2013 Olaf Monien / Developer Experts, LLC. /// </para> /// <para> /// All code comes "as is", without any guaranties granted. This code may contain bugs and my not work as advertised. /// </para> /// <para> /// RESTClient is licensed under Mozilla Public License 2.0 /// In other words you are free to use this library in your projects, just leave this header intact. /// </para> /// </remarks> // Logs to the console // Named NSLog2 to avoid name clash // iOS device: Xcode - Organizer -> Device - Console // Mac / iOS Simulator: Mac - Console procedure NSLog2(const AMessage: string); // Retrieves the vendor specific device ID - DO NOT USE UIDevice.uniqueIdentifier - this would lead to AppStore rejection since May 1st, 2013! function VendorIdentifier: string; implementation uses System.SysUtils, Apple.Utils, {$IFDEF IOS} Macapi.ObjectiveC, iOSApi.Foundation, iOSApi.UIKit, iOSApi.QuartzCore, iOSApi.CocoaTypes {$ELSE} {$IFDEF MACOS} Macapi.ObjectiveC, Macapi.Foundation {$ENDIF MACOS} {$ENDIF IOS} ; {$IFDEF IOS} // Hack to import forgotten classes/functions and properties // Be careful - classes with same name may already exist in iOSApi!! type // **** NSUUID NSUUIDClass = interface(NSObjectClass) ['{D9518F5E-DDBC-4702-A555-411D32B85340}'] end; // We just need the UUIDString here NSUUID = interface(NSObject) ['{4C137FF5-E854-461F-B77E-8CD357FD4E9C}'] function UUIDString: NSString; cdecl; end; TNSUUIDDX = class(TOCGenericImport<NSUUIDClass, NSUUID>) end; // **** UIDevice UIDeviceClass = interface(NSObjectClass) ['{D5105207-FBA7-4F55-BC7B-1ADACE347ECA}'] { class } function currentDevice: Pointer; cdecl; end; UIDevice = interface(NSObject) ['{481E431F-2C02-4F2D-86C5-7728480ECF48}'] function identifierForVendor: NSUUID; cdecl; end; TUIDeviceDX = class(TOCGenericImport<UIDeviceClass, UIDevice>) end; {$ENDIF} procedure NSLog2(const AMessage: string); var LMessage: NSString; begin LMessage := NSSTR(FormatDateTime('hh:nn:ss,zzz', now) + ' - ' + AMessage); iOSApi.Foundation.NSLog(PtrForObject(LMessage)); end; {$IFDEF IOS} function currentDevice: DX.Apple.Utils.UIDevice; begin result := TUIDeviceDX.Wrap(TUIDeviceDX.OCClass.currentDevice); end; function VendorIdentifier: string; var LDevice: DX.Apple.Utils.UIDevice; begin LDevice := currentDevice; result := NSStringToString(LDevice.identifierForVendor.UUIDString); end; {$ENDIF} end. Tweet This! Share this on del.icio.us Digg this! Share this on Reddit Get Shareaholic
Read More

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