hot chocolate: you got cocoa in my php

28
Hot Chocolate You got cocoa in my PHP <[email protected] >

Upload: wez-furlong

Post on 05-Jul-2015

11.368 views

Category:

Technology


1 download

DESCRIPTION

A look at using PHP to build Cocoa applications

TRANSCRIPT

Page 1: Hot Chocolate: You got cocoa in my PHP

Hot ChocolateYou got cocoa in my PHP

<[email protected]>

Page 2: Hot Chocolate: You got cocoa in my PHP

Why?

• I love bridging technologies

• I didn’t want to have to become an expert in Objective-C to hack together a couple of apps (backfired!)

• Similarly, python and ruby are not my forte

Page 3: Hot Chocolate: You got cocoa in my PHP

What?

• A PHP extension that bridges the Objective-C runtime to PHP

• Can take advantage of BridgeSupport

• Helper script to create a re-distributable version of your work

• No Xcode integration

Page 4: Hot Chocolate: You got cocoa in my PHP

How it works

• Objective-C is sugar on top of typing and message passing system

• Straight C apps can interrogate and call into that runtime

• This allows PHP to construct placeholder classes for classes defined in the Obj-C runtime

• Using the FFI library, PHP can construct machine code segments that can be used to bridge back from Obj-C and into PHP... allowing PHP script to define and extend Obj-C classes

Page 5: Hot Chocolate: You got cocoa in my PHP

Getting it, building it

# the password is phpficvs -d:pserver:[email protected]/repository \ login

cvs -d:pserver:[email protected]/repository \ co php-objc

cd php-objc/libffi

./configure

make && make install

cd ..

make && make install

Page 6: Hot Chocolate: You got cocoa in my PHP

Simple app

• Open Interface Builder

• Choose the ‘Application’ template

Page 7: Hot Chocolate: You got cocoa in my PHP

• Should see something like this:

Page 8: Hot Chocolate: You got cocoa in my PHP

Add a text edit field

• Drag the text field cell from the Library and into the Window

Page 9: Hot Chocolate: You got cocoa in my PHP

Declare a controller class

• Necessary for rigging events

• Just records the fact that the class will act as the controller, doesn’t define any code

• Drag the Object icon from the Library to the IB Window

• Change the class name to MyController

Page 10: Hot Chocolate: You got cocoa in my PHP

• Add an outlet to MyController(this declares that it will have aninstance variable of the same name)

• CTRL drag the the controller cubeto the text field

Page 11: Hot Chocolate: You got cocoa in my PHP

• click “textField” in the pop-up

• the connection is now visible in the inspector for MyController

• save the interface builder pieces as NIB file (NOT XIB!)

• I named mine SimpleApp

Page 12: Hot Chocolate: You got cocoa in my PHP

Recap

• We defined the UI for our application

• It has a text edit box

• We told the UI that we will provide a MyController class

• The UI will instantiate that class when it is loaded

• We told the UI that MyController has a property (outlet) called textField that is connected to the text edit box

• The UI will set textField to reference the edit box in the window when the UI is loaded

Page 13: Hot Chocolate: You got cocoa in my PHP

PHP Code

class MyController extends NSObject { public $textField; /** @objc:signature v@:@ */ function settextField_($value) { $this->textField = $value; } function awakeFromNib() { $this->textField->setStringValue_( date(‘r’)); }}

NSApplicationMain($argv);

Page 14: Hot Chocolate: You got cocoa in my PHP

Make it runnable locally

php utils/make-bundle -target-dir ~/Desktop \ -name 'SimpleApp' \ -url 'netevil.org' \ -resources samples/simpleapp/main.php \ -resources samples/simpleapp/SimpleApp.nib \ -nib SimpleApp \ -symlink

This creates an OSX bundle that is suitable for local testing.

Remove the bundle and rebuild it without -symlink when you’re ready to re-distribute it

Page 15: Hot Chocolate: You got cocoa in my PHP

Run it

• Double click the icon on your desktop

• or use “open ~/Desktop/SimpleApp.app” from the terminal

Page 16: Hot Chocolate: You got cocoa in my PHP

Let’s run it

Page 17: Hot Chocolate: You got cocoa in my PHP

Making a clickable button

• Go back to the interface builder and drag a button into your window

• double click the button and type some text to give it a label

• Define an action on the controller called ‘refresh:’

• CTRL-drag from the button to my controller, and select ‘refresh:’ from the pop-up

