TweetFollow Us on Twitter

Writing Cocoa Applications in Java

Volume Number: 19 (2003)
Issue Number: 12
Column Tag: Programming

Writing Cocoa Applications in Java

by Steve Klingsporn

Mac OS X is a great platform for software development. The combination of the Mac's elegant user experience, signature design and media tools, breakthroughs in mobile computing and UNIX-based underpinnings continues to lure developers away from other platforms. Apple has done a great deal of performance tuning in version 10.3 "Panther," optimizing the Carbon and Cocoa application frameworks while upgrading the underlying Mach kernel and BSD environment. Developers have a diverse choice of programming languages, from traditional assembly, C, and C++ to more dynamic languages like Objective-C, Java, JavaScript and Python. Apple ships Panther with "Xcode," its integrated development environment, which includes comprehensive documentation, sample code and the usual compilers and command-line tools. Xcode is an evolution of Project Builder, and adds neat features like code completion, fix and continue, predictive compilation, zero-link, distributed builds and a graphical debugger. Developers can choose between graphical tools like Xcode and Metrowerks CodeWarrior or more traditional command-line text editors and utilities. Apple rounds off its UNIX offerings with an X11 environment, which makes it extremely attractive to developers coming from Linux and FreeBSD camps. Apple is now the top vendor of high-volume UNIX systems, and Mac users can finally enjoy a truly remarkable, stable, and secure operating system.

Java has surpassed C and C++ as the world's most popular programming language, and is standard fare at most colleges and universities. Sun describes Java as "simple, object-oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, and dynamic." Developers compile Java source into platform-independent byte code that executes identically across host platforms in a virtual machine (VM) environment. Sun's "Hotspot" VM dynamically compiles this byte code into native object code at runtime, and its performance often equals or exceeds that of compiled C and C++. Apple realized this when moving its WebObjects application server to Java, as did Netscape when it profiled the performance of its Java ("Rhino") and C-based ("SeaMonkey") JavaScript engines. The performance problems that plagued Java in the early days have been addressed, and in most cases, the only noticeable tradeoffs are slightly longer application launch times and the memory overhead incurred by the VM. This environment offers an additional level of stability and security that C and C++ can't match, protecting applications from crashing and unauthorized resource access through the use of exceptions and a policy-based security model. Java has taken off in the server space due to many of these advantages, where stability and security are critical. Server-side Java development is pure joy on Mac OS X, as you can run any of the popular J2EE-compliant application servers, most popular relational databases, and you can easily deploy on Mac OS X Server or any other Enterprise-class UNIX servers while developing on your PowerBook and listening to iTunes.

Apple ships Java 2 Standard Edition (J2SE) versions 1.3.1 and 1.4.1 with Panther, and these releases are available to developers still using Jaguar via the Software Update service. Apple includes a number of notable improvements and innovations in its J2SE implementations, including the sharing of commonly used classes across VM instances, and using the Cocoa framework as the basis for its AWT and Java2D implementations. The net result is arguably the best and most tightly integrated implementation of Java 2 available on any platform. In addition to the standard tools from Sun, Apple includes a "Jar Bundler" utility that assists in generating double-clickable applications from JAR files, and "JavaBrowser," a quick and useful class browser that allows the browsing of Java package hierarchies and their associated class definitions, source code and documentation without switching back and forth between Xcode and multiple pages in a web browser. These two applications live in /Developer/Applications/Java Tools, and are installed by the Xcode installer. Figure 1 depicts JavaBrowser displaying the source code for the java.util.StringTokenizer platform class.


Figure 1: JavaBrowser displaying the source code to the StringTokenizer class.

Cocoa Java

Cocoa is the evolution of the object-oriented application frameworks developed in the early 90's at NeXT, and was instrumental in the transition to Mac OS X at Apple. Developers who are interested in writing new applications for the Mac will probably choose Cocoa over Carbon because of its modern, object-oriented nature and award-winning rapid user interface design tool, "Interface Builder." With Interface Builder, you visually construct your application's user interface, dragging, dropping, configuring and tying components to "outlets" and "actions" which map directly to properties and methods implemented in your source code. Interface Builder generates "NIB files" containing frozen objects, which are packaged in directories that correspond to the various human languages your application is localized into. Organizing NIB files this way together with localized program strings gives developers a simple and powerful mechanism for providing their applications in many different languages and markets simultaneously.

