TweetFollow Us on Twitter

Opening Up OpenDoc
Volume Number:11
Issue Number:1
Column Tag:New Apple Technology

Opening Up OpenDoc™

Creating focused, intuitive, easy to use software,
while leaving room to add features.

By Jens Peter Alfke & Jordan Mattson, Apple Computer, Inc.

The Software Problem

As authors of software, we are faced with competing demands from our customers. On the one hand, our users want applications that are easy to understand and use. On the other hand, they also want them to be feature rich and up-to-date with the latest system software releases from Apple.

In addressing users’ second demand - for feature-rich software (which is, after all, more useful to them) - we often end up creating big, difficult-to-understand, and difficult-to-use applications. Hence, in our quest to make our applications more useful, we have (in reality) made them less useful. In addition, our big, monolithic, all-in-one applications are difficult to maintain, so it’s difficult to add features and adapt new technologies from Apple.

What we need to solve this dilemma is a new way to create applications that allows developers to create focused, intuitive, and easy-to-use software, while at the same time allowing them to easily add new features.

The OpenDoc Solution

Apple offers OpenDoc as the solution to these problems. OpenDoc provides an architecture for applications that allows developers to create applications that are, in reality, a collection of components. OpenDoc’s features enable developers and users to create applications that meet their needs.

Component Architecture

In the OpenDoc world, applications are no longer large monoliths. Rather, they are collections of interconnected components. The components that make up an “application” in the OpenDoc world may or may not be from a single developer. In fact, they may have been turned into an “application” or custom solution by knowledgeable users, rather than the application developer.

In many ways, OpenDoc components can be mixed and matched to create custom solutions, much as Open Scripting Architecture compliant and AppleEvent aware applications can be crafted into custom solution. Of course, OpenDoc parts will have a much finer granularity than today’s scriptable applications.

Compound Document Support

One of the direct benefits of the OpenDoc component architecture is that components - or parts as they are referred to in the OpenDoc world - from different developers are able to transparently work together to produce a single document for the end user.

The benefit of compound documents for end users should not be underestimated. In fact, during OpenDoc user testing, many users remarked, “ you fixed the bugs ”, because they now could easily move from creating and editing one data type to another in a single document.

Customizability

A second major feature of OpenDoc is that parts are scriptable. This allows end users to customize their applications to meet their specific needs. This feature along with the component architecture of OpenDoc also allows for easy combination of parts from different sources into custom solutions.

Collaboration

The first version of OpenDoc implements a “draft” capability which allows you to easily track versions of a particular document and revert to an earlier version of need be. The OpenDoc architecture allows for authentication, digital signatures, store & forward messaging, and simultaneous access to documents. These features will appear in future versions of OpenDoc.

Cross-Platform

In response to the need to deploy the same application on multiple platforms, OpenDoc was designed from the ground up as a cross-platform application architecture. To this end, Component Integration Laboratories (also known as CILabs) is releasing OpenDoc as a reference specification and implementations. Individual vendors will then implement it on specific platforms. Various vendors have committed to implementing OpenDoc on Mac OS, Windows, OS/2, and AIX. Additional commitments are expected in the near future.

Replaceability

Because OpenDoc is designed to be a cross-platform architecture, it was imperative that the major sub-systems of OpenDoc be replaceable. This would allow for ease of adoption on various platforms, by allowing platform implementors to use technology present on their platform to implement OpenDoc by adhering to the OpenDoc reference specification.

Parsimony

Trying to address the plethora of issues involved in creating a cross platform programming environment (e.g. drawing systems, coordinate systems, etc.) is daunting. For this reason, the OpenDoc team has avoided addressing platform specific issues (for example, OpenDoc does not deal with QuickDraw or QuickDraw GX), and has instead focused on creating a human focused application architecture.

By creating a “light weight” architecture, the OpenDoc team has created a system to can more easily be ported to various platforms.

For those who want a full featured framework that deals with the platform specific issues which OpenDoc intentionally avoids addressing, Apple is developing OPF - the OpenDoc Parts Framework. OPF, which is based on the Bedrock application framework foundation, provides a complete cross-platform framework for the implementation of OpenDoc parts.

OpenDoc Architecture Overview

Documents

In the OpenDoc world, we make a shift from an application-centric world to a document-centric world. Along with this shift comes a change in the definition of the word document.

