TweetFollow Us on Twitter

Client-Server Development

Volume Number: 14 (1998)
Issue Number: 11
Column Tag: Viewpoint

Client/Server Development based on the Apple Event Object Model

by Sascha Kratky and Christoph Reichenberger (UNI SOFTWARE PLUS)
Edited by Richard Clark

Using AEOM for the design and implementation of the VOODOO client/server system

The term "Client/Server System" has become one of most used terms in today's computing world. We use client applications practically every day to transfer incoming emails from mail servers, download files from FTP servers, or to browse HTML pages offered on web servers all over the world.

Developers have chosen the client/server architecture as a reasonable means to structure large software systems, in order to make them leaner, more efficient, and easier to maintain. The basis of every client/server system forms the protocol that the client and the server applications are using to communicate with each other. For some applications like file transfer, mail transfer or hypertext transfer, there are well-known standardized protocols (e. g. FTP, SMTP, or HTTP) which remove the burden of having to design a proprietary protocol from scratch. Other areas, such as software version control, lack standardized protocols.

This article deals with the design and implementation of a protocol for a client/server based software version control system. It starts with a discussion of the basic properties of client/server systems. It explains why we chose to design and implement the protocol for the VOODOO client/server system on top of the Apple Event Object Model. A section on the problems that the developer faces when implementing a client/server system on top of the Apple Event Object Model concludes the article.

Client/Server Systems

The term "Client/Server System" refers to a general software architecture which can be applied to a variety of different applications. Most discussions of client/server systems take for granted that we are aware of the advantages that arise from using a client/server-based system. It may be worthwhile to recall the encouragement that originally led to the widespread use of client/server systems. A main motivation for a client/server system is that it provides an elegant solution for applications that need concurrent access of many clients to the same data. This simultaneous access problem is sketched in Figure 1.

Figure 1. In a non client-server system, multiple clients may access the same resource concurrently.

In this scenario clients access a database concurrently on the file system level. The database is usually stored on a file server machine on the network and clients have to mount the database in order to access it. This results in the following shortcomings:

  • All clients make concurrent changes to parts of the database. To avoid modifying parts of the database that are currently in use by another client, the clients have to implement a file system-based locking mechanism. Nevertheless, an unexpectedly interupted client process may leave the database in an unstable state. The consequences are higher chances of database corruption and the loss of valuable data.
  • Every client application must have full knowledge of the external representation of the database. A change to this representation means that all client applications have to be upgraded as well.
  • Propagating changes one client has made to the database to the other clients currently working on the database is difficult and unreliable. Every client would have to constantly poll the files of the database for changes made by other users in the meanwhile.

Interestingly enough, many commercial systems that claim to be truly client-server-based still follow this "file-server" approach and therefore suffer from the previously-mentioned drawbacks.

In a real client/server-system the clients do not access the database directly but get the needed data by sending requests to a server application, which is the only process that directly accesses the database (Figure 2). Instead of mounting the remote database the clients connect to a server process running on a remote machine.

Figure 2. In a client-server system, a server mediates all accesses to the shared resource.

This avoids the above-mentioned shortcomings for the following reasons:

  • Only the server application makes changes to the files of the database. The server can schedule the incoming requests by the clients, such that the consistency of the data in the database is always assured. When a client process dies, the server can take care of undoing any unfinished transactions of that client.
  • Only the server process has to know the external representation of the database. Clients are unaffected by changes to the representation as long as the communication protocol remains unchanged.
  • The server can propagate changes from one client to the other clients, since it can keep track which client has retrieved what data and when this data has become obsolete.
  • The server can postpone housekeeping tasks until idle time, i. e. no client has sent a request to the server for some time. In VOODOO Server, the server uses delta storage to store all the versions space-efficiently. The server performs the calculation of these deltas during idle time, such that check-in operations for clients solely consist of transferring the file to the server.

These advantages make the client-server architecture well suited for the implementation of a true multi-user aware version control system where users can simultaneously check-in and check-out files.

Apple Events and the Apple Event Object Model

Apple events were introduced with System 7 as a means for applications to communicate with other applications in a standard way. Applications use Apple events to request information from other applications or to return information as result to these requests. An application can send an Apple event to another application on the same computer, an application on a remote computer, and even to itself.

