Tip: If you've never developed for OS X or iOS before, you may find the previous articles in this series helpful. The complete list of articles is here. You can ignore most of the discussion of designing the user interface in Xcode since you'll be doing that in Delphi as usual.
Remember that iOS Simulator is a simulator, not an emulator. It does not emulate the ARM instruction set, but rather executes apps that have been compiled for x86 just like normal OS X apps. These apps are linked against x86 versions of the iOS frameworks rather than against ARM versions.
As a result, how an app operates under the Simulator can differ from how it operates on an actual device. This means you need to test on an actual device before deploying your app or submitting it to the App Store. However, the benefit of a simulator is speed - if you've ever developed for Android, you know that the Android emulator is almost useless because it's so slow.
Here are some things to watch out for when using the Simulator:
Here's a list of features not yet supported in the current stable version of Free Pascal (2.4.4):
http://wiki.freepascal.org/delphi_language_features_which_fpc_does_not_have
However, since presumably you'll be using version 2.5.1, some of these features should be available, as described here:
http://wiki.freepascal.org/FPC_New_Features_Trunk
Free Pascal supports UnicodeString, but string is still AnsiString. WideString is also available.
http://wiki.freepascal.org/FPC_PasCocoa
A list of Objective C classes available with the Foundation framework on iOS is here.
Presumably Delphi XE2 will include the IOUtils unit for iOS. This unit should make working with some aspects of the iOS file system easier. For example, to obtain the path to your app's temporary directory (tmp in the app's home directory), in Objective C you would use the Foundation framework's NSTemporaryDirectory function, as illustrated in this snippet of Objective Pascal code:
var tmpDir : NSString; begin tmpDir := NSTemporaryDirectory;To use tmpDir with the Pascal RTL, you would first need to convert it to an AnsiString. Part 5 introduced the NSHelpers unit that provides some basic string conversion routines for doing just that. However, if we assume the presence of the IOUtils unit, then presumably you could just do this instead:
var tmpDir : string; begin tmpDir := TPath.GetTempPath;More problematic is obtaining the path to your app's Documents directory. In Objective Pascal, you would use a somewhat awkward construction like this:
var paths : NSArray; docDir : NSString; begin paths := NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, True); docDir := paths.objectAtIndex(0);So what's the RTL equivalent? Well, presumably you could do something like this using IOUtils, although this code assumes both the name and relative location of the Documents subdirectory within the app home directory:
var docDir : string; begin docDir := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'Documents';In some cases you may be forced to use the Foundation framework if a Pascal RTL equivalent is not provided. For example, an iOS app's home directory includes a Preferences subdirectory. You never write directly to Preferences, though. Instead you use the NSUserDefaults class to read and write user preferences and to save and restore your app's state. You can also use the CFPreferences unit, since this calls a C library in the older CoreFoundation framework and doesn't require Objective C. (The Foundation framework is mostly Objective C wrappers around CoreFoundation functions - that is, Foundation turns these C functions into Objective C classes.)
For example, FCL includes units for working with XML files in a normal tree-oriented DOM fashion. The Objective C Foundation framework includes the NSXMLParser class, but this is an event-drive parser, designed for speed and minimal memory use, and you may not find it very useful. However, if you use the FCL XML units, you won't be able to compile your XML-handling code with Delphi.
For example, to load an XML file with the FCL XML units, you might do something like this:
var XmlDoc : TXMLDocument; begin ReadXmlFile(XmlDoc, FileName);In contrast, with Delphi you might write it like this:
var XmlDoc : IXMLDocument; begin XmlDoc := TXMLDocument.Create(nil); XmlDoc.FileName := FileName;FCL also includes units for working with SQLite databases. Every Mac and iOS device includes the SQLite library and since it's a normal C library, you don't need Objective C to use it, just the FCL sqlite3 and SQLite3db units.
For example, if your iOS app included a SQLite version of the FishFact database, you could open and query it like this:
var DbFileName : string; SqliteDb : TSQLite; FishName : string; QryResult : TStringList; begin DbFileName := 'biolife.sqlitedb'; //add appropriate path SqliteDb := TSQLite.Create(DbFileName); try //assuming SqliteDb.LastError=SQLITE_OK FishName := 'Clown Triggerfish'; QryResult := TStringList.Create; if SqliteDb.Query('SELECT "Species Name" FROM BIOLIFE WHERE Common_Name = "' + FishName + '";', QryResult) then begin // do something with QryResult.Strings[1] end; finally QryResult.Free; SqliteDb.Free; end;
Parts 1-5 of this series present an approach that substitutes Objective Pascal for Objective C, but otherwise uses Xcode and Cocoa Touch in essentially the same way as they are used in Objective C development. However, because Pascal is not integrated into the Xcode IDE, this approach requires some fairly awkward compromises. For example, since the only way to wire "connections" between the user interface layout and code in Xcode is via Objective C header files, an Objective Pascal Xcode project requires "placeholder" Objective C files which are not otherwise needed.
Delphi XE2 would appear to provide a reasonable "third way", moving user interface design and code editing out of Xcode (and off the Mac entirely) and into a Windows-hosted IDE that Delphi developers should find familiar, relegating Xcode to the final build step. To be sure, this approach comes with its own bit of awkwardness (flipping between Windows and OS X), but provides cross-platform opportunities that would not be possible with an Xcode-only approach.
However, there are some things that will probably require Xcode or direct access to Objective C frameworks. These range from the straightforward to the complex and the question is whether and how Delphi itself will address them.
For example, on both OS X and iOS, an app's Info.plist file controls many aspects of the app's behavior and is used to set the app's version, copyright statement, file associations, etc. While this is just an XML file, using the Xcode property list editor to set these things (rather than doing it on the Delphi side) would seem logical. One small example: To include a custom font file with an iOS app, you just add the name of the font to the UIAppFonts array in the Info.plist file and add the font .ttf file to your Xcode project. When Xcode builds your app, it will copy the font file into the app bundle automatically. It would seem rather pointless to duplicate this iOS-specific setting in a Windows-hosted IDE where it has no cross-platform correspondence.
A bigger challenge is accessing device-specific functionality. Will this be done via the iOS Objective C frameworks (perhaps accessed via Objective Pascal syntax) or in a cross-platform way? PhoneGap shows that a great deal of mobile functionality can be supported in a cross-platform fashion, even for JavaScript, so perhaps a cross-platform library for mobile will emerge eventually for Delphi too.
For example, to add a Google map to an iOS app in Xcode, you use the MapKit framework: Just drop an MKMapView onto a view, make a connection for it (in this case, myMap), then add code like this to display the map:
var region : MKCoordinateRegion; begin region.center.latitude := myLatitude; region.center.longitude := myLongitude; region.span.latitudeDelta := 0.02; region.span.longitudeDelta := 0.02; myMap.setRegion(region); myMap.setMapType(MKMapTypeHybrid);Most mobile platforms support mapping, so it's not hard to imagine a cross-platform Pascal library that supports, say, both Google and Bing maps.
macpgmr (at) fastermac (dot) net
First posted Aug. 7, 2011.