Before the advent of OpenDoc, to quote the OpenDoc Technical Summary, “ a document has a type which is used to choose the application which will help the user edit, view, and print the document.” With this starting point, we were quickly led to a world defined and dominated by monolithic applications like Microsoft Word and Aldus PageMaker.

In an OpenDoc world, our definition of document changes radically. A document now is a collection of parts.

Parts

As we said above, each and every document in the OpenDoc world is a collection of OpenDoc parts. A part can be defined as, once again quoting the OpenDoc Technical Summary, “ the boundaries in the document where one kind of content ends and another begins.” Therefore, each document is a collection of various pieces of content. It is this attribute of the OpenDoc architecture that makes compound documents natural.

OpenDoc parts can be embedded within any other part, and all parts are rooted directly or indirectly within the root part. This attribute of OpenDoc parts allows for the creation of extremely rich compound documents as you mix and match content.

Part Handlers

While OpenDoc parts contain the content within documents, they do not provide any way to display or manipulate this content. These tasks are left to the part handlers. Part handlers are responsible for displaying (both on the screen and in printed form) the part; editing the part; and management of persistent and runtime storage for the part.

Editors & Viewers - Part handlers are further broken down into two classes: editors and viewers. Editors and viewers are exactly what their names imply. A part editor provides the facilities to display, edit, and store a part, while a part viewer provides all of this functionality, except the ability to edit a part.

If you are implementing OpenDoc part handlers, for every editor that you create, you should also create a viewer. This will allow users who have purchased your part editor to create documents using those parts that can then be viewed by other users who have not purchased your part editor.

Of Parts, Part Handlers, and Objects

In getting a conceptual handle on parts and part handlers, it is often helpful to map them to the more familiar world of programmatic objects. Taken together parts and part handlers provide all of the features found in an object.

Parts provide the state information or field portion of an object, while part handlers provide the behaviors or methods of an object.

With this conceptual mapping in hand, it should be clear that one can implement within the OpenDoc application architecture any system that can be implemented using object oriented programming techniques.

The Document Shell & Containers

The document shell provides the system specific facilities that manage the interaction between the user and OpenDoc. The document shell is the container for all of the OpenDoc parts for a specific document.

It’s possible to retrofit an non-OpenDoc application, so that it can embed OpenDoc parts. Any application that has been so modified is called a container and acts in place of the document shell for the parts that it embeds. The process of turning an existing application into an OpenDoc container is called “containerizing”. Containerizing an application is discussed later in this article.

OpenDoc Foundations

OpenDoc delivers its functionality by building on top of a number of technologies from Apple and others.

Apple Events & the Open Scripting Architecture (OSA)

One of the key features of OpenDoc is customizability. If OpenDoc is to be customizable, OpenDoc parts must be scriptable. Scriptability is brought to OpenDoc through the use of AppleEvents and the Open Scripting Architecture. This means that every OpenDoc part is fully scriptable, recordable, and attachable. Therefore, it is possible to easily combine a collection of OpenDoc parts into a custom solution.

Bento™ Storage

Bento, a high performance storage system, which has been available on the Macintosh for sometime provides the foundation for the OpenDoc storage system. By adopting Bento, the OpenDoc team is providing authors of OpenDoc parts with a flexible and high performance storage system.

Drag and Drop Manager

The Drag and Drop Manager is being used in Apple’s implementation of OpenDoc to provide direct manipulation in the user interface of OpenDoc for Macintosh. With OpenDoc for Macintosh’s dependence on OSA and the Drag and Drop Manager, you could say that System 7.5 is OpenDoc ready and awaiting the release of OpenDoc for Macintosh later this year.

SOM

Cleanly managing the dynamic linking of objects in the OpenDoc world is handled by IBM’s SOM (System Object Model). The details of SOM and why it is important to OpenDoc is discussed by Jens in another article (“Learning to Love SOM”) in this issue.

As you can see from perusing this list of technologies, the OpenDoc team is building on some of the best technology available to create OpenDoc.

OpenDoc Myths

There are a number of myths circulating that do a disservice to developers trying to evaluate OpenDoc’s suitability to meet their needs. We’ll take this opportunity to explode these myths.

OpenDoc is a Compound Document Architecture

The first myth that you encounter - and one which is unfortunately reinforced by OpenDoc’s name - is that OpenDoc is solely a compound document architecture. As we said above, it is true that OpenDoc supports compound documents, but as a component application architecture, it is much more than a compound document architecture.