Cocoa is written in the Objective-C language, which consists of a small number of extensions to ANSI C that enable object-oriented programming and dynamic runtime features. Objective-C is a more elegant and concise language than C++, lacks many of its drawbacks and pitfalls, and has a unique syntax for defining classes, categories, protocols and message passing between objects. Despite the power and simplicity of this language, C++ won the language war in the mid 90's, and Java's popular syntax more closely resembles C++, while borrowing many of Objective-C's features. James Gosling, Java's mastermind, credits Objective-C for inspiring many of the language's dynamic features, and today uses his PowerBook for most of his research and development work. While Objective-C may be the language that Apple would like to see developers using, it acknowledges Java's popularity and utilizes the "Java Bridge" technology the WebObjects team developed to facilitate building fully native Cocoa applications in pure Java. While you can continue to develop platform-independent Java applications using "Swing" and AWT, only Cocoa offers a true Aqua user experience and access to platform-specific features that Mac users have come to expect. Cocoa Java is a very attractive option for new and existing developers, leveraging the best aspects of these technologies without requiring the additional learning curve of mastering an unfamiliar programming language. You can freely mix Objective-C and Java code in your applications, and can design your classes so Cocoa-dependent code is separate from more generic code, which can continue to run unmodified on other host platforms.

Creating Your Project

To create a new Cocoa Java project, launch Xcode (in /Developer/Applications), and select "New Project..." from the "File" menu. Select "Cocoa Java Application," click "Next," and tell Xcode the name and location of your new project. If you are planning on developing a document-based application utilizing the NSDocument class, you may want to select "Cocoa Java Document-based Application" instead.


Figure 2: Using Xcode to create a new Cocoa Java project.

Xcode will create a new project directory for you based on its template for a Cocoa Java application, and will put some placeholder files into this directory, including a "MainMenu.nib" file for editing in Interface Builder, links to the AppKit, Cocoa and Foundation frameworks, and a "main.m" Objective-C stub file that is called only to launch your application, and is actually optional. Figure 3 shows what a new Cocoa Java project window should look like. The name of your project, of course, will be different from the one used in this article. If you are using Project Builder on Jaguar, things will be arranged differently. A considerable number of articles have been written about Cocoa development in Project Builder.


Figure 3: A new Cocoa Java application project window.

At this point, you will begin to follow the usual iterative Cocoa development patterns. Much has been written in previous articles and tutorials about this process, which generally consists of using Interface Builder to design classes in the "Classes" tab of your NIB file window, specifying instances of these classes in the "Instances" tab by dragging or manually creating them, and drawing out the connections between them. You then either auto-generate or edit your source code files, implementing the various member variables and methods associated with the outlets and actions you define in the "Classes" tab. You should keep all of your program strings in a text file called "Localizable.strings," and use NSBundle.localizedString to retrieve them instead of hard-coding them in your source. You can generate different language bundles for other localizations containing this file and any NIB files that have localization-specific changes. "MainMenu.nib" is the default NIB file that Xcode generates from its Cocoa Java project template, and should be double-clicked to launch Interface Builder when you are ready to begin specifying the menus and windows for your application. You can break your application's user interface up into multiple NIB files to decrease your application's launch time and provide your localizers with files that are easier to manage and edit.

Differences From Objective-C

The obvious difference from programming in Objective-C is that you will be using Java to implement your source files. The Cocoa AppKit and Foundation Kit frameworks are implemented in the com.apple.cocoa.application and com.apple.cocoa.foundation packages. You should import these packages in full, or at least the classes from them you plan on using, in each of your source files that depends on Cocoa. You are simply using Cocoa for your user interface and platform integration instead of AWT or JFC ("Swing"). Everything else more or less remains familiar, and you can use any of the tried and true Java platform classes you like mixed in with your use of Cocoa. You can add the paths to your class, source and documentation files for your application to JavaBrowser if you wish, and conveniently browse them in conjunction with the Java and Cocoa platform classes. You can even use "Ant" to build portions or the entirety of your project, though this will require you to manually write a "build.xml" file and do a bit of extra work. You will find that most of the Cocoa sample code on the web and most of the mailing lists, books and other resources listed at the end of this article are written in Objective-C, so a rudimentary understanding of the language and its message passing syntax will prove useful. Converting between Objective-C and Java will become second-nature as soon as you get the hang of its syntax peculiarities, and you will begin to appreciate the conventions Apple took in converting the API to Java, often using familiar interfaces instead of protocols and the like. In most cases, there is no penalty (or "toll") for subclassing or calling back and forth between the two languages across the Java Bridge, and Apple's documentation describes cases in which you should pay special attention to performance or memory management issues.

