Objective Pascal
To compile these projects you must install the latest version of FPC from SVN (currently 2.5.1) and PascalGladiator 0.7.1 (or higher) with ObjP syntax support. If you prefer UNIX you can use the installer shell script or there is a install application available (see below).
To install using a Mac application download the installer and follow the first 2 steps and optionally parse the iPhone headers. The installer itself was made using Objective Pascal and performs the same steps found in the shell script. You can also continue to use the installer to upgrade your version of FPC if you need.
ObjP Installer Version History. Version 1.0.2 (7/16/10): - The installer now accepts a base version (instead of being fixed at 2.2.4) so you can change this manually when new versions of FPC are released. - There is a "Copy Headers" option which will copy the translated headers from SVN to the Objective Pascal directory you specified. - Universal Binary (OS 10.5 and higher). Version 1.0.1: - Widened status label. - Added -p to the cp command when copying files to the ObjectivePascal directory.
AppKit/Foundation Examples
- CircleView. Pascal port of Apple's CircleView example by Ryan Joseph. Shows how to use the components of the Cocoa text system to draw a custom NSView.
- OutlineView. Pascal port of Apple's OutlineView example by Ryan Joseph. Shows the most basic implementation of NSOutlineView using the file system as a data source.
- MiniBrowser. Pascal port of Apple's MiniBrowser WebKit API example by Ryan Joseph. This requires at least revision 13831 of WebKit headers from SVN.
- NIBWindows. This was an example project I made but corrected by Gorazd Krosl to more Cocoa-ish. ;)
- PLuaTerminal. Simple terminal for the lua programming language by Gorazd Krosl.
- TemperatureConverter. Pascal version of the Apple Cocoa tutorial application for beginners by Gorazd Krosl.
- FPCEventManager. Simple CoreData document based application, a port of Apple's EventManager by Gorazd Krosl.
Library Examples
- RegexKitLite. Pascal port of RegexKitLite by Gorazd Krosl. A framework is supplied for linking which must be placed inside the applications bundle in the Frameworks folder. The example contains only a single unit which is the complete interface to the framework.
iPhone Examples
These examples require the iPhone SDK (from Apple) and translated Pascal interfaces to run (which I can not distribute, see the script above). As of version 0.7.2 PascalGladiator supports a target for compiling bundles which will run in the iPhone simulator but Xcode and certificate ($99) is still required for device targets.
- iArkanoid. This is a test game by Dmitry 'skalogryz' Boyarintsev which shows how to make a basic iPhone app using CoreGraphics.
These headers have been parsed from Cocoa frameworks using the framework parser script and corrected by hand to be as accurate as possible.
Version 2.0 headers with comments and objccategory support.
Older headers.
Please contact me with any and all corrections to the headers so I can include them into the official package.
The framework parser is a PHP script which translates Objective-C headers into Objective Pascal units. The parser is still not 100% accurate however even after much development but can still be used to batch convert entire frameworks which can then be polished by hand afterwards to achieve good results.
Examples
Parsing the Foundation.framework while omitting some files.
php parser.php -root="/Developer/ObjectivePascal" -all -comments -frameworks="foundation" -ignore="NSGeometry.h,NSObjCRuntime.h,NSRange.h"Parse a single header in QuartzCore.framework without pre-parsing Foundation.framework for symbols.
php parser.php -root="/Developer/ObjectivePascal" -comments -header="quartzcore/CIImageProvider.h"Parse WebKit.framework with supporting Foundation/AppKit frameworks (no printing as designated by the ^ prefix) then print only a few files.
php parser.php -root="/Developer/ObjectivePascal" -all -comments -frameworks="^foundation,^appkit,webkit" -only="DOMFile.h,DOMFileList.h,DOMProgressEvent.h"Parse the QuickLookUI framework but merge output instead of normal printing which overwrites previous files.
php parser.php -root="/Developer/ObjectivePascal" -all -merge -frameworks="quicklookui"
Manual
- Locate the .framework you want to parse and record the path for later use when building the command line.
- Add an entry to frameworks.xml (in the parser directory) with the appropriate tags for the framework. To make configuring the parser easier many options are specified here in XML instead of editing PHP variables.
- <bridge> tag is currently not used but specified in some entries anyways.
- <root> tag is the relative path to the root include file (see step 4). The path is relative to the -root path (see step 5)
- <headers> tag is the path to the directory which contains the Objective-C headers (usually in /System/Library/Frameworks).
- <include_pattern> is a regular expression that captures the Pascal syntax of include files in the root .inc file. This is usually {[$]+include (.*).inc}.
- <header_pattern> is a regular expression that captures files in the header directory (defined in <headers>). This is usually ^(.*)\.h.
- <ignore_lines> is a regular expression that causes to parser to ignore lines that present parsing errors you want to skip and edit by hand.
- <ignore_comments> is a regular expression that causes to parser to ignore comments. Note, if the comment is found inside a multi-line comment block it will break the entire block.
- <external_macro> In the frameworks the macro which defines NSString constants changes from framework to framework so you must specify it here or NSString constants will not get parsed. For example in UIKit.framework it is UIKIT_EXTERN and in QuartzCore.framework it is CA_EXTERN. AppKit and Foundation macros are defined internally as PHP variables so you do not need to specify them here.
- <ignore_types> and <ignore_methods> will cause the parser to ignore these types and methods when parsing. Separate multiple values by commas without spaces.
- <replace_types> causes the parser to replace types with a different name. For example: <type>CGFLOAT_DEFINED=__CGFLOAT_DEFINED</type> will replace all occurrences of CGFLOAT_DEFINED with __CGFLOAT_DEFINED.
- Make a framework directory in the root directory (see step 5 and -root).
- Make the root .inc file with all units which will be parsed and put it in the directory created in step 3.
- Usually named a header with the same name as the framework for example, AppKit.h contains all the headers in the framework.
- This step involves taking care to arrange the included units in the proper order. The order in the original "umbrella" header is usually pretty close but often requires some rearranging.
- Make the command line for the parser
- Frameworks assigned in -frameworks and prefixed ^ will parse but not print.
- The ^foundation framework is usually always included so extra class information is parsed for the other frameworks as they all use foundation classes occasionally. If you do not specify foundation then classes will be printed as pointers (NSStringPointer instead of NSString).
The example below will parse the entire WebKit framework.
php parser.php -objp -all -root="/Developer/ObjectivePascal" -frameworks="^foundation,webkit"- Make the master unit file named after the framework, like AppKit.pas. This unit will include all the .inc files in the framework directory that was created in step 3. You can add extra code here if you like but normally it's enough to copy a template like AppKit.pas and change a few lines. For example, the $linkframework macro should be changed and possibly some interfaces added to the uses clause. Usually CocoaAll.pas will need to be added in order to get Foundation and AppKit functionality in supporting frameworks.
Command line usage
-all Print all headers (.h) from AppKit/Foundation frameworks. -header=\"foundation/NSObject.h\" Prints a single header from system frameworks (if specified) or direct path. -root Sets the root path of the output directory. -framework_path Sets the root path of the frameworks directory (defaults to /System/Library/Frameworks). -show Prints output to screen instead of file (mutually exclusive to -noprint). -comments Parses comments. -merge Headers are merged by difference (using diff/patch) instead of overwritten. -ignore=\"NSObject.h,NSArray.h\" Ignores the list of headers during parsing (-all only, no spaces). -only=\"NSObject.h,NSArray.h\" Only print these files (-all only, no spaces). -noprint Parses but does not print (-all only). -iphone One-time parse for iPhone headers. -cocoa One-time parse for Cocoa (AppKit/Foundation) headers. -frameworks=\"appkit,foundation\" List of supported frameworks to parse.
Version History
Version 2.0
- -merge. The parser will merge new lines into the into the old file without overwriting saved lines. Note this feature uses diff/patch UNIX utilities and may present conflicts when lines changed in the original version are near added lines in the updated version.
- -comments.
- Category support using objccategory.
- Protocol methods are merged into classes which adopt the protocol under the { Adopted Protocols } section. This is mandatory to comply with the Objective Pascal syntax but should not affect you.
- The -objp switch is irrelevant since PasCocoa support is obsolete now and can be omitted.
Version 1.0
- Support for Objective was added to augment the existing PasCocoa logic.
Download the parser here which contains basic documentation and frameworks.xml file with predefined frameworks for reference.
The first step is to install the ARM compiler by using the script found here. This script assumes you have downloaded the latest version of the FPC sources at /Developer/ObjectivePascal/fpc and have download FPC 2.4.0 here.
It's recommended you run the Objective Pascal install script listed above which will download the sources from SVN and optionally parse the iPhone headers needed to develop any applications. If you just want to download the sources run the svn co http://svn.freepascal.org/svn/fpc/trunk /Developer/ObjectivePascal/fpc command in the terminal.
To compile using the ARM compiler use a command similar to: /usr/local/lib/fpc/2.5.1/ppcarm Main.pas -FD/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin -XR/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk -Cfvfpv2
Once you have compiled a binary you need to install the application to the device via Xcode. This step requires you register with the iPhone developer program and pay an annual fee of $99. After you registration is accepted (this will take a few days) you will be able to create a certificate via the developer web site (Provisioning Portal) which you will download and install into Xcode. This is a rather long process actually and involves many steps but the site will walk you through all of them. Finally after the certificate has been installed successfully in Xcode, running iPhone projects with a device target will install the application onto said device.
This multi-step process is automated (you never need to use Xcode manually once configured) with a script found here. To run the script use a command like: php install_iphone_app.php -binary="path/to/binary" -project="path/to/iphone_template" -config="Debug" -dev="John Doe (SDJKLD9D8S9)" which will build the Xcode project, copy the FPC binary, code sign the binary and resources then run the project from Xcode via AppleScript thus installing the application.
Requirements
- Create an Xcode iPhone project. In Xcode create a new project using any iPhone template then delete all source files and resources (besides main.m). Copy any resources and info.plist files into the Xcode project as they will be copied into the application bundle when it is built (you can also copy files directly into the application bundle). Make sure you select Debug as the active configuration and any SDK "device" named SDK for active SDK.
- Get the iPhone developer string. Build the project and then inspect the Build Results window. In the code sign item copy the text after iPhone Developer: (see the screen shot for help). This string will be used as the -dev option (see below).
Script usage
-config: Active configuration in Xcode project (Debug or Release). -binary: Path to ARM binary compiled with FPC. -project: Path to Xcode iPhone project. -dev: iPhone Developer as in the Xcode code sign command. Example: John Doe (DKJF87DHSJKD).
Source Code
These units and are being offered as-is for reference and education but the functionality isn't very well documented. Some of these units require Objective Pascal and are missing low-level system units needed to compile but can still be used to study if you found anything interesting.
Toolbox
- TObjectUnit.pas. Root class which adds support for reference counted memory, auto-release pools, archiving/unarchiving objects, generic key based properties, dynamic method invocation/registering using strings and the general design for all other objects to follow.
- TArchiverUnit.pas. This class duplicates many areas of TDictionary but was need as the root class for archiving that didn't rely upon TObject like TDictionary does.
- TResponderUnit.pas. Adds user notification support (using CFNotification) and response handling to the object. Objects which subclass TResponder can post/receive notification events using an Object Pascal interface and respond to a generic action/target interface used in other classes to communicate with external objects.
UNIX
- TProcessTaskUnit.pas. This will execute a command asynchronously using popen inside of a task and read the output line by line.
Carbon Wrappers
- TTaskUnit.pas. Wrapper for the Multiprocessing API.
- TDragUnit.pas. Wrapper for the Drag Manager API.
- TArrayUnit.pas. Wrapper for CFArray which includes subclasses for supporting a variety of types besides CFType including TObject and Pascal pointers.
- TDictionaryUnit.pas. Wrapper for CFDictionary including while-loop enumeration. Unlike TArray I haven't made a subclasses to handle multiple types so you must rely on a series of constructors which are named confusingly (the reason I changed TArray).
- TStringUnit.pas. Wrapper for CFString which adds some features missing in CFArray but available in NSArray.
- THTTPUnit.pas. Wrapper for the CFHTTP API.
- TDirectoryNotificationUnit.pas. Wrapper for the File Manager directory notification callbacks.
- TTimerUnit.pas. Wrapper for Carbon event loop timers.
- TFolderIteratorUnit.pas. Wrapper for the File Manger directory iteration.
- TUserNotificationUnit.pas. Wrapper for the CFUserNotification API.
- TEventHandlerUnit.pas. Wrapper for the Carbon Event Manager which is easy to subclass and make reusable classes for common events instead of using callbacks.
- TPrintSessionUnit.pas. Wrapper for the Core Printing API (not yet complete).
Carbon GUI
- TWindowUnit.pas. Wrapper for the Window Manager API with various other additions and Carbon event support also. TWindow is a subclass of TView.
- THIViewUnit.pas. This base class wraps HIView and makes it possible to make control views by subclassing. All the views below except THIToolbar are subclasses of THIView.
- THICascadingViewUnit.pas. Cascading view like found in the Get Info window in the Finder.
- THISplitViewUnit.pas. Split view which is included in Cocoa but never made for Carbon.
- THITabViewUnit.pas. Tab view like found in many modern applications. This unit subclasses THIToolbarView which supports most of the basic functionality.
- THIToolbarViewUnit.pas. Toolbar view which supports adding different types of views often found in toolbars like at the bottom left hand corner of Mail.app.
- THIToolbarUnit.pas. Wrapper for the HIToolbar API which was absolutely terribly to implement in Carbon but nice in Object Pascal.
- TControlUnit.pas. Essentially a wrapper for the Control Manager API (and HIView API) but extends it with many other features like notifications for value changes, archiving/unarchiving values to disk and event subclassing for making custom controls. Packaged in the unit are many subclasses for common controls which abstract the underlying API's and make them easy to extend. There is a top level procedure which will iterate all controls in a window then allocate a TControl based object for the control which you can access via control name (assigned in IB control properties) instead of using HICommands.
- TViewUnit.pas. Root class for all "view" based controls even.
- TMenuUnit.pas. Partial wrapper for the Menu Manager API and allows for creating contextual menus easily.
Other API's
- SpriteEngine. Example of how to make a full featured 2D sprite engine with CoreGraphics and Objective Pascal (like seen in TaskCard). This code is platform independent for OS X and iPhone but all the implementation details are not finished yet. There is currently no project file or examples so you can't compile but this is still interesting for study.
- PCRERegex. The PCRE regular expression library with Object Pascal interface.
- DataBrowser. This package contains several units which add an Object Pascal wrapper to the DataBrowser API and defines a system of data sources and nodes classes which can be used instead of custom data types so you don't have to define the behavior of rows over and over again.
© 2010 The Alchemist Guild


