Important SSL Update Available for Indy

As you might have heard a pretty dangerous bug in OpenSSL has recently been discovered. See OpenSSL’s vulnerability page for more information. This serious bug has been fixed in OpenSSL version 1.0.1g

As mentioned by Jeroen, updated SSL builds for Indy are already available at fulgan.com (which is Indy’s binary warehouse since ages)

The static libraries have not been updated, as they are for client side use only.

If you run any kind of server that offers SSL/HTTPS connections and uses any 1.0.1 version of OpenSSL, they you need to update. If you are using any older versions, then you want to update anyway ;-)

Posted in Miscellaneous | Leave a comment

Viewing logs on Android devices

On my previous post I mentioned how to generate a log entry from your Delphi app on Android devices:

uses
AndroidApi.Log;

var
LMarshaller: TMarshaller;

begin
LOGI(TMarshaller.AsAnsi(‘Hello World’).ToPointer)

But how do you actually get hold of Android’s log output?

You can view the log stream on a console by entering this command:
adb.exe logcat
adb.exe is part of the Android SDK and usually comes with Delphi XE5:
C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\adt-bundle-windows-x86-20130522\sdk\platform-tools\adb.exe

A console log might look a bit messy though (at least to me), so you might try this free tool, which even lets you filter the log stream:

Android LogViewer

Android LogViewer

Posted in Android, Delphi, Development | Leave a comment

Dealing with MarshalledAString

A couple of versions ago Delphi XE kind of silently introduced the new string types MarshalledString and MarshalledAString.

These types basically map to PChar and PAnsiChar, which worked fine for years. Since Delphi went multi-platform though, there was the need to introduce some stricter abstraction from string types that may exist on all those various platforms, such as Win, MacOSX, iOS and now, with XE5, even Android. And it’s not just platforms, but even a set of different compilers now.

So everytime there are API calls to a certain platform, it’s very likely that you will encounter MarshalledString or MarshalledAString. “Marshalled” means that there needs to be some conversion applied to read or write a “regular” string (which is always Unicode since D2009)

So how would you fill in a “regular string” into this function?

function LOGI(Text: MarshaledAString): Integer;
(A function taken from AnroidAPI.pas)

The important thing here is, that “Text” is MarshalledAString – which means we have to supply an AnsiString. To convert a Delphi Unicode string to Ansi, there is a TMarshaller structure:

var
LMarshaller: TMarshaller;

begin
LOGI(TMarshaller.AsAnsi(‘Hello World’).ToPointer)

AsAnsi does all the dirty work to convert the multibyte Unicode string to a single byte Ansi encoded string (there are overloads to specify a codepage) and returns a TPtrWrapper, which is a structure that points to the actual memory containing the new Ansi string. As MarshalledAString is basically just a pointer, that pointer can easily be supplied using “ToPointer”.

Posted in Android, Delphi, Development, iOS | Leave a comment

Delphi XE5 : SSL / HTTPS on different platforms with TIdHTTP and TRESTClient

Using SSL/HTTPS with Indy’s TIdHttp (or through TRESTClient – which is effectively based on TIdHttp) requires external OpenSSL libraries, which is something most of us probably learned in the past.

With Delphi XE5 now supporting different platforms, such as Windows, Mac, iOS devices, iOS Simulator and Android devices, there are now a couple of different libraries and approaches to follow.

Btw, if you are using TRESTClient, then you can just assign a URL like https://www.example.com/api to TRESTClient.BaseURL – you don’t have to worry about assigning an SSL IO handler, as you would have to, if working with TIdHttp directly. TRESTClient detects that situation automatically.

In one of Marco Cantú’s recent posts you will find some very useful information about how to build your own OpenSSL binaries iOS – which is a good idea from a security standpoint.

Marco’s post is basically for iOS only, so I thought I should share an overview that covers all platforms and make this an easy to follow SSL with Delphi recipe.

As mentioned above building your own SSL libraries from source is a good idea, but many people would just like to download ready-to-use binaries. For us Delphi users there is a trustful mirror site which has recent builds available since many years:

http://indy.fulgan.com/SSL

There are dynamic libraries (a.k.a “DLLs”) and static libraries (a.k.a “.a files”)

Recent dynamic libraries (32-bit): openssl-1.0.1e-i386-win32.zip
Recent static libraries: OpenSSLStaticLibs.7z

Windows

Download dynamic libraries and put them into the same directory as your exe. You may also put them into your system’s windows\system32 directory.