One key difference between Objective-C and Java Cocoa is that Apple has not provided Java equivalents for many of the I/O, string manipulation and other such classes in the Foundation Kit, including NSFileHandle, NSThread, NSValue and NSScanner, expecting developers to instead use standard Java platform counterparts like java.io.File, java.lang.Thread, java.lang.Object and java.util.StringTokenizer. Use java.lang.String instead of NSString; NSAttributedString and other Cocoa classes that take strings accept them. Java's network and file I/O classes are not only familiar to seasoned Java developers, but often offer more elegant solutions than their Objective-C counterparts. Java's platform advantages really start to become self-evident when using features like reflection, serialization, and remote method invocation (RMI), not to mention libraries like JDBC, which enables a Cocoa developer to easily write a vendor-neutral relational database application with a native Cocoa user experience in an afternoon. Any of the countless Java packages and libraries available can be leveraged by your Cocoa Java applications, saving you time and allowing you to concentrate on implementing application-specific functionality. This truly powerful combination of technologies should not be overlooked by anyone considering using Objective-C for their next killer Cocoa app.

Mixing Java and Cocoa

For the purposes of this article, we will be examining some of the code from "Aquataxx," a Cocoa Java implementation of the classic arcade strategy game, "Ataxx," shown in Figure 4. Aquataxx is a comprehensive example of using Cocoa features like brushed metal windows, drawers, sheets, bouncing Dock icons, text editing, tab views, user defaults, localized strings, drag and drop, sound, animation and drawing in custom NSView subclasses. In addition, it sports a game engine with impressive AI, networked game play and messaging, a standalone network "roster server" for finding other online players, and some advanced threading techniques, all written in portable, platform-agnostic Java. The result is a portable implementation of Ataxx with a challenging computer player, a rich, themable Cocoa user experience, network play and chat, and more. Writing the same game in Objective-C would have taken longer than the two weeks it took to write Aquataxx.


Figure 4: Aquataxx, a Cocoa Java game used as an example in this article.

Listing 1 depicts using Cocoa and Java platform classes together to implement the action method that is invoked by the "About Aquataxx" item in the "Aquataxx" application menu. Note that the method is public and a regular java.lang.Object is used for the sender parameter. We splice the Java version from java.lang.System into the version NSTextField and display the game's about sheet.

Listing 1:

A simple Cocoa "action" method, linked from the NIB file in Interface Builder.

/**
      Shows the about sheet 
      @param sender the sender of the message
   **/
   public void showAboutSheet(Object sender)
{        
      /* Set the version string, if need be */
      NSTextField versionField =    
         (NSTextField)mAboutPanel.contentView().
         viewWithTag(1);
         
      String versionString = versionField.stringValue();
   if (versionString.indexOf("{0}") > -1)
   {
      StringBuffer buffy = new 
         StringBuffer(AtaxxApplication.APPLICATION_VERSION);
         buffy.append(" - Java ");
         buffy.append(System.getProperty("java.version"));
         versionString = MessageFormat.format(versionString,
            new Object[] { buffy.toString() });
         versionField.setStringValue(versionString);
   }
        
/* Show the sheet */
   NSApplication.sharedApplication().beginSheet(
      mAboutPanel, mGameWindow, this, null, null);
}

Memory Management and Thread Safety

In most cases, you will not have to explicitly worry about memory management in your Cocoa Java applications. The usual warnings regarding hanging onto references and what not still apply, and Apple has a document that is referenced at the end of this article that explains the exceptions to these general rules. In some cases, to get around complicated interactions between Cocoa and Java objects, you will need to wrap objects in an NSArray; in others, you may have to catch possible NSExceptions that can be thrown by Cocoa object constructors. For the most part, the tricky retain and release memory management conventions used in Objective-C can be avoided; another one of Java's advantages improves the Cocoa development experience!