It is either OpenDoc or OLE

Another myth that confronts developers considering OpenDoc is that they must either choose between OpenDoc or Microsoft’s OLE (Object Linking and Embedding). This is simply not true. In fact, OpenDoc is a superset of OLE and fully interoperable with OLE. This means that if you write an OpenDoc part editor, it is also a first class OLE object. In fact, a number of highly experienced authors of OLE objects have commented that the easiest way to implement an OLE object is to write an OpenDoc part editor.

OpenDoc is incompatible with existing applications

Because of your ability to “ramp up” into OpenDoc - see our discussion of the steps to OpenDoc below - developers can immediately take advantage of OpenDoc with minimal work and more fully embrace the OpenDoc application architecture as resources and product requirements warrant.

OpenDoc is Mac-centric

This myth could not be further from the truth. As we discussed before, OpenDoc was designed from the ground-up as a cross-platform application architecture. The designers of OpenDoc looked at all of the personal computer and workstation operating systems during the OpenDoc design process. The result is a standard that is being fully implemented on a number of platforms.

OpenDoc is hard

Moving to any new software architecture involves some work, but in comparison to OLE 2.0, implementing OpenDoc parts is straight-forward. And when you consider that, by implementing an OpenDoc part you also implement an OLE object, the extra work involved is minimal.

The Steps To OpenDoc

When you decide to adopt OpenDoc, it is not an all or nothing choice. Rather, you can ease into OpenDoc and rearchitect your application at your own pace. The steps in adopting OpenDoc are (1) being a container, (2) being a part, and (3) being a collection of parts.

Being a container

The first step that you should take on the path to a full implementation of the OpenDoc application architecture is to turn your existing applications into containers. This will allow your application to embed OpenDoc parts. Therefore, by taking this simple step, you will have given your users compound documents and the ability to transparently add functionality to your base application.

The process of containerizing your application, and the tools that Apple is working on to ease the process, is described below in the section on containerizing your application.

Being a part

The next step along the OpenDoc application architecture road is to turn your application into an OpenDoc part editor. This will allow your application and its functionality to be embedded into other applications that are OpenDoc containers and within other OpenDoc part editors.

Being a collection of parts

The final step along the road to OpenDoc is to rearchitect your application as a collection of OpenDoc part editors. This will involve looking at your application and breaking it up into functional pieces.

For example, let’s examine how we turn a word processor into a collection of OpenDoc parts.

The first thing we would do is look at the end product - that is, a document - and decide on its various parts. In looking at a common document, I find the following pieces: table of contents, text, illustrations, tables, graphs, and an index. To turn our word processor into a collection of parts, we would create parts for each of these pieces. But wait, the illustrations and graphs pieces can be covered by parts dedicated to this purpose. We don’t have to write this functionality, because we can “inherit” it from other parts.

Next we look at the services provided by your average word processor and find that we have spell checking, grammar checking, and word counting. Now, we can either write these parts ourselves, bundle someone else’s parts with our word processors, or let our users get the spell checker, grammar checker, and word counter parts that they prefer.

After this process of “partifying” our word processor, we are ready to start implementing. If we decide to create the entire word processor in-house, we have to implement a table of contents part (which will use our text part), a text part, an index part (which will again use our text part), a spell checker part, a grammar checker part, and a word counter part.

Once we have these parts completed, we could look at how we can target them at specific markets. For example, we could create a word processor for the legal market where the various parts would have intelligence about legal documents built in and where we would add a time billing part to add in keeping track of work on clients’ cases.

Containerizing your Application

Revving existing code to support OpenDoc doesn’t have to mean going as far as turning it into a part handler. While this isn’t a huge task, it’s nontrivial, and may not be immediately feasible for large applications. You can, however, modify your application to allow OpenDoc parts to be embedded in its documents. This won’t allow your content to be embedded elsewhere (except via existing mechanisms such as Publish and Subscribe or Cut and Paste) but it does allow users to work with arbitrary content in your documents using their favorite part editors. You can think of this as using OpenDoc as a universal plug-in architecture.

To make this a simple task, Apple is working on a Container Application Library (CALib) that you can link into your application. Using CALib, revving your application to support embedding OpenDoc parts will be similar to adding QuickTime movie controller and PowerTalk mailer support - it’s like the former in that it requires slight modifications to your event loop and window-update routines to display the foreign content and handle user interaction with it, and like the latter in that it affects the way you store your documents to disk.

