iPhone development with PHP and XML


Building the application starts with defining some commands that the iPhone remote control will present for you to select. You use an XML file to define the commands. Listing 1 shows this file.
                
<commands>
  <command title="Next Song">
    tell application "iTunes" to next track
  </command>
  <command title="Previous Song">
    tell application "iTunes" to back track
  </command>
</commands>


The file is a list of <command> tags. Each tag has a title attribute that defines a human readable title for the command. And the content of the <command> tag is the AppleScript code to execute when the command is requested. Because of XML encodings, if you want to put in any AppleScript code that has angle bracket (< or >) or ampersand (&) characters, you must encode those as<>, and &, respectively.
To wrap this XML file, I wrote a PHP V5 Command class that reads the file, returns the command names, and runs the commands using the Mac OS X osascript command. The code for this class is shown in Listing 2.

Listing 2. commands.php
                
<?php
class Commands
{
  private $_commands;

  function __construct()
  {
    $this->_commands = array();

    $doc = new DOMDocument();
    $doc->load('commands.xml');
    $cmds = $doc->getElementsByTagName( 'command' );
    foreach( $cmds as $cmd )
    {
      $this->_commands []= array( 
        'title' => $cmd->getAttribute('title'),
        'command' => $cmd->firstChild->nodeValue
      );
    }
  }

  function getCommands()
  {
    $cmds = array();
    foreach( $this->_commands as $cmd )
    {
      $cmds []= $cmd['title'];
    }
    return $cmds;
  }

  function runCommand( $id )
  {
    $ph = popen( "osascript", "w" );
    fwrite( $ph, $this->_commands[$id]['command'] );
    fclose( $ph );
  }
}
?>

The class starts by loading up the commands.xml file. It reads in the file using the DomDocument PHP class. Then, it finds all the command arguments using getElementsByTagName. When it has the <command> tags as an array, the class loads the_commands member variable with the titles and AppleScript commands.

Two additional methods are defined:
  • The getCommands() method, which simply returns a list of the names
  • The runCommand() method, which given an index runs that command using the osascript command-line AppleScript executor.
With the commands XML file and Commands PHP class written, it's time to add an interface. Just to make sure everything is working properly, I'll put a fairly rudimentary interface on it. This interface is shown in Listing 3.

Listing 3. Simple interface script
                
<html><body>
<?php
require_once('commands.php');
$cmds = new Commands();
?>
<?php
$id = 0;
foreach( $cmds->getCommands() as $cmd ) {
?>
<a href="do.php?id=<?php echo($id);?>"><?php echo( $cmd ); ?></a><br/>
<?php $id++; } ?>
</body></html>

The script first gets the Command class, and then asks it for the lists of commands using the getCommands() method. Then, the script builds a set of links to the do.php page using the command index number and the name of the command that theCommands class returned.
When I navigate to the page in the Safari browser, I see something like Figure 1.

Figure 1. The rudimentary interface
The rudimentary interface 
I could use this as my iPhone interface and it would work. But it wouldn't feel like the iPhone. So, the next thing to do is use the iUI toolkit to extend the interface. Listing 4 shows the code for doing so.

Listing 4. index.php
                
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>Mac Controller</title>
<meta name="viewport"
  content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"/>
<style type="text/css" media="screen">@import "iui/iui.css";</style>
<script type="application/x-javascript" src="iui/iui.js"></script>
</head>
<body>
<div class="toolbar">
  <h1 id="pageTitle"></h1>
  <a id="backButton" class="button" href="#"></a>
</div>
<?php
require_once('commands.php');
$cmds = new Commands();
?>
<ul title="Commands" selected="true">
<?php
$id = 0;
foreach( $cmds->getCommands() as $cmd ) {
?>
<li>
<a href="do.php?id=<?php echo($id);?>"><?php echo( $cmd ); ?></a>
</li>
<?php $id++; } ?>
</ul>
</body></html>

At the top of the file, you include the iUI CSS file that has all the styles that give the page its iPhone look. Then, you include the iUI JavaScript file that handles all the interactivity. After that, you use the Commands class to get the list of commands. With that list, you build an unordered list (<ul>) with list item elements for each item (<li>). No, it's not as ugly as it sounds. In fact, you can look at it in Safari, and you'll get exactly the same look as you would on the iPhone, as shown in Figure 2.

Figure 2. The index.php page as rendered in Safari
The index.php page as rendered in Safari 
If you use Windows, don't worry: Safari now runs on both Windows and Mac. Of course, the PHP that runs this code must be on a Mac to run the osascript command and the AppleScript code. But you could use system commands if you want to run this on DOS or UNIX® systems.
The final step is to create the do.php file that index.php references to run the actual commands. This class is shown in Listing 5.

Listing 5. do.php
                
<?php
require_once('commands.php');

$cmds = new Commands();
$cmds->runCommand( $_GET['id'] );
?>

Now, you can use Safari to browse to the page locally and just click the links to check whether the application works. If everything is in order, iTunes will go to the next or previous song depending on what you select.
One thing I did have to change on my installation was to edit the /etc/httpd/httpd.conf file, change the User setting to my user name, and change the Group setting to staff. I then rebooted my Apache server by running this command line:
% apachectl graceful

With that done, my iTunes interface flipped back and forth between tracks when I clicked the links. I can then turn on my iPhone and use the Safari browser to go to my local machine by IP address and access the application, as long as my laptop and my iPhone are on the same Wi-Fi network.
As I did the research for this article, I found that someone had already taken this whole concept of a Mac-driven remote for the iPhone to a new level. The project is called telekinesis, and it's hosted on the Google Code site. The application is called iPhone Remote, and it runs as a graphical user interface (GUI) application in Mac OS X.
When I launch iPhone Remote, it opens Safari to a page that shows what it will look like on the iPhone. This is shown in Figure 3.

From here, I can navigate to my applications and open them, browse my documents, use an iTunes remote, even navigate around the screen and run command lines—all from my iPhone.
The iPhone Remote does prompt you for a user name and password so that not just anyone can use your Mac after you've installed and run it. So, it's possible to use the iPhone as a secure virtual network computing (VNC) device for your Mac remotely.
Developing for the iPhone is a breeze. The ads say that the iPhone gives you access to the Internet as is rather than some mobile version of it, and the ads are right: You can browse to your normal pages just as you would on your Mac or PC. But toolkits like the iUI interface builder help give the application a more genuine iPhone look and feel—handy with applications like this XML and PHP-driven iPhone remote.


Tags: Php, Xml, Iphone app in Php


Comments

Popular posts from this blog

Create Desktop Application with PHP

Insert pandas dataframe into Mongodb

Add and delete columns dynamically in an HTML table