Java developers are used to satisfying the needs of most modern applications, especially those that use network I/O, with multiple threads. Java encourages the use of multithreading, and Java threads (java.lang.Thread) on Mac OS X are implemented as native Mach threads, so they have excellent performance. One of the inherent pitfalls of multithreaded programming is thread safety, and many aspects of the Cocoa frameworks are not yet guaranteed to be thread safe, meaning you cannot safely call many aspects of Cocoa, including your user interface, from background threads such as one that blocks on incoming network I/O. Since network socket I/O blocks in J2SE 1.3.1, and holding up the main thread in which many aspects of Cocoa including your user interface run in can result in unacceptable performance, a mechanism is needed to enable background threads to tell the main thread to execute code that interacts with Cocoa. NSObject in Objective-C has a method, performSelectorInMainThread, but unfortunately this functionality is not available in Cocoa Java. To get around this, the most popular strategy is to subclass NSApplication and implement sendEvent to handle application-defined events that correspond to blocks of code that need to be called in the main thread. Code that is called from your sendEvent implementation is guaranteed run in the main thread. Failing to observe the fact that many aspects of Cocoa are not thread safe will result in unexpected, random crashes (not exceptions) that can be hard to reproduce and debug and appear to be in Cocoa's Objective-C code. These types of crash logs can be confusing to developers programming in pure Java, yet can often help in tracking down sections of code that should be run in the main thread. Listing 2 is the full source for AtaxxApplication, the custom NSApplication subclass used in Aquataxx to handle events posted by background threads. Listing 3 depicts an example of posting such an event. The full source for Aquataxx is referenced at the end of this article, and can be examined for further examples of using this technique to assure your application plays by proper threading rules.

Listing 2:

AtaxxApplication, an NSApplication subclass that handles application-defined events.

/* AtaxxApplication.java */

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

/**
   A NSApplication subclass to add the ability to respond to application-defined events.
 **/

public class AtaxxApplication
   extends NSApplication
{
   /** Application version string **/
   public static final String APPLICATION_VERSION = "1.8";
    
/* Application-defined event types */
   protected static final short NEW_MATCH_EVENT = 0;
   protected static final short SCROLL_CONVERSATION_EVENT = 1;
   protected static final short CONFIRM_CONNECTION_EVENT = 2;
   protected static final short UPDATE_ROSTER_EVENT = 3;
   protected static final short INCOMING_DROPPED_EVENT = 4;
    
/**
   Overridden to respond to custom events.
   @param event the event being processed.
 **/
   public void sendEvent(NSEvent event)
   {
      /* Only worry about application-defined events */
      if (event.type() == NSEvent.ApplicationDefined)
      {
         switch (event.subtype())
         {                
   /* Create a new match */
            case NEW_MATCH_EVENT:
            {
               AtaxxController.sharedController().
                  startNewMatch(event.data1(),
                     event.data2());
               break;
            }
                
   /* Scroll the conversation view */
            case SCROLL_CONVERSATION_EVENT:
            {
               AtaxxController.sharedController().
                  scrollConversationView();
               break;
            }
                    
   /* Confirm a connection request */
            case CONFIRM_CONNECTION_EVENT:
            {
               AtaxxController.sharedController().
                  confirmConnectionRequest();
               break;
            }
                    
   /* Update roster data source */
            case UPDATE_ROSTER_EVENT:
            {
               AtaxxController.sharedController().
                  updateRosterDataSource();
               break;
            }
                    
   /* Close the connection request sheet */
            case INCOMING_DROPPED_EVENT:
            {
               AtaxxController.sharedController().
                  closeAnySheet(null);
               break;
            }
         }
      }
      else
      {
         super.sendEvent(event);
      }
   }
}

Listing 3:

A wrapper method that posts an application-defined event.
      
      /**
         Posts an application-defined event to the current application.
         @param code the event code
         @param data1 the first parameter
         @param data2 the second parameter
         @param front post to the front of the queue?
      **/
      public void postApplicationDefinedEvent(short code,
                                                      int data1,
                                                      int data2,
                                                      boolean front)
      {
         NSEvent event = NSEvent.otherEvent(NSEvent.ApplicationDefined,
            new NSPoint(0, 0), 0, System.currentTimeMillis() / 1000.0, 0,
            null, code, data1, data2);
         NSApplication.sharedApplication().postEvent(event, front);
      }

Implementing Custom Views