CALib is not yet ready for prime time, but you can find the current version of the interfaces on the CD.

Writing a Part Handler

What Is a Part Handler?

A part handler is a subclass of the SOM class ODPart, and every part that a user creates using this part handler is an instance of this subclass. To write a part handler, you need to create your subclass and fill in the methods declared by ODPart’s API.

The runtime model of a part is similar to that used in object-based frameworks: OpenDoc itself takes care of running the document process, and when a part (or something owned by one) needs to do something, OpenDoc sends it a message telling it to do so. If you prefer to think in procedural terms - and yes, you can write part handlers in regular C - your part editor consists of a set of callbacks that are called by OpenDoc, and each part is a data structure of your design that’s passed to these callbacks.

Some common messages sent to a part are: InitPartFromStorage (read the part’s data in from the document file); Draw (display your content in a facet on screen or on a printed page); and HandleEvent (respond to a mouse click, keystroke, etc.) There are about 60 methods in the ODPart API, but many of them are used only for advanced features like data linking, or embedding other parts. (By contrast, OLE 2 defines a server API with over 120 required calls.)

Using OpenDoc Services

Of course, no part is an island, and there’s more to OpenDoc than a set of callbacks. To work properly in an OpenDoc document, your part handler will need to interact with various OpenDoc objects and subsystems. (Parts don’t usually interact directly with other parts, although they can create extension objects that other parts can call.) What follows is an abbreviated bestiary of some of the most common OpenDoc classes that your part handler will have business dealings with.

ODStorageUnit

An OpenDoc document is a highly structured file. It consists of a group of storage units, which you can think of as persistent data blocks. Storage units aren’t explicitly nested, but they can reference each other in the same way that memory blocks can point to each other. This allows any kind of hierarchy or other network of connections.

Every part in a document gets its own storage unit: this is where it stores its content and any other data it needs to keep around. It accesses the data by sending messages to its storage unit object. Directly accessing a document using the File or Resource managers is verboten.

A storage unit consists of a group of named properties, each storing a different piece of data. One property always stores the part’s main content (for instance, a bit map for a paint part) and others can store additional data (such as the zoom level, extra color tables, or tool settings.)

Properties can store data in multiple formats, similarly to the Clipboard or a DragReference. Each property consists of a group of values, each of which is tagged with a data type. A value is a block of binary data that can be accessed as a stream. The API is much like the File Manager or the stdio library, except that you are also allowed to insert and delete bytes.

Storage units aren’t just for files, either - they’re also used for the Clipboard, for data linking, and for drag-and-drop. You use exactly the same API to read and write data to all four!

Your part interacts with its storage unit to read its contents when the document is opened (InitPartFromStorage) and to save changes when the document is saved (Externalize). It also uses storage units to access the Clipboard, to support drag and drop of content, and as the source or destination of a data link. Since the API is the same, most of your data I/O code can be shared between all these cases.

ODFrame

Unless a part is the root of a document, it owns only a piece of it, at the discretion of its parent part. For drawing and handling of user events to work, the document’s spatial real estate needs to be clearly divided up among its parts. Frames are the objects that take care of this.

An ODFrame represents a region of a document that’s owned by a part. Every part typically has at least one frame, since otherwise it wouldn’t be able to display anything or accept user input. Multiple frames of a single part might represent different views of the same content (such as a spreadsheet and a chart) or places to show successive pieces of content (like linked text boxes in a page layout program.) And of course, don’t forget that there can be several parts instantiated from your part handler in one document, each with its own content and each with one or more frames.

Frames are the middlemen of layout negotiation. An embedded part and its container can make deals about the real estate the embedded part’s frames are allowed to occupy. This lets a part grow or change shape (or even add new frames) as necessary, subject to the approval of its container.

Your part handler deals with frames when a new part instance is created in a document, and when the user creates new frames for the part to draw in. It also talks to its frames if it needs to change their size or shape. Container parts deal with embedded frames to manage their embedded parts.

ODFacet

While a frame represents a region where a part appears in a document, a facet represents where a frame appears in a window (or a printed page). When a frame becomes visible, a facet is created for it to display in, and when the frame is hidden or scrolled out of view the facet can be deleted. Facets deal with imaging-related issues like window coordinates and clipping.

The distinction between frames and facets can be confusing; keep in mind that a facet is a place where a frame is displayed. A frame is a persistent area of the document, and a facet is an ephemeral area of a window or printout.