The Apple Event Object Model (AEOM) enables developers to structure the scripting interface of their applications in an object-oriented way. The AEOM allows both the definitions of Apple events and Apple event Classes. The Apple event Classes are templates for Apple event Objects. Each object encapsulates some data that the user can access via the object's properties. Properties are named attributes of an object. For example, an object of class window would have its name, size, and position as properties.

Apple event objects can be hierarchically structured by making some Apple event objects elements of other objects. For example, an application object can have document objects as its elements. The documents themselves have window objects as elements. The resulting hierarchy of objects is called the containment hierarchy.

Apple events act on these objects just like messages do in objects oriented programs. Related classes and events can be grouped together into suites. The most commonly used objects and events are group together in the Apple event Core Suite. The Apple events defined in the Core Suite include Create Element, Delete, Get Data and Set Data. Just as a user can apply the Cut, Copy, and Paste commands to almost any data on the screen these commands should be implemented in virtually every Apple event object.

Apple events and Apple Event Objects also form the basis for the AppleScript programming language. AppleScript scripts enable the user to write down series of Apple events in a very high-level "natural" language. Users typically write scripts to automate everyday work or to combine the functionality of different applications to achieve a desired result. [Other applications, such as UserLand's Frontier can also generate Apple events to drive your application. - ed RC]

In order to be scriptable an application must contain an Apple Event Terminology Extension resource (a resource of type AETE), which defines the containment hierarchy as well as the mapping of objects and events to the vocabulary. AETE resources allow AppleScript to support multiple "dialects" such as English and Japanese.

The attempt to fully explain the Apple Event Object Model would be beyond the scope of this article. For more information on Apple events, the AEOM and AppleScript see Inside Macintosh: Inter-Application Communications and the AppleScript Language Guide.

Why should you use Apple events and the Apple Event Object Model?

Using Apple events and the Apple Event Object Model as the basis for a protocol has a number of advantages not only for clearness and extensibility reasons but also for your development and testing process:

  • Supporting the AEOM and Apple's Core Suite guarantees consistency with the scripting interface of other applications. When moving from one scriptable application to another the user will encounter already many familiar terms. So your server application is not only accessible for your clients but becomes a well-behaved citizen in the world of Open Scripting Architecture-compliant applications such as Frontier and FaceSpan.
  • You can test the server application by writing AppleScripts, which send Apple events to the server. Since you can save these scripts you are able to reproduce the same tests over and over again. These test scripts can grow into a handy test suite for your server application.
  • You can quickly build a GUI that accesses your server application using RAD tools like FaceSpan. Using FaceSpan you can implement an application completely in AppleScript while the FaceSpan environment offers Apple event classes for most user interface elements like Windows, Button and Lists. This makes it fairly easy to build a complete Mac-like client application with minimal effort on top of your AE-based client/server interface.
  • AEOM based protocols are quite flexible when it becomes necessary to extend the protocol. You can add a property to a class or add a completely new class which supports existing events. Rarely is it necessary to define a new Apple event, since many of the existing events can also act on objects of the new class. In contrast, protocols built without the Object Model often contain a myriad of verb-noun hybrid commands such as GetPreferences, SetPreferences, GetFolder, SetFolder, etc. The only way to extend such a protocol is by adding new Apple event definitions.
  • The transition from "procedural" Apple events to the AEOM can be compared with the transition from a procedural oriented language like C to an object oriented language like C++. This implies that many object oriented design methods like design patterns (1, 5) can also be applied to the design of your custom Apple Event Object Model making the design more flexible and easier to understand.

Designing your Custom AEOM

The following section guides you through the process of designing a client-server protocol based on the AEOM. We will use the protocol of our VOODOO Server application as an example here. Let us briefly explain VOODOO's functionality and data types in order to help you better understand the following description of the object hierarchy.

The VOODOO Server application is designed as an almost faceless server application, which exposes all its functionality through the Apple Event Object Model. Clients should be able to access all data stored in the server's database by sending requests to the server. Therefore, it was our goal that all elements of a VOODOO database should be modeled by means of Apple Event Objects. A VOODOO database holds collections of projects, parts and users. Users can log on to the server and open projects in the database. A project is further divided into different parts. A part represents a directory structure that is put under version control. Parts can also be shared among different projects. Figure 3 shows a VOODOO database for an example compiler project.

Figure 3. Structure of a VOODOO Server database.

The example database contains two projects: "Compiler" and "Linker". The project "Compiler" consists of the parts "Compiler" that stores all compiler specific files and a part "Toolslib" with common utility files. The part "Toolslib" is shared with the project "Linker", such that all changes made to "Toolslib" from the Compiler project are immediately visible in the project "Linker", too.

As mentioned, a part in the VOODOO database corresponds to a directory tree of the user's hard disk. The user can add files and folders to a part, fetch files from the part for modification and store a new versions to the database later. The VOODOO server takes care of storing different versions of files space efficiently using a combination of delta and compression algorithms. Each time a modification has been made to a part's item the server adds an event to the part's history. The event contains the date of the change, the user, the kind of change (e. g. added, revised, renamed, etc.), the items in the part that were changed and a comment. Besides that, the user can add a bookmark at an arbitrary point in time of the history to label milestones of the project.

It would be beyond the scope of this article to describe the full functionality of the VOODOO server. The server will form the basis for a new generation of version control tools to be released by UNI SOFTWARE PLUS in the near future but is also available for licensing to allow other companies to integrate version control functionality directly into their products. If you are interested in more details or want to download a free demo version, please visit <http://www.unisoft.co.at> or send an email to <voodoo@unisoft.co.at>.

Classes

The elements of a VOODOO database have been modeled as classes in the VOODOO suite. The inheritance hierarchy of these classes is sketched in Figure 4.

Figure 4. Inheritance hierarchy of the classes of the VOODOO AEOM.

All classes inherit from a common base class, which defines properties that are common to all the object classes. The directory tree of a part consists of files and folders. Therefore the base class of both is vItem, which represents a node in this tree. The part history contains both events and bookmarks. The common properties of these two classes have been extracted into a class entry which represents an entry in the part history.

Note that the names vItem, vFile, and vFolder were chosen to avoid name clashes with the terms item, file, folder which are the names of standard types in AppleScript.

The hierarchical relations of the objects can be seen in the containment hierarchy (Figure 5).

An object of class database forms the root of the containment hierarchy. The database contains user and project objects as elements. The recursive structure of directory trees is mirrored by the fact that the vFolder object can contain other vFolder objects.

Note that some object classes appear several times in the containment hierarchy. For example a vItem object contains all event objects that are valid for this item. This is a subset of the set of all the event objects that are valid for the whole part.

Figure 5. Containment hierarchy within the VOODOO AEOM.

Events

Once you have designed the inheritance and containment hierarchy for the classes, Apple event definitions can be added to your suite. Most of the events that you find you have to support are already defined in the Apple event Core Suite. As an example the following script shows how the Create Element event can be used to create files and folders in a part of the VOODOO database:

tell application "VOODOO Server"
   tell first database
      tell part "Compiler" of project "Compiler"
         make new vFolder at the end of it¨
            with properties {name:"FrontEnd"}
         make new vFile at the end of result¨
            with properties {name:"Scanner.c"}
      end tell
   end tell
end tell

To retrieve data from the database the Get Data and Count Elements Apple events can be used. The following script shows the use of these events.

tell application "VOODOO Server"
   tell project "Compiler" of first database
      - What parts does the project "Compiler" consist of?
      get name of every part
      tell part "Compiler"
- How many versions of the file "Scanner.c" have been stored?
         count every vVersion of vFile ¨
            "Scanner.c" in vFolder "FrontEnd"
      end tell
   end tell
end tell

When a user wants to store a new version of a file to a part, the data of this file has to be transferred to the server on the remote machine via Apple events. The following Apple events of the VOODOO Suite allow the transfer a particular version of a file to the database:

start store: announce a new store task
   start store  reference   - the vFile to be stored to
      [comment  string]     - comment describing new version
      [unlock  boolean]     - unlock vFile after store is finished (default:false)
   Result:   reference      - the newly created store task

The Apple event start store tells the server that the user wants to store data of a new version to a file. The comment parameter of the Apple event is used to initialize the comment of the event object that will be added to the part's history. The unlock parameter tells the server to unlock the file to be stored to, if the user previously locked it to prevent other users from making changes to it. The Apple event returns a reference to a store task as result, which is used later to store the actual data.

store: store data valid for the specified store task
   store  reference          - the store task the data is valid for
      data  anything         - the data block to be stored

The actual data of the version is transferred to the Server using one or several store Apple events (the data can be transferred in one block or in several chunks).

finish: finish the specified task
   finish  reference         - the task to finish

When all the data has been transferred to the server the client sends a finish Apple event to the store task to signal that the transfer is complete. The following example script illustrates the use of these Apple events:

tell application "VOODOO Server"
   tell first database
      tell part "Compiler" of project "Compiler"
         start store vFile "Scanner.c" in vFolder "FrontEnd"
         set theStoreTask to result
         store theStoreTask data "/* Scanner.c */"
         - store additional data ...
         finish theStoreTask
      end tell
   end tell
end tell
Using these Apple events many users can store data to the server at the same time. The server receives the versions, puts them into an incoming pool and takes care of storing these items space efficiently when there's nothing else to do.

Implementation Issues

Once you have designed your Object Model, you must implement the necessary handlers for resolving the Apple event object references and for processing the Apple events. This section gives some hints for implementing a server application and covers some implementation details that are particular for an AEOM based server application. The latter requires careful attention to identifying and maintaining multiple client/server connections.

First of all we want recommend you use an application framework that provides support for the AEOM in order to reduce your own implementation efforts. Metrowerks' PowerPlant is an example of an application framework that has extensive AEOM support. In PowerPlant, the AEOM can be implemented by adding classes to the framework using LModelObject as a base class and overriding methods to handle specific Apple events. PowerPlant already supports many of the events of the Core Suite. The exact details of implementing an AEOM in PowerPlant have been thoroughly described in (4).

Factor your Application

It is a good idea to factor your server application into domain-specific and communication-specific parts. This enables you to replace the communication layer of the server with a different protocol or to add support for other protocols. Figure 6 shows how this has been done in the VOODOO server application.

Figure 6. Structure of the VOODOO Server application.

The VOODOO Engine, which contains the code to access the data in the VOODOO database, is based on the ANSI C++ Standard Library only. The AEOM handling code is built on top of PowerPlant and calls the VOODOO engine to access the data in the VOODOO database. The very small user interface part of the VOODOO Server application also is based on PowerPlant.

Identifying Different PPC Sessions

An essential task of a server application is to keep track of all the connections of clients in order to be able to perform initializations when a new connection is established and cleanups when a connection is closed. Note that connections are not always closed explicitly by the client. The client process may crash and a server must be able to deal with this situation properly in order to ensure data integrity.

A TCP/IP based server has full control over its connections since it awaits and accepts new connections at a dedicated port. The server can easily keep track of all the connections that have been established by clients. When the client side unexpectedly closes the connection, an error is usually pending on the connection's socket on the server side.

With Apple events the situation is different. The Apple Event Manager does not explicitly inform the server application when a new session with a client is established. There is also no particular notification available when a session to a client application has been closed. Instead, the application receives all Apple events as high level events during normal event processing within the main event loop. The usual way to process an Apple event is to pass it to the Apple Event Manger function AEProcessAppleEvent, which then activates the appropriate Apple event Handler function.

However, the communication with Apple events is based on the PPC Toolbox. By using a combination of Apple Event Manger and PPC Toolbox calls, the developer can gain control over the server's session handling again. The following code examples illustrate how this can be done. The key idea is to wrap all the necessary Toolbox calls in a class PPCSession that represents a client's active connection to the server. For simplicity we use PowerPlant container classes in the following example code.

Class PPCSession

class PPCSession {
public:
   PPCSession(const AppleEvent& inAppleEvent);
   virtual PPCSessRefNum GetID();
   static PPCSession* FindSession(PPCSessRefNum inSessID);
   static void VerifySessions();
   virtual Boolean IsActive();
   virtual ~PPCSession();
protected:
   virtual void Closed();
   PPCSessRefNum                     mSessionID;
   PPCReadPBRec                      mPBRec;
   static TArray<PPCSession*>  sActiveSessions;
};

The class PPCSession can be used as is or as a base class for more elaborate session classes. The VOODOO Server overrides this class to add information for which user has logged on in this session and which projects the user has opened.

PPCSession::PPCSession

PPCSession::PPCSession(const AppleEvent& inAppleEvent)
{
   OSErr      err;
   Size         bogusSize;
   DescType   bogusType;
   TargetID   addr;
      
   err = ::AEGetAttributePtr(&inAppleEvent,
                  keyAddressAttr, typeTargetID,
                  &bogusType, &addr, sizeof(addr), &bogusSize);
   ThrowIfOSErr_(err);
   mSessionID = addr.sessionID;
   mPBRec.ioResult = 0;
   sActiveSessions.AddItem(this);
}

The constructor takes an Apple event as its only parameter and examines the address attribute of this Apple event. The address attribute contains the PPC session reference number of the underlying PPC session and the address of the machine on the AppleTalk network from which the Apple event was sent. The session reference number is stored in the instance variable mSessionID. The session object then inserts itself into the list of all active PPCSession objects. The instance variable mPBRec which is used by the IsActive method is initialized, too (see below).

PPCSession::GetID

PPCSessRefNum
PPCSession::GetID()
{
   return mSessionID;
}

The method GetID is an accessor function that returns the session reference number of the PPC session.

PPCSession:: FindSession

PPCSession*
PPCSession::FindSession(PPCSessRefNum inSessID)
{
   PPCSession* sess;
   TArrayIterator<PPCSession*> iterator(sActiveSessions);
   while (iterator.Next(sess)) {
      if (sess->GetID() == inSessID) {
         return sess;
      }
   }
   return nil;
}

The class method FindSession searches the list of all PPCSession objects for an object with the given Session Reference Number. The search is done using a PowerPlant iterator object.

PPCSession::VerifySessions

void
PPCSession::VerifySessions()
{
   PPCSession* sess;
   TArrayIterator<PPCSession*> iterator(sActiveSessions);
   while (iterator.Next(sess)) {
      if (!sess->IsActive()) {
         sess->Closed();
         delete sess;
      }
   }
}

PPCSession:: Closed

void
PPCSession::Closed()
{
   // should be overwritten!
}

VerifySessions is a class method that should be called periodically by the server application to verify that the server's connections are still intact. An ideal location for calling this method would probably be the idle handler of your application. The function iterates through the list of all PPCSession objects and deletes those objects whose underlying PPC session has been closed by the client side. Before the object is deleted, the message Closed is sent to the object. Derived classes of PPCSession can override the Closed method to perform cleanup tasks, when the connection has been unexpectedly closed. The VOODOO Server takes care of aborting any of the user's unfinished storage tasks, closing any of the user's opened projects, and logging off the user.

PPCSession::IsActive

Boolean
PPCSession::IsActive()
{
   if (mPBRec.ioResult == 0) {
      // test if session is still active 
      mPBRec.ioCompletion = nil;
      mPBRec.sessRefNum   = mSessionID;
      mPBRec.bufferLength = 0;
      mPBRec.bufferPtr    = nil;
      OSErr err = ::PPCReadAsync(&mPBRec);
      return (err == noErr);
   }
   else {
      // assume that session is active
      // if asynchronous call has not yet finished
      return (mPBRec.ioResult == 1);
   }
}

The actual check whether a PPC session is still intact is done inside the method IsActive. This function tries to read a zero length block from the PPC session, so no data is actually fetched, but an error message will be returned from the call when the session is no longer intact. The actual call of PPCRead is done asynchronously. Therefore the call's parameter block can not be declared as a local variable. For simplicity we made mPBRec an instance variable of the class PPCSession. If the asynchronous PPCRead call has not yet finished, it is assumed that the session is still active.

PPCSession::~PPCSession

PPCSession::~PPCSession()
{
   sActiveSessions.Remove(this);
   if (mPBRec.ioResult == 1) {
      // finishing asynchronous calls
      PPCEndPBRec pb;
      pb.ioCompletion = nil;
      pb.sessRefNum   = mSessionID;
      ::PPCEndSync(&pb);
   }
}

The classes' destructor removes the PPCSession object from the list of active sessions. If an asynchronous call is still pending for the session, this call is finished using the PPCEnd toolbox call. This is necessary since the parameter block mPBRec is not longer valid after the execution of the object's destructor.

MyAppleEventHandler

pascal OSErr
MyAppleEventHandler(
   const AppleEvent*   inAppleEvent,
   AppleEvent*            outAEReply,
   SInt32                     inRefCon)
{
   Size               bogusSize;
   DescType         bogusType;
   TargetID         addr;
   short            eventSource;
   PPCSession*      sess;

   err = ::AEGetAttributePtr(&inAppleEvent, keyAddressAttr,
           typeTargetID,
           &bogusType, &addr, sizeof(addr), &bogusSize);
   if (err != noErr) return err;
   sess = PPCSession::FindSession(addr.sessionID);
   if (sess == nil) {
      // a new session has been established
      sess = new PPCSession(inAppleEvent);
   }
   // continue with normal Apple event processing
}

The Apple event handler of your server application is the right place to create the session objects. The function MyAppleEventHandler sketches the necessary operations. The handler first examines the Apple event's address attribute to get the session reference number. If there is no PPCSession object valid for the session reference number, a new PPC session has been established by a client.

User Interaction

A server application usually runs unattended by the user on a remote machine. An Apple event based server application can thus not make use of the user interaction calls of the Apple Event Manager. The only way for the server application to interact with the user is to return error messages. The error message should contain both a unique error number and an error message string. For a further discussion of user interaction in Apple event based server applications see (6).

Concurrency

An Apple event server application can receive events from different client applications at the same time. While the server is busy handling an Apple event from one client, Apple events of other clients are delayed. It is important for the server to be as responsive to clients as possible, otherwise the server application becomes the bottleneck of the client/server system.

With Apple events the server has the possibility to suspend the handling of an Apple event using the AESuspendTheCurrenEvent toolbox call and continue processing other events. Execution of the suspended Apple event can be resumed later using the AESuspendTheCurrentEvent. Each suspended Apple event can then be assigned an own thread of execution. See (2) for details how to thread the execution of Apple events.

Conclusion

The Apple Event Object Model is an ideal choice when designing the protocol for a client-server-based application. This article discussed some issues you should consider when designing a protocol of a client/server system based on the AEOM. It showed the advantages of using Apple events and in particular the Apple Event Object Model. Thanks to the object-oriented nature of the AEOM the data provided by the server can be designed using an object-oriented approach. However, using Apple events as the communication basis for a client/server system also leads to some problems, especially what concerns the accurate control of connections. The paper finally presented a solution to gain the necessary control by using services of the PPC Toolbox.

Bibliography and References

  1. E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns,. Addison-Wesley, ISBN 0-201-63361-2, 1995
  2. Grant Neufeld. "Threading Apple Events". MacTech Magazine 12:4 (April 1996), pp. 33-40.
  3. Christoph Reichenberger. "Keeping Things Straight, Orthogonally" MacTech Magazine 12:6 (June 1996), pp. 61-70.
  4. Jeremy Roschelle. "Powering Up Apple Events in PowerPlant". MacTech Magazine 11:6 (June 1995), pp. 33-46.
  5. John Schettino. "The Tao of Design". MacTech Magazine 13:4 (April 1997), pp. 30-39.
  6. Cal Simone. "According To Script: User Interaction in Apple Event-Driven Applications". Develop, Issue 29 (May 1997), pp. 74-80.
  7. Cal Simone. "The AppleScript Scorecard Guidelines". MacTech Magazine 14:2 (February 1998), pp. 16-18.
  8. Cal Simone. "According To Script: An External Editing Apple Event Protocol". Develop in MacTech Magazine 13:5 (April 1997), pp. 30-39.

Sascha Kratky studied computer science at the Johannes Kepler University in Linz, Austria. After graduation he joined UNI SOFTWARE PLUS where he is working on the VOODOO project. You can reach Sascha by sending email to kratky@unisoft.co.at.

Christoph Reichenberger studied computer science at the Johannes Kepler University Linz, Austria. After that he worked there as an assistant professor for seven years and finalized his work with a PhD thesis on software configuration management. Then he joined UNI SOFTWARE PLUS where he is now managing the VOODOO product line which is an offspring of his former research work. He can be reached via email at chrei@unisoft.co.at. The home page of UNI SOFTWARE PLUS can be visited at http://www.unisoft.co.at.

 
AAPL
$94.27
Apple Inc.
+0.33
MSFT
$44.97
Microsoft Corpora
+0.13
GOOG
$598.71
Google Inc.
+9.23

MacTech Search:
Community Search:

Software Updates via MacUpdate

Macs Fan Control 1.1.12 - Monitor and co...
Macs Fan Control allows you to monitor and control almost any aspect of your computer's fans, with support for controlling fan speed, temperature sensors pane, menu-bar icon, and autostart with... Read more
A Better Finder Rename 9.37 - File, phot...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more
MacBook Air EFI Firmware Update 2.9 - Fo...
MacBook Air EFI Firmware Update is recommended for MacBook Air (Mid 2011) models. This update addresses an issue where systems may take longer to wake from sleep than expected and fixes a rare issue... Read more
FileZilla 3.9.0.1 - Fast and reliable FT...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface.Version 3.9.0.1: MSW: Fix installation issue with locked DLLs... Read more
OS X Yosemite 10.10 DP4 - Developer Prev...
Note: This is a Developer Preview. You must be a registered Apple Mac Developer to download this update. OS X Yosemite is Apple's newest operating system for Mac. An elegant design that feels... Read more
FinderPop 2.5.6 - Classic Mac utility, n...
FinderPop is a Universal preference pane that extends OS X's contextual menus using a FinderPop Items folder much as the Apple Menu Items folder used to do for the Apple menu. It has other features... Read more
SpiderOak 5.1.7 - Secure cloud backup, s...
SpiderOak is a multi-platform secure online backup, storage, access, and sharing solution engineered for the consumer and small businesses. You must first sign up to use SpiderOak. Running natively... Read more
Espionage 3.6 - Simple, state of the art...
Espionage offers state-of-the-art encryption and plausible deniability for your confidential data. Sometimes, encrypting your data isn't enough to protect it. That's why Espionage 3 goes beyond data... Read more
calibre 1.45.0 - Complete e-library mana...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
iFFmpeg 4.3.1 - Convert multimedia files...
iFFmpeg is a graphical front-end for FFmpeg, a command-line tool used to convert multimedia files between formats. The command line instructions can be very hard to master/understand, so iFFmpeg does... Read more

Latest Forum Discussions

See All

FlyCraft Herbie: Crazy Machines Review
FlyCraft Herbie: Crazy Machines Review By Jennifer Allen on July 22nd, 2014 Our Rating: :: TRICKY FLYINGUniversal App - Designed for iPhone and iPad A tough game of careful thrusting and navigation, FlyCraft Herbie: Crazy Machines... | Read more »
MTN Review
MTN Review By Jessica Fisher on July 22nd, 2014 Our Rating: :: ADORABLE, SERENE, AND AMUSINGUniversal App - Designed for iPhone and iPad MTN is an adorable, talking pet mountain that is less game and more zen garden.   | Read more »
Fly High with Ninja UP! Now Available o...
Fly High with Ninja UP! Now Available on the App Store Posted by Jessica Fisher on July 22nd, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Bio Inc. Review
Bio Inc. Review By Nadia Oxford on July 22nd, 2014 Our Rating: :: SICKENING - IN A COMPELLING WAYUniversal App - Designed for iPhone and iPad Bio Inc is about orchestrating the medical destruction of a single person. If that doesn’... | Read more »
HELMUT Review
HELMUT Review By Andrew Fisher on July 21st, 2014 Our Rating: :: TRUNDLE SIMULATOR 2014Universal App - Designed for iPhone and iPad HELMUT is a fun, fleeting time-sink that offers a momentary distraction and nothing else.   | Read more »
Walkr Review
Walkr Review By Jennifer Allen on July 21st, 2014 Our Rating: :: ORIGINAL WALKINGiPhone App - Designed for the iPhone, compatible with the iPad Walking is a bit more exciting thanks to this planet building/discovering sim reliant... | Read more »
Zombie Commando Review
Zombie Commando Review By Jennifer Allen on July 21st, 2014 Our Rating: :: MINDLESS SLAUGHTERUniversal App - Designed for iPhone and iPad Briefly fun but ultimately forgettable, Zombie Commando will scratch an itch then be... | Read more »
Swords & Poker Adventures Review
Swords & Poker Adventures Review By Jennifer Allen on July 21st, 2014 Our Rating: :: SOULLESS POKER PLAYUniversal App - Designed for iPhone and iPad Swords & Poker Adventures is a mishmash of Poker and RPGing, but it lacks... | Read more »
Warhammer 40,000: The Horus Heresy: Drop...
Warhammer 40,000: The Horus Heresy: Drop Assault Coming Soon to iOS Posted by Jennifer Allen on July 21st, 2014 [ permalink ] Coming soon to iOS will be an all-new Warhammer 40,000 tactical strategy game by the name of The Horus Heresy: Drop As | Read more »
A Life Worth Dying For Review
A Life Worth Dying For Review By Jordan Minor on July 21st, 2014 Our Rating: :: A BEAUTIFUL MINDUniversal App - Designed for iPhone and iPad A Life Worth Dying For is a fascinating portrait of a serious subject.   | Read more »

Price Scanner via MacPrices.net

Twelve South HiRise For MacBook – Height-Adju...
If you use your MacBook as a workhorse desktop substitute, as many of us do, a laptop stand combined with an external keyboard and pointing device are pretty much obligatory if you want to avoid... Read more
Why The Mac Was Not Included In The Apple/IBM...
TUAW’s Yoni Heisler cites Fredrick Paul of Network World whoi blogged last week that the Mac’s conspicuous absence from Apple and IBM’s landmark partnership agreement represents a huge squandered... Read more
Save $100 on 13-inch Retina MacBook Pros, plu...
Adorama has 13″ Retina MacBook Pros on sale for $100 off MSRP. Shipping is free, and Adorama charges sales tax in NY & NJ only: - 13″ 2.4GHz/128GB MacBook Pro with Retina Display: $1199 - 13″ 2.... Read more
Blurr it 2.3 for iOS – Quickly Blurs Selected...
Hyderabad, India based TouchLabs has announced a new update of Blurr it 2.3, their photography app for iOS users. Blurr it allows you to blur part of the image to hide potentially sensitive or... Read more
MacBook Airs on sale for $100 off MSRP, start...
Best Buy has the new 2014 MacBook Airs on sale for up to $100 off MSRP on their online store. Choose free home shipping or free local store pickup (if available). Prices valid for online orders only... Read more
Amazon Announces Kindle Unlimited: Unlimited...
Amazon.com has introduced Kindle Unlimited — a new subscription service which allows customers to freely read as much as they want from over 600,000 Kindle books, and listen as much as they want to... Read more
New Linksys Wireless Range Extenders Boost Wi...
Linksys has announced its new lineup of Linksys Wi-Fi Range Extenders. Consumers often experience a weak wireless signal in some parts of their house or apartment caused by blocking elements such as... Read more
MacBook Airs available starting at $719
The Apple Store has Apple Certified Refurbished 2013 & 2012 MacBook Airs in stock today starting at $719. An Apple one-year warranty is included with each MacBook, and shipping is free: 2013... Read more
Get the best deals on iPad minis with Apple r...
The Apple Store has Certified Refurbished 2nd generation iPad minis with Retina Displays available for up to $130 off the cost of new models, starting at $339. Apple’s one-year warranty is included... Read more
Best Buy’s College Student Deals: $100 off Ma...
Take an additional $100 off all MacBooks and iMacs, $50 off iPad Airs and iPad minis, at Best Buy Online with their College Students Deals Savings, valid through July 25th. Anyone with a valid .EDU... Read more

Jobs Board

*Apple* Computer Technician - Fairfield Coun...
Company DescriptionWe are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over 20 Read more
*Apple* Computer Technician - Fairfield Coun...
Company DescriptionWe are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over 20 Read more
Mac Expert - *Apple* Online Store Mexico -...
…MUST be fluent in English and Spanish to be considered for this position At Apple , we believe that hard work, a fun environment, creativity and innovation fuel the Read more
*Apple* Computer Technician - Fairfield Coun...
Company DescriptionWe are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over 20 Read more
Mac Expert - *Apple* Online Store - Apple (...
**Job Summary** At Apple , we believe that hard work, a fun environment, creativity and innovation fuel the ultimate customer experience. We believe each customer Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.