One of the more rewarding aspects of Cocoa programming is implementing your own NSView subclasses. NSView is the base class in the Cocoa user interface class hierarchy, and all of the user interface components you see and interact with inevitably inherit from it. If one of Apple's standard views does not suit the type of data or interaction you are trying to represent, as is the case with the game board and player score views in Aquataxx, you should implement a custom NSView subclass. You subclass NSView in the "Classes" tab of your NIB file window in Interface Builder, and create a corresponding Java source file just as you would if you were using Objective-C. Listing 4 is the complete source code for AtaxxScoreView, a custom view that draws both players' names and scores and highlights the active player with an etched appearance that looks similar to iTunes. For a more comprehensive and exciting example of a custom view that handles events and uses optimized drawing and drag and drop, take a look at the source for AtaxxView, which draws the game board and is found in the full source code distribution. Cocoa user interface programming is a lot more fun, intuitive, and rewarding than using "Swing!"

Listing 4:

The complete source for AtaxxScoreView, a custom NSView subclass.
/* AtaxxScoreView.java */
import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;
/**
   A custom NSView subclass that displays an etched
   metallic scoreboard for two players, and highlights
   the player whose turn it is.
 **/
public class AtaxxScoreView
    extends NSView
{
   /* The colors for drawing the scoreboard */
   public static final NSColor FOREGROUND_COLOR =
      NSColor.colorWithCalibratedRGB(.20f, .20f, .20f, 1.0f);
   public static final NSColor BACKGROUND_COLOR = NSColor.whiteColor();
   public static final NSColor FOREGROUND_UP_COLOR = NSColor.blackColor();
   public static final NSColor BACKGROUND_UP_COLOR = NSColor.grayColor();
/* The (four) attributed score strings ((back, front) * 2) */
   private NSMutableAttributedString mScoreStrings[] = null;
    
/**
   Constructor
   @param frame the frame rectangle
 **/
   public AtaxxScoreView(NSRect frame)
   {
      super(frame);
      mScoreStrings = new NSMutableAttributedString[4];
   }
/**
   Tells the window server that we are not opaque (we are transparent).
   @returns false, as we are transparent.
 **/
   public boolean isOpaque()
   {
      return false;
   }
    
/**
   Draws the view
   @param rect the update rectangle
 **/
   public void drawRect(NSRect rect)
   {
      if (mScoreStrings != null)
      {
         NSMutableRect stencil = new NSMutableRect(bounds());
         stencil.insetRect(0.5f, 1.0f);
         stencil.setOrigin(new NSPoint(1.0f, 0.0f));
         NSGraphics.drawAttributedString(mScoreStrings[0], stencil);
         NSGraphics.drawAttributedString(mScoreStrings[2], stencil);
         stencil.setOrigin(new NSPoint(0.0f, 1.0f));
         NSGraphics.drawAttributedString(mScoreStrings[1], stencil);
         NSGraphics.drawAttributedString(mScoreStrings[3], stencil);
      }
   }
/**
   Creates the 4 attributed score strings, based on
   the current score strings and player that is up.
   @param player1 the string for the first player
   @param player2 the string for the second player
   @param up the player that is up (hilighted)
   (0 = none, 1 = player 1, 2 = player 2)
 **/
   public synchronized void update(String player1,
                                          String player2,
                                          int up)
   {
      /* For convenience in looping through the strings */
      String strings[] = { player1, player1, player2, player2 };
      NSMutableAttributedString newStrings[] =
         new NSMutableAttributedString[4];
                
      for (int i = 0; i < 4; i += 2)
      {
         /* Create the pair of attributed strings (foreground and background) */
         newStrings[i] = 
            new NSMutableAttributedString(strings[i]);
         newStrings[i + 1] = 
            new NSMutableAttributedString(strings[i + 1]);
   /* Create a range for the string pair */
         NSRange range = new NSRange(0, strings[i].length());
            
   /* Set the text alignment */
         NSMutableParagraphStyle paragraphStyle =
            new NSMutableParagraphStyle();
         paragraphStyle.setAlignment((i < 2) ? 
            NSText.LeftTextAlignment :
            NSText.RightTextAlignment);
         newStrings[i].addAttributeInRange(
            NSAttributedString.ParagraphStyleAttributeName,
            paragraphStyle, range);
         newStrings[i + 1].addAttributeInRange(
            NSAttributedString.ParagraphStyleAttributeName,
            paragraphStyle, range);
                
   /* Set the font to the system font, size 10 (localization?) */
         NSFont font = NSFont.systemFontOfSize(10);
         newStrings[i].addAttributeInRange(
            NSAttributedString.FontAttributeName,
            font, range);
         newStrings[i + 1].addAttributeInRange(
            NSAttributedString.FontAttributeName,
            font, range);
            
   /* Set the foreground and background colors */
         NSColor foregroundColor = FOREGROUND_COLOR;
         NSColor backgroundColor = BACKGROUND_COLOR;
         if ((i < 2 && up == 1) ||
            (i > 1 && up == 2))
         {
            foregroundColor = FOREGROUND_UP_COLOR;
            backgroundColor = BACKGROUND_UP_COLOR;
         }
         newStrings[i].addAttributeInRange(
            NSAttributedString.ForegroundColorAttributeName,
            backgroundColor, range);
         newStrings[i + 1].addAttributeInRange(
            NSAttributedString.ForegroundColorAttributeName,
            foregroundColor, range);
            
   /* Fix up the attributes, whatever that does */
         newStrings[i].fixAttributesInRange(range);
         newStrings[i + 1].fixAttributesInRange(range);
            
   /* Set the actual attributed score strings */
         mScoreStrings[i] = newStrings[i];
         mScoreStrings[i + 1] = newStrings[i + 1];
      }
      /* Redraw the view! */
      display();
   }
}