Your part handler interacts with its facets when it draws their contents. The Draw method is passed a reference to a facet that needs updating. The part handler then queries the facet to get the graphics port, the clip region and the offset, and makes QuickDraw or QuickDraw GX calls to draw the contents of the frame that owns the facet. Container parts also create facets for their embedded frames and manage their clipping regions.

ODArbitrator and ODFocusSet

In OpenDoc, unlike OLE 2, many components of a document can be alive at once. To keep them from squabbling over who has access to shared resources like the menu bar and the keyboard, OpenDoc uses arbitration.

A part calls the arbitrator to request access to a focus. If the request is granted, the part gets exclusive access to the focus until another part requests access. The owner can then decide to give up the focus, or to refuse the request.

The keyboard focus and the menu focus grant access to keystrokes and menu commands: the part that currently owns that focus gets the event. The selection focus determines which frame has the special active border drawn around itself. The modal focus grants the ability to display a modal dialog: OpenDoc prevents mouse clicks in other windows from activating those windows, while the modal focus is in play.

The set of foci is extensible by developers. Any unique shared resource, such as a serial port or printer, could be defined as a focus by implementing a focus module.

Your part handler interacts with foci and the arbitrator when it activates itself, usually as a response to a click. If it has menus, it grabs the menu focus so it can display them. If it handles keyboard input, it grabs the keyboard focus. If it puts up a modal dialog or alert, it grabs the modal focus for the duration of the dialog’s appearance.

ODSession

The session is a central object that represents an OpenDoc process. Since it’s unique per process, it’s used to store global data. (Why not just store the global data as global variables? Because not all shared-library implementations support per-process globals: for instance, in Windows DLLs they’re global to the entire system. Abstracting all per-process globals into one object makes OpenDoc more platform-independent.)

Your part handler asks the session for references to global objects like the Clipboard, the arbitrator (used to find foci), the window state (used to create windows and palettes), and the menu bar.

This has been only a whirlwind tour of the most commonly-seen denizens of an OpenDoc document. If you want to read further, look for the OpenDoc architecture guide and API description on the CD. If you’d rather dive in, take a look at the sample part source code and try to follow along.

Building a Part Handler

The Development Process

The full process of implementing a part handler consists of:

• Declare a subclass of ODPart, fill in the implementation of each method, and compile and link the implementation files. This is the standard development process for SOM classes, and is described in the article Learning To Love SOM. The output is a shared library that you then copy into the OpenDoc folder in the Extensions folder.

• Build a stationery file by dropping your part handler library onto the OpenDoc launcher (a tiny application called OpenDoc in the OpenDoc folder.) This produces an OpenDoc stationery document containing a new instance of your part. In practice, users create parts by using such stationery rather than by interacting directly with your part editor library.

• Open your part in OpenDoc by double-clicking the stationery (if you want it to open into its own window as the root part of the document) or by dragging the stationery file into an OpenDoc part that can embed other parts, such as the ContainerPart.

• Chances are you’ll need to fix some bugs or add new features. Modify your source code, then recompile and relink. If your part’s storage format didn’t change, you can use the existing stationery pad and just open a new part from it. Otherwise, toss out the old stationery pad and build another one.

The Easy Way

There’s definitely a learning curve attached to the SOM build process, and as I mentioned above, many part methods can be filled in with standard boilerplate for simple editors. And anyway, all good programmers know that it’s easier to steal someone else’s working code and start hacking at it, than it is to write code from scratch.

In keeping with this philosophy, Eric Soldan and Tantek Çelik have written a utility called PartMaker that spits out part templates as CodeWarrior PowerPC projects complete with source code. All you do is tell PartMaker what you want your part to be named, and build the project it produces. Then you can start modifying the code to turn it into your own part. In Apple’s behavioral research facilities, macaque monkeys with no prior OpenDoc experience have been observed to create, build and run parts in under ten minutes using PartMaker.

PartMaker is extensible and we’ll be providing lots of part templates configured for different types of parts. The simplest one we have right now is called “•C++ OD Leaf Part”; it builds - what else? - a “Hello World” part. All it does is display a text message in a frame, and change the message when you click. However, all the infrastructure is there for supporting a general leaf (non-embedding) part, and once you replace the Draw and HandleMouseDown methods you’re on your way to your first killer part editor.

