A pet project of mine, InstantChat, went live on the App Store today. It’s a (very) simple chat app that lets you quickly connect and chat with any nearby iPhone, iPod touch, or iPad via Bluetooth. I’m planning on adding some more features in the near future, such as Wi-Fi connectivity, chat history logging, and a few other goodies.
Archive for the ‘Development’ Category
Why You Should Care About UI
Sunday, December 12th, 2010I know a lot of developers aren’t great with UI design, or “making it look pretty” as some will call it, but too often it seems that making necessary improvements to the interface of an application or site is the subject of procrastination — “we’ll get to it when we have time” — and then time never arrives, as many other things are considered more important. Even when a company has a full-time designer, it seems that the designer often has the struggle of selling people on their cause before they can get significant changes made, because developers often feel it isn’t important to make the requested changes if the site already works, although the user’s experience may be suboptimal.
I have seen this many times, and often it is even further shadowed by the fact that the product or site is popular with its customers, or that people have used it for a long time, so it must be fine, right? Wrong. Just because people are buying or using your product doesn’t mean there aren’t problems with it, or that it doesn’t need improvement. And you can’t always rely on the customer to tell you what they want to see in terms of UI, because they often don’t know — they just want it to work with the least amount of effort necessary.
This is the concept that is important to keep in mind when developing the application as well, as many complex applications have complex UIs that are completely necessary. It is often assumed that flexibility requires complexity, but there are many good examples that this is not the case. A good working example would be the file search feature in Apple’s Mac OS X Finder.
Rather than bombarding the user with every possible option, they are initially presented with a simple search field, present at the corner of every file window. Typing in that field will initiate a quick search for files that match the entered text, and the toolbar shows just a couple of options, allowing the user to specify if they want to search the entire computer or just their folder, and if they want to show all files that contain the text, or just ones whose names match. Clicking the plus sign to the right offers an additional row, allowing the user to further refine the search by selecting a property and a condition (i.e. “Kind” is “PDF” or “Name” “begins with” “Agreement”). The user can then continue adding these filters to obtain as much detail as they need. While the display can become cluttered with several of these filter bars, it is not as confusing or overwhelming as the countless and little used search boxes may be on some “advanced” searching interfaces, where the user must look through a wide array of fields to determine which fields require input to filter results.
It is this mindset of keeping UI elements simple and relevant to the user that is necessary for sites and applications to thrive. If your interface is clean, simple and functional, not only will users buy your product or service and continue to use it, but they will actually enjoy using it and be more likely to offer positive recommendations to others because they enjoy it.
Using Magic Methods to Call Remote Functions
Saturday, November 27th, 2010Have you ever wanted to directly call a function or method that is in a script on another server? I know it sounds crazy, but stay with me here. Initially, my answer to this solution was to write an XML interface, which seemed entirely logical especially since both sides of the equation weren’t necessarily running in PHP.
So to execute a service on another machine, the front-end server would have an object definition, which would both provide a defined structure for the object (such as a payment), as well as offering some common methods to perform a remote request to the backend server to actually do some work. When the object was ready to do something, it would call its own request method, passing in a URL to an interface page, and the request method would handle building an XML request based on the properties of the object, posting the XML to the page that was passed in, and then returning the XML response when all was done. On the other side of the picture, the page that is handling the request would in turn initialize a similarly structured object, which was defined with the necessary methods to perform the work requested (such as processing a payment). For example, in order to call the MakePayment method on the payment object, the frontend would need a MakePayment method, which sets up the payment details and initiates the XML request, and then the XML interface would need a handler created to set up the payment and handle calling the MakePayment method on the actual object on the backend server.
Definitely not the most elegant solution, but it made the most sense when we originally encountered the need to pass requests between servers, particularly due to the language differences I mentioned earlier.
Some of the best and craziest ideas happen by chance, and that’s exactly how I stumbled upon this idea. A coworker was having some difficulty with one of the services, and was slightly confused by which code was causing the problem, as there were effectively four components in the mix — the display page on the frontend, the service’s object definition, the XML interface on the backend server, and the “real” object definition there. After seeing the error he was getting and having a look at the code, I determined the problem was that he was just missing a method definition on the frontend, and would need to create one. When I explained this, however, he responded with a simple question: “Why can’t I just call this method directly?” My initial response, of course, was to say “because it’s on another server” and that you can’t simply make calls across systems like that, but then I started wondering exactly the same thing — why not?
I knew that you could transfer information across systems easily by storing session data in a shared database, and I started to wonder why a similar principle wouldn’t work for directly calling methods. So the solution I came up with is actually relatively simple: serialize the request object and send the entire object over the POST to the other server. The handler on that server just needs to unserialize it there, and call the requested method, and then serialize and return the response. I further simplified this by defining a __call “magic method” on the template object that automatically facilitates the request, allowing you to call any method that is defined on the backend server’s object in the code on the frontend without having to define the methods on both servers.
There are, of course, some gotchas to watch out for (some objects can’t be easily serialized, such as SimpleXMLElements), but for the most part this works pretty well and requires very little code to function on the frontend server.
Simplify Reporting Output
Tuesday, March 17th, 2009$Report = new Report( "My Report" );
if (isset($_GET['format'])) {
$Report->Type = $_GET['format'];
}
$Report->Columns = array("Employee", "Department", "Salary");
foreach ($Employees as $Employee) {
$Report->Rows[] = array($Employee->Name, $Employee->Department, $Employee->Salary);
}
$Report->Display();
Recently, I have been tasked having to generate several reports containing various metrics, and then export these into an Excel sheet so that the data can be processed further. I also occasionally get requests for data in a CSV format that can be imported into another system. And these are just for the one-off reports... most of the standard reporting tools I have written produce data in an XML format, which is then procssed by an AJAX frontend and displayed in an HTML table to the user. Talk about messy.
So this morning, I finally sat down and wrote out a report abstraction class that has been floating around in my head for the past couple of months. Rather than have to worry about writing display code when building a report, I can simply deal with the data and hand it over to the class for display processing:
$Report = new Report( "My Report" );
if (isset($_GET['format'])) {
$Report->Type = $_GET['format'];
}$Report->Columns = array("Employee", "Department", "Salary");
foreach ($Employees as $Employee) {
$Report->Rows[] = array($Employee->Name, $Employee->Department, $Employee->Salary);
}
$Report->Display();
From there, the class takes the type identifier (which in this case is being selected by the user and passed in the URL), and provides the data in the correct format. The class itself is fairly small, weighing in with less than 200 lines of code, but can display data in Excel, CSV, XML, HTML, or PDF, as well as a printer-optimized layout if the data is intended to be printed instead of displayed on-screen.





