Developing with Objective Pascal
Part 8: Creating a Multi-Architecture Static Library (Objective C)
Contents
Introduction
Parsing the Objective C Header Files
Compiling the Objective C Classes
Using the Static Library in a Pascal App
Introduction
These notes describe how to compile Objective C classes into a static library
that you can use in an Objective Pascal iOS app. The example given is for the
popular ASIHTTPRequest classes, which are available here:
http://allseeing-i.com/ASIHTTPRequest
Parsing the Objective C Header Files
Before going much further, make sure you can parse the Objective C header
files into equivalent Objective Pascal declarations. With a simple class that
has only a few methods, you could probably just transliterate them manually,
but with a large number of classes like ASIHTTPRequest, you'll want to use
the latest FPC header parser, available here:
iOS_6_Parsing_Status.html
The parser includes all of the files needed to parse the ASIHTTPRequest
header files and compile the Pascal Asihttp unit. To set up the parser for
other header files, see Part 9.
Compiling the Objective C Classes
The easiest way to compile the Objective C classes is to create an
Xcode project to do it.
- Start Xcode and choose File | New | New Project. On the Framework
& Library tab, select Cocoa Touch Static Library and click Next.
- Enter the name to use for the library in Product Name. In this
example, the Pascal Asihttp unit expects a library named libAsihttp.a, so enter
Asihttp - Xcode will add the "lib" prefix to whatever you enter, per
convention. Click Next and save the new project wherever you want. The name you
entered will also be used to name the project folder.
- You could copy all of the Objective C .h (header) and .m
(source) files into the project's source folder and then add them to the
project, but it's easier just to add them from wherever they're located. Choose
File | Add Files to do that. Note that "adding" does not copy anything,
but just points the project to the added files.
Important! With the ASIHTTPRequest example, be sure to add all
of the .h files and .m files from both the ASIHTTPRequest Classes folder
as well as the External/Reachability folder.
- Set the project's iOS Deployment Target to the earliest version of
iOS that your app(s) will target to ensure that the classes are not using
features that won't be available. You set this on the project's Info tab.
- On the project target's Build Phases tab, click Add Build
Phase | Add Run Script, then copy and paste this script into the box for
the run script:
if [ $PLATFORM_NAME = "iphonesimulator" ]; then
cp $BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH $PROJECT_DIR/$EXECUTABLE_PATH
else
$DEVROOT/usr/bin/lipo $BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH $PROJECT_DIR/$EXECUTABLE_PATH -create -output $PROJECT_DIR/$EXECUTABLE_PATH
fi
This script will combine the Simulator and ARM .a (archive) files into a
single .a file.
- We want a multi-architecture library that includes support for i386, armv6
and armv7. Beginning with Xcode 4.2, the "standard" ARM architecture is now
armv7, whereas in earlier versions "standard" included both armv6 and armv7.
So with Xcode 4.2 and later, change the ARCHS setting on the project
target's Build Settings tab from "Standard (armv7)" to "armv6 armv7".
- To compile, select Simulator for your iOS deployment target and
choose Product | Build. Then select iOS Device and choose
Product | Build again. Be sure to compile for Simulator first, then for
the device (ARM) since the script assumes that order.
- Check that the .a file (libAsihttp.a) has been created okay and contains all
architectures. Note that the script creates the .a file in the project's
top level folder instead of burying it under ~/Library/Developer/Xcode/DerivedData
along with the other compiled files. Change to this folder and use the
file command. For example:
file libAsihttp.a
libAsihttp.a: Mach-O universal binary with 3 architectures
libAsihttp.a (for architecture armv6): current ar archive random library
libAsihttp.a (for architecture armv7): current ar archive random library
libAsihttp.a (for architecture i386): current ar archive random library
Using the Static Library in a Pascal App
- Add the Pascal interface unit (Asihttp) to your app's uses. If the
unit's compiled files (Asihttp.o / Asihttp.ppu) are not where FPC can find them,
add to the compiler's unit search path using the -Fu switch.
Tip: Depending on how your app's Xcode project is set up, you
can add switches either to its build script or, if the script uses them,
to user-defined settings on the project target's Build Settings tab.
- Use the FPC -Fo switch to add the path to the library
(libAsihttp.a) to the compiler's object search path.
- Test the library. For example, you can test the ASIHTTPRequest class
with this simple code:
var
url : NSURL;
request : ASIHTTPRequest;
error : NSError;
begin
url := NSURL.URLWithString(NSSTR('http://jaiku.com/feed/json'));
request := ASIHTTPRequest.requestWithURL(url);
request.startSynchronous;
error := request.error_;
if not Assigned(error) then
NSLog(request.responseString); //output JSON to console
Copyright 2011 by Phil Hess.
macpgmr (at) fastermac (dot) net
First posted Nov. 9, 2011; last edited May 9, 2013.