How To Build and Run It:

1. After installing OpenDoc and the development tools from the CD, find the document “•C++ OD Leaf Part” in the PartMaker folder and double-click it.

2. Fill in your desired classname and company name in the PartMaker dialog. Both names should be valid C/C++ names. The company name should identify you or your company; it’s combined with the classname to resolve potential name conflicts at runtime.

3. Press the “Create Part” button, and choose where to save the new part’s folder. Then quit PartMaker.

4. Open up the new folder and launch the CodeWarrior PowerPC project inside, whose name will look like “ClassName µ”. Take a look at the source if you like; the actual guts of the part class are in “CPClassName.cpp”.

5. Choose the Make command from the Project menu. This will compile the part sources and build a shared library with the same name as your class. (You can change the filename from the Preferences dialog if you want.)

6. Copy or move the library to the Editors folder in your Extensions folder to install it.

7. Drop the library onto the OpenDoc application in the OpenDoc folder. After some whirring and clanking, a stationery file will appear - this file contains a real live instance of your part. You can move this stationery file wherever you like.

8. Open any OpenDoc document or stationery pad that contains an embedding part such as ContainerPart.

9. Drop your stationery file into the ContainerPart and an instance of your part will appear inside it. Congratulations, you’ve just built and run an OpenDoc part handler!

We have two other PartMaker templates on this CD; they’re based on the official OpenDoc sample code. The first, SamplePart, is another “Hello World” part, but one with a lot more infrastructure underneath it. It supports more of the standard and recommended part human interface than the simple leaf part does. The second is SoundPart, a simple sound annotation.

 
AAPL
$111.16
Apple Inc.
+1.75
MSFT
$47.05
Microsoft Corpora
+1.31
GOOG
$510.51
Google Inc.
+5.62

MacTech Search:
Community Search:

Software Updates via MacUpdate