Page 18: Hot Chocolate: You got cocoa in my PHP

Implement the refresh: action

/** @objc:signature c@:@ */ function refresh_($sender) { $this->textField->setStringValue_(date('r')); }

Now whenever the button is clicked, the refresh_ method is called, which re-sets the the text field to the current time

Note how the : in the name that interface builder uses for the method has been changed to an underscore in the PHP code.

Page 19: Hot Chocolate: You got cocoa in my PHP

On naming, bridging

• Objective-C uses the concept of a “Selector” to identify a method name

• The Selector has the name of the method and the parameter names (separated by colons) encoded into it

• The bridge maps selectors to PHP method names, replacing colons with underscores

• Selectors often end with a colon, which means you’ll often see method names the end with an underscore

Page 20: Hot Chocolate: You got cocoa in my PHP

Mapping Primer

+ (NSApplication *)sharedApplication

this is a static method of the NSApplication class, the PHP way to call it is this:

$App = NSApplication::sharedApplication();

- (void)setDelegate:(id)anObject

this is a regular "instance" method of the NSApplication object, call it like this:

$App->setDelegate_($anObject)

- (id)targetForAction:(SEL)anAction to:(id)aTarget from:(id)sender

$App->targetForAction_to_from_($anAction, $aTarget, $sender);

Page 21: Hot Chocolate: You got cocoa in my PHP

Method signatures

• Objective-C is quite a dynamic runtime environment considering that it was built for static languages

• Obj-C allows introspection of the types of methods and parameters

• PHP is a completely dynamic “typeless” environment, where there is “no” static type information

• The bridge can query existing Obj-C types to call them properly, but has to reciprocate if it expects to allow your code to be called from Obj-C

• That means that you need to annotate any methods you define that are going to be called from Obj-C

Page 22: Hot Chocolate: You got cocoa in my PHP

Method signatures

• /** @objc:signature c@:@ */function refresh_($sender)

• the first character is the return type

• v means ‘void’, or no return value

• c represents a ‘char’ value

• the next two characters will always be next; they represent $this and the SELector for the method being invoked

• @ is an object instance

• : is a SELector (method name)

• the final character indicates that an object is the only actual parameter to the method

Page 23: Hot Chocolate: You got cocoa in my PHP

BridgeSupport

• Anyone used PHP-GTK? (or any other PHP GUI toolkit?)

• Biggest pain-point is the need to generate wrappers for all the widgets

• Same problems already solved by the “other” scripting languages over and over again

• Apple noticed this and did something good; they made a tool called gen_bridge_metadata that scans a framework and generates a datafile describing the functions, classes and macros it provides

• We can load this at runtime when we load the framework bundle and emit PHP bridges for those things without having to code them by hand

Page 24: Hot Chocolate: You got cocoa in my PHP

Frameworks

They’re bundled up shared librariesInclude functions, constants and classesCan use system provided frameworks thusly:

objc_import_framework(‘Foundation’);

$n = NSPageSize();

printf("page size is %u\n", $n);

Page 25: Hot Chocolate: You got cocoa in my PHP

Caveats with Frameworks and BridgeSupport

• There are some holes:

• no support yet for ‘cftype’ declarations in the .bridgesupport files

• this prevents use of the AddressBook framework

• Limited support for accessing C structures

• this prevents use of the KeyChain functions

• Quite possibly other holes

• These are fixable, just not implemented yet

Page 26: Hot Chocolate: You got cocoa in my PHP

Writing Applications

• There’s only so much I can show you

• Application building is largely prototyping the UI in Interface Builder and then writing PHP code to handle events

• BridgeSupport gives you access to frameworks without having to write C code or recompile the core

• The recipe for knowing what code to write in PHP is boils down to reading the reference for the frameworks you want to use for the GUI or OSX specifics and understanding how to translate it to the PHP equivalent

Page 27: Hot Chocolate: You got cocoa in my PHP

Where do we go from here?

• As stated, there are some holes in the bridge

• I’m relying on people to use this stuff and point out where they are so that we can fix it

• Ultimately I’d love to see a meta-UI layer that abstracts PHP-GTK, WinBinder and PHP-Objc so that PHP apps can run on all systems with a native UI

Page 28: Hot Chocolate: You got cocoa in my PHP

Questions?

• These slides are on my blog and on slideshare

• my blog: http://netevil.org

• O’Reilly have a book on Cocoa programming

• Apple have various online tutorials

• CamelBones (the Perl Objective-C bridge) has some tutorials too