Files (32 Bit)

  • libeay32.dll
  • ssleay32.dll

Mac OSX

No download required, recent versions of Mac OSX come with OpenSSL pre-installed, you only need to tell your app where the required dynamic libraries (a.k.a dylibs) can be found. On typical Mac installations they are in “/usr/lib/”

uses
IdSSLOpenSSLHeaders;
...
IdOpenSSLSetLibPath('/usr/lib');

You could also deploy these files with your app by adding them to your apps deployment files list (and enable it for Mac OSX and iOS Simulator only)

Files

  • libcrypto.dylib
  • libssl.dylib

(Both files are usually symbolic links to actual binaries like /usr/lib/libssl.0.9.7.dylib)

iOS Simulator

No download required, recent versions of Mac OSX come with OpenSSL pre-installed (and which is used by the iOS Simulator as well), you only need to tell your app where the required dynamic libraries (a.k.a dylibs) can be found. On typical Mac installations they are in “/usr/lib/”

IdOpenSSLSetLibPath('/usr/lib');

Files

  • libcrypto.dylib
  • libssl.dylib

(Both files are usually symbolic links to actual binaries like /usr/lib/libssl.0.9.7.dylib)

iOS Device

iOS does not allow to load any dynamic code, thus you need to download the static OpenSSL libraries and put them into the main source directory of your application, so that Delphi can find them while compiling/linking your app.

Files

  • libcrypto.a
  • libssl.a

Android Device

Info follows soon!

Making your project multi platform

As you can actually have one project compiling to all the mentioned platforms you probably want some ifdefs to handle all platforms and their units automatically. Below is a sample DPR file that works fine for me:

program SSLTest;

uses
  System.StartUpCopy,
{$IF Defined(IOS) and Defined(CPUARM)}
  IdSSLOpenSSLHeaders_Static,
{$ELSE}
  IdSSLOpenSSLHeaders,
{$ENDIF}
  FMX.Forms,
  Unit5 in 'Unit5.pas' {Form5};

{$R *.res}

begin
{$IF Defined(IOS) and not Defined(CPUARM)}
  IdOpenSSLSetLibPath('/usr/lib/');
{$ENDIF}
  Application.Initialize;
  Application.CreateForm(TForm5, Form5);
  Application.Run;
end.
Posted in Delphi, Development, iOS, iPad, iPhone, Miscellaneous | Leave a comment

Getting wget on a Mac

wget is a standard tool for issuing HTTP requests from a command line. Even with having Indy’s TIdHttp on a Mac now, it might be handy for some tests or scripts to use wget.

The equivalent of

IdHttp.get('http://google.com');

is

wget http://google.com

Unfortunately though wget is not installed by default on MacOSX (only curl is, which is a similar command, with quite a different syntax), but there is an easy way to get wget:

As Delphi developer, using Delphi XE 4′s mobile compiler, you probably already have Xcode (including command line tools) installed – which would be the only requirement for the following. Open a terminal window on your Mac and run the script below. It may take a minute or two and when done wget will be ready to use (it will automatically be copied into one of your bin directories)

curl -O http://ftp.gnu.org/gnu/wget/wget-1.14.tar.gz
tar xvzf wget-1.14.tar.gz
cd wget-1.14
./configure --with-ssl=openssl
make
sudo make install

There might be newer versions than 1.14, but I didn’t check, 1.14 works just fine for me.

Credits: Mike Beach

Posted in Miscellaneous | Leave a comment

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.

Posted in Miscellaneous | Leave a comment

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:

Posted in Delphi, Development, iOS | Leave a comment

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.
Posted in Delphi, Development, iOS | Leave a comment

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.

Posted in Miscellaneous | Leave a comment

Delphi samples updated constantly

Since a while the samples that come with Delphi are actually connected to a SubVersion repository of Embaracderos, that is you might want to “update” them from time to with your favorite SVN client.

Samples for Delphi XE4 can usually be found here:

C:\Users\Public\Documents\RAD Studio\11.0\Samples

If you have Tortoise installed, then just right click “Samples” and hit “SVN Update”

Last checkin according to the log is from Monday, April 22nd – and thus not in XE4′s installation ISO. The log reaches back until July 21st, 2010 – so if you like you can track how features evolved over time and made it into the samples ;-)

Bildschirmfoto 2013-05-01 um 13.10.01

Posted in Delphi, Development | Leave a comment