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.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

ESET Cyber Security 6.11.414.0 - Basic i...
ESET Cyber Security provides powerful protection against phishing, viruses, worms, and spyware. Offering similar functionality to ESET NOD32 Antivirus for Windows, ESET Cyber Security for Mac allows... Read more
Opera 105.0.4970.29 - High-performance W...
Opera is a fast and secure browser trusted by millions of users. With the intuitive interface, Speed Dial and visual bookmarks for organizing favorite sites, news feature with fresh, relevant content... Read more
Slack 4.35.131 - Collaborative communica...
Slack brings team communication and collaboration into one place so you can get more work done, whether you belong to a large enterprise or a small business. Check off your to-do list and move your... Read more
Viber 21.5.0 - Send messages and make fr...
Viber lets you send free messages and make free calls to other Viber users, on any device and network, in any country! Viber syncs your contacts, messages and call history with your mobile device, so... Read more
Hazel 5.3 - Create rules for organizing...
Hazel is your personal housekeeper, organizing and cleaning folders based on rules you define. Hazel can also manage your trash and uninstall your applications. Organize your files using a familiar... Read more
Duet 3.15.0.0 - Use your iPad as an exte...
Duet is the first app that allows you to use your iDevice as an extra display for your Mac using the Lightning or 30-pin cable. Note: This app requires a iOS companion app. Release notes were... Read more
DiskCatalogMaker 9.0.3 - Catalog your di...
DiskCatalogMaker is a simple disk management tool which catalogs disks. Simple, light-weight, and fast Finder-like intuitive look and feel Super-fast search algorithm Can compress catalog data for... Read more
Maintenance 3.1.2 - System maintenance u...
Maintenance is a system maintenance and cleaning utility. It allows you to run miscellaneous tasks of system maintenance: Check the the structure of the disk Repair permissions Run periodic scripts... Read more
Final Cut Pro 10.7 - Professional video...
Redesigned from the ground up, Final Cut Pro combines revolutionary video editing with a powerful media organization and incredible performance to let you create at the speed of thought.... Read more
Pro Video Formats 2.3 - Updates for prof...
The Pro Video Formats package provides support for the following codecs that are used in professional video workflows: Apple ProRes RAW and ProRes RAW HQ Apple Intermediate Codec Avid DNxHD® / Avid... Read more

Latest Forum Discussions

See All

New ‘Dysmantle’ iOS Update Adds Co-Op Mo...
We recently had a major update hit mobile for the open world survival and crafting adventure game Dysmantle ($4.99) from 10tons Ltd. Dysmantle was one of our favorite games of 2022, and with all of its paid DLC and updates, it is even better. | Read more »
PUBG Mobile pulls a marketing blinder wi...
Over the years, there have been a lot of different marketing gimmicks tried by companies and ambassadors, some of them land like Snoop Dog and his recent smoking misdirection, and some are just rather frustrating, let’s no lie. Tencent, however,... | Read more »
‘Goat Simulator 3’ Mobile Now Available...
Coffee Stain Publishing and Coffee Stain Malmo, the new mobile publishing studio have just released Goat Simulator 3 on iOS and Android as a premium release. Goat Simulator 3 debuted on PS5, Xbox Series X|S, and PC platforms. This is the second... | Read more »
‘Mini Motorways’ Huge Aurora Borealis Up...
Mini Motorways on Apple Arcade, Nintendo Switch, and Steam has gotten a huge update today with the Aurora Borealis patch bringing in Reykjavik, new achievements, challenges, iCloud improvements on Apple Arcade, and more. Mini Motorways remains one... | Read more »
Fan-Favorite Action RPG ‘Death’s Door’ i...
Last month Netflix revealed during their big Geeked Week event a number of new titles that would be heading to their Netflix Games service. Among them was Acid Nerve and Devolver Digital’s critically acclaimed action RPG Death’s Door, and without... | Read more »
SwitchArcade Round-Up: Reviews Featuring...
Hello gentle reader, and welcome to the SwitchArcade Round-Up for December 4th, 2023. I’ve been catching up on my work as much as possible lately, and that translates to a whopping six reviews for you to read today. The list includes Astlibra... | Read more »
‘Hi-Fi Rush’ Anniversary Interview: Dire...
Back in January, Tango Gameworks and Bethesda released one of my favorite games of all time with Hi-Fi Rush. As someone who adores character action and rhythm games, blending both together seemed like a perfect fit for my taste, but Hi-Fi Rush did... | Read more »
Best iPhone Game Updates: ‘Pizza Hero’,...
Hello everyone, and welcome to the week! It’s time once again for our look back at the noteworthy updates of the last seven days. Things are starting to chill out for the year, but we still have plenty of holiday updates ahead of us I’m sure. Some... | Read more »
New ‘Sonic Dream Team’ Performance Analy...
Sonic Dream Team (), the brand new Apple Arcade exclusive 3D Sonic action-platformer releases tomorrow. Read my in-depth interview with SEGA HARDLight here covering the game, future plans, potential 120fps, playable characters, the narrative, and... | Read more »
New ‘Zenless Zone Zero’ Trailer Showcase...
I missed this late last week, but HoYoverse released another playable character trailer for the upcoming urban fantasy action RPG Zenless Zone Zero. We’ve had a few trailers so far for playable characters, but the newest one focuses on Nicole... | Read more »