BBEdit 11.0.2 - Powerful text and HTML e...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
ExpanDrive 4.2.1 - Access cloud storage...
ExpanDrive builds cloud storage in every application, acts just like a USB drive plugged into your Mac. With ExpanDrive, you can securely access any remote file server directly from the Finder or... Read more
Adobe After Effects CC 2014 13.2 - Creat...
After Effects CC 2014 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous After Effects customer). After Effects CS6 is still available... Read more
Command-C 1.1.7 - Clipboard sharing tool...
Command-C is a revolutionary app which makes easy to share your clipboard between iOS and OS X using your local WiFi network, even if the app is not currently opened. Copy anything (text, pictures,... Read more
Tidy Up 4.0.2 - Find duplicate files and...
Tidy Up is a complete duplicate finder and disk-tidiness utility. With Tidy Up you can search for duplicate files and packages by the owner application, content, type, creator, extension, time... Read more
Typinator 6.3 - Speedy and reliable text...
Typinator turbo-charges your typing productivity. Type a little. Typinator does the rest. We've all faced projects that require repetitive typing tasks. With Typinator, you can store commonly used... Read more
GraphicConverter 9.5 - Graphics editor w...
GraphicConverter is an all-purpose image-editing program that can import 200 different graphic-based formats, edit the image, and export it to any of 80 available file formats. The high-end editing... Read more
Toast Titanium 12.0.1 - The ultimate med...
Toast Titanium goes way beyond the very basic burning in the Mac OS and iLife software, and sets the standard for burning CDs, DVDs, and now Blu-ray discs on the Mac. Create superior sounding audio... Read more
QuickBooks 2015 16.0.2.1422 R3 - Financi...
Save 20% on QuickBooks Pro for Mac today through this special discount link QuickBooks Pro 2013 helps you manage your business easily and efficiently. Organize your finances all in one place, track... Read more
Remotix 3.0.6 - Access all your computer...
Remotix is a fast and powerful application to easily access multiple Macs (and PCs) from your own Mac. Features: Complete Apple Screen Sharing support - including Mac OS X login, clipboard... Read more

Latest Forum Discussions

See All

Brothers in Arms 3: Sons of War Review
Brothers in Arms 3: Sons of War Review By Jennifer Allen on December 18th, 2014 Our Rating: :: FUN BUT PUSHYUniversal App - Designed for iPhone and iPad Brothers in Arms 3: Sons of War could be great fun, but its plethora of... | Read more »
The Snow is Falling on the French Countr...
The Snow is Falling on the French Countryside of Carcassonne’s Newest Update Posted by Jessica Fisher on December 18th, 2014 [ permalink ] < | Read more »
Creatures Such As We Review
Creatures Such As We Review By Jennifer Allen on December 18th, 2014 Our Rating: :: INTERESTING DISCUSSIONSUniversal App - Designed for iPhone and iPad Taking a more sedate approach to interactive fiction, Creatures Such As We... | Read more »
Give It Up! (Games)
Give It Up! 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: GIVE IT UP is a rather hard game where you have to assist this cheerful, singing Blob in jumping through 9 different tracks.So far... | Read more »
The Drive : Devil's Run (Games)
The Drive : Devil's Run 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: ON THE ROAD AGAIN! The Drive - Devil’s Run is classic point to point style racing game that pays homage to the classics... | Read more »
Procreate Pocket (Entertainment)
Procreate Pocket 1.01 Device: iOS iPhone Category: Entertainment Price: $2.99, Version: 1.01 (iTunes) Description: Create - anytime, anywhere. Made by the developers of the award-winning Procreate® for iPad®, Procreate Pocket™ allows... | Read more »
IRON FINGER - Mini Games Championship (...
IRON FINGER - Mini Games Championship 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Quick to play, easy to learn yet hard to master.. TAP, SWIPE & TILT your way through mini games that... | Read more »
Pentaction: Medieval (Games)
Pentaction: Medieval 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Pentaction: Medieval is a turn-based strategy board-game about chance and skill on the battlefield. Take control of your... | Read more »
Hipstify Review
Hipstify Review By Jennifer Allen on December 17th, 2014 Our Rating: :: COOL FILTERSUniversal App - Designed for iPhone and iPad Add filters, quotes, and fancy frames to your images, thanks to Hipstify.   | Read more »
Mighty Smighties Gets Evolve Cards and N...
Mighty Smighties Gets Evolve Cards and New Worlds Posted by Jessica Fisher on December 17th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »

Price Scanner via MacPrices.net

KMI MIDI K-Board Great Gift for Amateur &...
The K-Board is a MIDI Nano keyboard for music creation for iPad, Android, And computers; the easiest way to make music with iPads & Android tablets, and Mac, Windows, or Linux computers. Ultra-... Read more
Amazon offers 15-inch 2.2GHz Retina MacBook P...
 Amazon.com has the 15″ 2.2GHz Retina MacBook Pro on sale for $1699 including free shipping. Their price is $300 off MSRP. Stock is limited, so act now if you’re interested. Read more
Holiday sales continue: MacBook Pros for up t...
 B&H Photo has new MacBook Pros on sale for up to $300 off MSRP as part of their Holiday pricing. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1699... Read more
Google Search App For iOS Gets A Major Makeov...
Google has given iOS users an early Christmas present with a substantial update of it’s not-very-often-upgraded Google Search app. Google Search has been my go-to tool for Web searches since it was... Read more
ShopKeep Apple Pay And Chip Card Reader Avail...
ShopKeep, a cloud-based technology provider to more than 10,000 small business owners to manage retail shops and restaurants with iPads, has released its new Apple Pay and chip card reader. This... Read more
Holiday sale! 27-inch 5K iMac for $2299, save...
 B&H Photo has the 27″ 3.5GHz 5K iMac in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP, and it’s the lowest price available for... Read more
Holiday Sale! 3.7GHz Quad Core Mac Pro availa...
 B&H Photo has the 3.7GHz Quad Core Mac Pro on sale for $2599 including free shipping plus NY sales tax only. Their price is $400 off MSRP, and it’s the lowest price for this model from any... Read more
iPhone 6 Number 3 Canadian Google Search Of 2...
CTVNews.ca reports that Apple’s iPhone 6 was the third highest-trending Google Canada search topic of 2014, exceeded only by Robin Williams largely after his death by suicide in August, and the FIFA... Read more
New iPad mini 3 Counter-Top & Wall Mount...
newMacgadgets has announced new secure all-acrylic displays for the iPad mini 3 (also works fine with the mini 2, last year’s iPad mini With Retina Display, and the original iPad mini). The new iPad... Read more
Holiday sales continue, MacBook Airs for up t...
B&H Photo has 2014 MacBook Airs on sale for up to $120 off MSRP, for a limited time, for the Thanksgiving/Christmas Holiday shopping season. Shipping is free, and B&H charges NY sales tax... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.