Conclusion

Java is an excellent choice for developing Cocoa applications. If you are a Java programmer, are new to Cocoa, or are not interested in learning Objective-C, you should give Cocoa Java a try. The popularity of the language and the sheer quantity of third-party libraries and tools provide Java programmers with an impressive array of pre-engineered solutions over those available in Objective-C. Apple continues to provide Java interfaces to the new features it adds to Cocoa. It's time for developers to take better advantage of this technology and provide Apple with the feedback they need to make Cocoa Java even better. The end result is more great applications for Mac OS X.

Resources

The following resources will help you get started in learning about Cocoa Java programming. Sun has a general Java language tutorial, Apple has a Cocoa Java tutorial, and there are several sample applications installed with Xcode that will prove to be good references. The Aquataxx game distribution and full source code referenced in this article is available, and Apple and The Omni Group have good Cocoa development mailing lists that can be browsed and searched at http://cocoa.mamasam.com. If you have questions that you cannot find the answers to, or would like to discuss Cocoa Java programming in general, you can contact the author at steve@buzzlabs.com.


Steve Klingsporn is an independent software developer living in Chicago with his cat, Sonya. He has an 11 year history of working at companies such as Apple, Netscape, and Sun. He is available for independent Mac OS X, Java and web development, and can be reached at steve@buzzlabs.com.

 
AAPL
$116.47
Apple Inc.
+0.00
MSFT
$47.98
Microsoft Corpora
+0.00
GOOG
$537.50
Google Inc.
+0.00

MacTech Search:
Community Search:

Software Updates via MacUpdate

Cobook 3.0.7 - Intelligent address book....
Cobook Contacts is an intuitive, engaging address book. Solve the problem of contact management with Cobook Contacts and its simple interface and powerful syncing and integration possibilities.... Read more
StatsBar 1.9 - Monitor system processes...
StatsBar gives you a comprehensive and detailed analysis of the following areas of your Mac: CPU usage Memory usage Disk usage Network and bandwidth usage Battery power and health (MacBooks only)... Read more
Cyberduck 4.6 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Evernote 6.0.1 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
calibre 2.11 - Complete e-library manage...
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
Herald 5.0.1 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
Firetask 3.7 - Innovative task managemen...
Firetask uniquely combines the advantages of classical priority-and-due-date-based task management with GTD. Stay focused and on top of your commitments - Firetask's "Today" view shows all relevant... Read more
TechTool Pro 7.0.6 - Hard drive and syst...
TechTool Pro is now 7, and this is the most advanced version of the acclaimed Macintosh troubleshooting utility created in its 20-year history. Micromat has redeveloped TechTool Pro 7 to be fully 64... Read more
PhotoDesk 3.0.1 - Instagram client for p...
PhotoDesk lets you view, like, comment, and download Instagram pictures/videos! (NO Uploads! / Image Posting! Instagram forbids that! AND you *need* an *existing* Instagram account). But you can do... Read more

Latest Forum Discussions

See All