Price Scanner via MacPrices.net

Apple is clearing out last year’s M1-powered...
Apple has Certified Refurbished 11″ M1 iPad Pros available starting at $639 and ranging up to $310 off Apple’s original MSRP. Each iPad Pro comes with Apple’s standard one-year warranty, features a... Read more
Save $50 on these HomePods available today at...
Apple has Certified Refurbished White and Midnight HomePods available for $249, Certified Refurbished. That’s $50 off MSRP and the lowest price currently available for a full-size Apple HomePod this... Read more
New 16-inch M3 Pro MacBook Pros are on sale f...
Holiday MacBook deals are live at B&H Photo. Apple 16″ MacBook Pros with M3 Pro CPUs are in stock and on sale for $200-$250 off MSRP. Their prices are among the lowest currently available for... Read more
Christmas Deal Alert! Apple AirPods Pro with...
Walmart has Apple’s 2023 AirPods Pro with USB-C in stock and on sale for $189.99 on their online store as part of their Holiday sale. Their price is $60 off MSRP, and it’s currently the lowest price... Read more
Apple has Certified Refurbished iPhone 12 Pro...
Apple has unlocked Certified Refurbished iPhone 12 Pro models in stock starting at $589 and ranging up to $350 off original MSRP. Apple includes a standard one-year warranty and new outer shell with... Read more
Holiday Sale: Take $50 off every 10th-generat...
Amazon has Apple’s 10th-generation iPads on sale for $50 off MSRP, starting at $399, as part of their Holiday Sale. Their discount applies to all models and all colors. With the discount, Amazon’s... Read more
The latest Mac mini Holiday sales, get one to...
Apple retailers are offering Apple’s M2 Mac minis for $100 off MSRP as part of their Holiday sales. Prices start at only $499. Here are the lowest prices available: (1): Amazon has Apple’s M2-powered... Read more
Save $300 on a 24-inch iMac with these Certif...
With the recent introduction of new M3-powered 24″ iMacs, Apple dropped prices on clearance M1 iMacs in their Certified Refurbished store. Models are available starting at $1049 and range up to $300... Read more
Apple M1-powered iPad Airs are back on Holida...
Amazon has 10.9″ M1 WiFi iPad Airs back on Holiday sale for $100 off Apple’s MSRP, with prices starting at $499. Each includes free shipping. Their prices are the lowest available among the Apple... Read more
Sunday Sale: Apple 14-inch M3 MacBook Pro on...
B&H Photo has new 14″ M3 MacBook Pros, in Space Gray, on Holiday sale for $150 off MSRP, only $1449. B&H offers free 1-2 day delivery to most US addresses: – 14″ 8-Core M3 MacBook Pro (8GB... Read more

Jobs Board

Mobile Platform Engineer ( *Apple* /AirWatch)...
…systems, installing and maintaining certificates, navigating multiple network segments and Apple /IOS devices, Mobile Device Management systems such as AirWatch, and Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Senior Product Manager - *Apple* - DISH Net...
…Responsibilities** We are seeking an ambitious, data-driven thinker to assist the Apple Product Development team as our Wireless Product division continues to grow Read more
Senior Product Manager - *Apple* - DISH Net...
…Responsibilities** We are seeking an ambitious, data-driven thinker to assist the Apple Product Development team as our Wireless Product division continues to grow Read more
Senior Software Engineer - *Apple* Fundamen...
…center of Microsoft's efforts to empower our users to do more. The Apple Fundamentals team focused on defining and improving the end-to-end developer experience in Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.