Space Expedition Review
Space Expedition Review By Jordan Minor on November 24th, 2014 Our Rating: :: ONE SMALL STEPUniversal App - Designed for iPhone and iPad The only thing boring about Space Expedition’s lonely journey is its title.   | Read more »
Ubisoft Gives Everyone Two New Ways to E...
Ubisoft Gives Everyone Two New Ways to Earn In-Game Stuff for Far Cry 4 Posted by Jessica Fisher on November 21st, 2014 [ permalink ] | Read more »
Golfinity – Tips, Tricks, Strategies, an...
Dig this: Would you like to know what we thought of being an infinite golfer? Check out our Golfinity review! Golfinity offers unlimited ways to test your skills at golf. Here are a few ways to make sure your score doesn’t get too high and your... | Read more »
Dark Hearts, The Sequel to Haunting Meli...
Dark Hearts, The Sequel to Haunting Melissa, is Available Now Posted by Jessica Fisher on November 21st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Meowza! Toyze Brings Talking Tom to Life...
Meowza! | Read more »
Square Enix Announces New Tactical RPG f...
Square Enix Announces New Tactical RPG for Mobile, Heavenstrike Rivals. Posted by Jessica Fisher on November 21st, 2014 [ permalink ] With their epic stories and gorgeous graphics, | Read more »
Quest for Revenge (Games)
Quest for Revenge 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: The great Kingdom of the west has fallen. The gods ignore the prayers of the desperate. A dark warlord has extinguished... | Read more »
Threadz is a New Writing Adventure for Y...
Threadz is a New Writing Adventure for You and Your Friends Posted by Jessica Fisher on November 21st, 2014 [ permalink ] In the tradition of round-robin storytelling, | Read more »
SteelSeries Stratus XL Hardware Review
Made by: SteelSeries Price: $59.99 Hardware/iOS Integration Rating: 4 out of 5 stars Usability Rating: 4.5 out of 5 stars Reuse Value Rating: 4.25 out of 5 stars Build Quality Rating: 4.5 out of 5 stars Overall Rating: 4.31 out of 5 stars | Read more »
ACDSee (Photography)
ACDSee 1.0.0 Device: iOS iPhone Category: Photography Price: $1.99, Version: 1.0.0 (iTunes) Description: Capture, perfect, and share your photos with ACDSee. The ACDSee iPhone app combines an innovative camera, a powerful photo... | Read more »

Price Scanner via MacPrices.net

CEA Study Finds More People Recycling Electro...
A new study by the Consumer Electronics Association (CEA) finds that electronics recycling receives the continued and growing support of consumers. According to the CEA,s Recycling and Reuse Study,... Read more
15″ 2.2GHz Retina MacBook Pro on sale for $17...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale today for $1749. Shipping is free, and B&H charges NY sales tax only. B&H will also include free copies of Parallels Desktop... Read more
27-inch 3.5GHz 5K iMac in stock today and on...
 B&H Photo has the new 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... Read more
21-inch 1.4GHz iMac on sale for $979, save $1...
B&H Photo has the new 21″ 1.4GHz iMac on sale for $979.99 including free shipping plus NY sales tax only. Their price is $120 off MSRP. B&H will also include free copies of Parallels Desktop... Read more
13-inch 1.4GHz/256GB MacBook Air on sale for...
B&H Photo has lowered their price on the 13″ 1.4GHz/256GB MacBook Air to $1059.99 including free shipping plus NY sales tax only. Their price is $140 off MSRP, and it’s the lowest price for this... Read more
Save up to $400 with Apple refurbished 2014 1...
The Apple Store has restocked Apple Certified Refurbished 2014 15″ Retina MacBook Pros for up to $400 off the cost of new models. An Apple one-year warranty is included with each model, and shipping... Read more
New 13-inch 1.4GHz MacBook Air on sale for $8...
 Adorama has the 2014 13″ 1.4GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. B&H Photo has the 13″ 1.4GHz/128GB MacBook... Read more
Apple Expected to Reverse Nine-Month Tablet S...
Apple and Samsung combined accounted for 62 percent of the nearly 36 million branded tablets shipped in 3Q 2014, according to early vendor shipment share estimates from market intelligence firm ABI... Read more
Stratos: 30 Percent of US Smartphone Owners t...
Stratos, Inc., creator of the Bluetooth Connected Card Platform, has announced results from its 2014 Holiday Mobile Payments Survey. The consumer survey found that nearly one out of three (30 percent... Read more
2014 1.4GHz Mac mini on sale for $449, save $...
 B&H Photo has lowered their price on the new 1.4GHz Mac mini to $449.99 including free shipping plus NY tax only. Their price is $50 off MSRP, and it’s the lowest price available for this new... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC)- Retail S...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Store Leader Program - College Gradu...
Job Description: Job Summary As an Apple Store Leader Program agent, you can continue your education as you major in the art of leadership at the Apple Store. You'll 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
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.