TweetFollow Us on Twitter

The Road to Code: Leopard Detour

Volume Number: 23 (2007)
Issue Number: 11
Column Tag: Programming

The Road to Code: Leopard Detour

What's new for developers in Leopard

by Dave Dribin

Short Detour

In this month's The Road to Code, we're going to be taking a short detour from the usual programming road. Instead of talking about Objective-C and object-oriented programming, I'm going to talk about Leopard. You may have heard about Apple's next generation operating system, Mac OS X 10.5, a.k.a Leopard. While much of the marketing buzz revolves around the new features available to the end-users, such as Time Machine, Spaces, and Cover Flow in The Finder, many improvements are in store for the developer, too. Since I still have not used Leopard extensively for development and there are far more changes than I can discuss in a single article, I'll be picking out some of the highlights that I've already encountered or am looking forward to using. While this article will be most useful for existing developers, you'll still learn a lot about developing for Mac OS X, even if you're not an old hat.

Development Tools

There are many improvements in the existing development tools, but there are also a couple of interesting new ones.

Xcode

Leopard comes with a new version of Xcode, Apple's integrated development environment (IDE), now up to Version 3.0. The first change you'll notice is that the main text editor has received an overhaul. The most immediate difference you'll encounter is that errors and warnings are now displayed inline as bubbles of text, as in Figure 1. While this is better than constantly keeping the build window open, or hovering over errors in the gutter to see the full message, it can also be a bit distracting. The bubbles shift lines of text down to fit themselves on screen, and I find this makes it a bit hard to see context around the error in question. For now, I'm keeping this option enabled, as it may grow on me over time.


Figure 1: Xcode error bubbles

The debugger has been better integrated, so that debugging doesn't require as much mental context switching. One of the best features is that the debugger can be invoked any time you run the application. There are no longer separate Build and Run and Build and Debug options. This is wonderful because often you are testing a program, only to realize that you'd like to set a breakpoint when something goes wrong. In the previous versions, you'd have to re-start the program under the debugger. Now, you can just set the breakpoint, and the debugger will automatically attach to your running application. In addition, there's no longer a separate debugger window, which helps keep you focused on the problem at hand.

Xcode 3.0 also provides the ability to refactor Objective-C code. Refactoring allows you to make your code more readable or simplifies its structure without changing the behavior. Other IDEs have had refactoring for a few years now, and it is a feature I am really excited about. Some examples of refactoring provided by Xcode are renaming variable names (including instance variables), renaming classes, extracting a block of code into a method, and the ability to move methods up and down in the inheritance hierarchy. While some of these can be done with search and replace, refactoring, in addition to being easier, is usually more accurate since it is not purely text based.

The long laundry list of changes does not stop there. Here's a taste of more new features:

Code folding and code focusing using a focus ribbon.

Code completion has been simplified with inline code completion.

Project snapshots allow you to experiment freely and revert code changes, if necessary. While I don't see this replacing a full-blown source code management (SCM) system, it is still nice to have.

A better Build Settings editor, including the ability to set architecture-specific settings.

The Research Assistant provides easy access to reference documentation, without taking your focus away from the code.

Adds the ability to have versioned Core Data models. This helps data migration as your model changes over time.

GUI access to SCM repositories.

For details, see the "Xcode 3.0 Feature Overview" document.

Interface Builder

Interface Builder also reaches Version 3.0 with significant updates. Interface Builder (IB) has a long history, going all the way back to NeXTSTEP (the .nib extension is short for NeXT Interface Builder), and was ripe for an update. The user interface has been completely updated for 3.0. Separate palettes for GUI controls have been replaced with the concept of a Library. All controls are now shown in a single list, as in Figure 2. While the Library still groups similar controls, you can also search for controls by name. The list dynamically updates to show only the matching controls.


Figure 2: Interface Builder Library window

IB also adds support for some new controls, but the one I am currently most excited about is support for NSToolbar. Toolbars have previously needed to be setup programmatically, which can be a bit of a chore. Now, you can add a toolbar to a window, add items to a toolbar, and hookup their actions all in IB.

The Inspector Window has been improved to support multiple selection. This a is big time saver, since you can now set properties of multiple controls all at once, rather than selecting each one individually. The best part, I think, is that you can select any set of controls, and only the common properties are shown.

My favorite update, though, is the ability for IB to automatically synchronize outlets and actions to header files. Gone are the days where you drag and drop changed header files from Xcode to IB to synchronize them. This single update alone will probably save you hours of frustration.

For a full list of changes, see "Interface Builder 3.0 Release Notes," but here's a quick list of other exciting changes:

Support for Core Animation.

Support for Tree Controller and Dictionary Controller.

Real-time animation to visualize springs and struts.

Interface Builder Plug-in model to replace IBPalette.

DTrace and Instruments

DTrace is a fantastic performance diagnostic and system tracing tool, originally developed by Sun Microsystems for their Solaris operating system. Sun released it as Open Source, and Apple has ported it to Mac OS X for Leopard. DTrace is a command line application that can be used not only to monitor system performance, but also as a debugging tool. For example, you can print out arguments of functions when they are called with very little overhead, and without recompiling. DTrace is extremely flexible and even has it's own scripting language called D, so you can use to write custom tracing scripts. And DTrace isn't just for user applications. You can use DTrace on the kernel and your own kernel extensions, too.

But the goodness doesn't stop there. Instruments is a new GUI performance monitoring tool, reminiscent of Garage Band, but for developers. You can add different "instruments" such as memory usage, CPU load, and object allocation, and you can see these measurements change over time. Under the hood, Instruments uses DTrace and it's essentially just a pretty face on top of libdtrace, the programmatic API for DTrace. This also means you can customize Instruments by writing your own instruments using D scripts.

I have not used DTrace or Instruments extensively but I am willing to bet that they will find a permanent home in my tool belt, along side Apple's already fantastic list of performance tools, such as Shark.

Objective C 2.0

The native language for Mac OS X applications, Objective-C, also gets a new major revision, giving us Objective-C 2.0. In Objective-C 2.0, we'll see fast enumeration, garbage collection, simplified property accessors, and enhancements to protocols.

Fast enumeration

Fast enumeration is combination of syntactic sugar and a speed increase. The old school way of looping through all objects of an NSArray is using an NSEnumerator, as follows:

   NSArray * colors = [NSArray arrayWithObjects:
      @"red", @"green", @"blue", nil];
   NSEnumerator * e = [colors objectEnumerator];
   NSString * color;
   while (color = [e nextObject])
   {
      NSLog(@"Color: %@", color);
   }

The new way to do this in Objective-C 2.0 is to use a special for loop syntax:

   for (NSString * color in colors)
   {
      NSLog(@"Color: %@", color);
   }

Not only is this easier to read, but it is apparently much more efficient than good ol' NSEnumerator. You can even add fast enumeration to your custom classes if you implement the NSFastEnumeration protocol.

Garbage Collection

One of the trickiest aspects of programming in Objective-C is dealing with dynamic memory management. Although reference counting is an improvement over malloc/free in C and new/delete in C++, it is still cumbersome and error prone. With Objective-C 2.0 comes garbage collection (GC) and the promise of making dynamic memory management painless. At a high level, this means you no longer have to send retain and release messages to objects to update their reference count. It also means you do not have to implement dealloc to free your instance variables. The garbage collector will find unused objects, affectionately known as garbage, and free them for you. It also simplifies your accessor methods. For example, instead of implementing setWidget: as follows:

- (void) setWidget: (Widget *) widget
{
   if (_widget != widget)
   {
      [_widget release];
      _widget = [widget retain];
   }
}

You need to simply do an assignment:

- (void) setWidget: (Widget *) widget
{
   _widget = widget;
}

The garbage collector also handles retain cycles properly, so you no longer have to deal with those specially. This is common in parent/child relationships and using delegates.

There is quite a bit more detail to garbage collection, especially if you are converting an existing code base, but this gives you a taste of what is available. It's also worth noting that Xcode 3.0 is itself a garbage collected application. I think this is a good sign for Apple to eat it's own dog food and it gives me a warm fuzzy that GC really is the way forward for new, Leopard-only applications. I think it will also quell the gut instinct of many who believe that GC impacts performance too much. As I usually say to people who worry about performance: profile it before blaming something. I'm sure we'll see more on this topic as Leopard gets thrown through the ringer in the months to come. Overall, I'm really excited to see get my hands dirty with GC, and I think it will make the learning curve for newcomers to Objective-C a little less steep. Oh, and in case you're wondering how all of your existing applications will work, garbage collection is disabled by default, so no worries.

Properties

Continuing the trend of making the programmer's life simpler is the introduction of properties. The concept of properties is not new to Objective-C and is the backbone of Key Value Coding (KVC), Key Value Observing (KVO), and Cocoa Bindings. After writing even a small amount of Objective-C code, you will find yourself writing a lot of boilerplate code for KVC-compliant getter and setter methods, affectionately know as accessors. As I showed above, implementing accessors has been simplified with garbage collection. Nevertheless, it's still a lot of brainless code to write. You have to implement two methods for each property, and if you can't use garbage collection in your application, it's even more brainless code. Objective-C 2.0 now has special syntax to work with properties.

New keywords are provided to simplify the declaration and implementation of properties. First, the declaration:

@interface Person : NSObject
{
   NSString * _name;
}
@property(copy, readwrite) NSString * name;
@end

The @property line is similar to declaring name and setName: methods. It states that there is a property named name of type NSString *. The attributes given in the parenthesis customize the behavior of the property. In this case, copy means perform a copy in the setter, and readwrite means declare a getter and setter. A property can be readonly if there should be no setter method. There are other property declarations, too, so please see "The Objective-C 2.0 Programming Language" document for details.

On the implementation side, there is a new keyword to generate the method implementations for you:

@implementation Person
@synthesize name = _name;
@end

The @synthesize keyword implements the methods for property named name using the instance variable _name. Again, there are different ways to customize the property implementation so see the official manual for details.

The end result of using the property keywords is a lot less boilerplate code. But wait, there's more! Objective-C also provides a new dot syntax to simplify property access. Thus, instead of invoking the accessors methods as follows:

   Person * person = ...;
   NSLog(@"Name: %@", [person name]);
   [person setName: @"Steve Jobs"];
You can use the dot syntax:
   Person * person = ...;
   NSLog(@"Name: %@", person.name);
   person.name = @"Steve Jobs";

Protocols

The last feature of Objective-C 2.0 I'm going to introduce is an enhancement to formal protocols. Protocols define a set a methods that implementing classes must implement. Now methods can be defined as optional using the new @optional keyword:

@protocol MyProtocol
- (void) requiredMethod;
@optional
- (void) anOptionalMethod;
@end

Since optional methods are often seen in informal protocols, such as delegates, I think this feature will get used a lot. The benefit to using a protocol with optional methods over an informal protocol as that it makes your code more explicit and readable. It also improves the runtime metadata about an implementing class. For example, at runtime you can check to see if an object conforms to a formal protocol using conformsToProtocol:, but not an informal one.

Objective-C Runtime

The features listed above are for the Objective-C language syntax, but the runtime underpinnings also get an update. Mostly, this is transparent, but if you do any low-level hacking, you'll want to read up on the new runtime API. For example, class posing has been deprecated, so you'll need to find another way to accomplish what you want.

Much of the updates are for the new 64-bit implementation of the runtime. Because they didn't have to worry about keeping backward compatibility, some of the changes could be more extensive. Some of the improvements are better performance, support for non-fragile instance variables, and zero-cost C++ compatible exceptions. Be aware, though, that some features that are only deprecated in the 32-bit implementation are removed completely from the 64-bit implementation, such as class posing. See "Objective-C Runtime Release Notes for Mac OS X v10.5" for full details.

New and Improved APIs

The tools and language are not the only area to see drastic improvements. There are new and improved APIs to go along with those changes.

Core Animation

Core Animation is one of those revolutionary APIs that will probably change the way nearly all Mac OS X applications look and behave. Core Animation takes the power of the graphics card and unleashes it to the masses. Typically, you would have to really dig deep into OpenGL to fully utilize this power, but Core Animation makes it much easier by providing an API for fluid animation, 2D rendering, and 3D projections.

Core Animation itself is a lower-level API, but the Cocoa Application framework provides direct support for it. At the simplest level, some properties of an NSView and NSWindow are now animatable. This means that the new value does not get set immediately, but takes place over time. For example, if you set the frame of a view like this, the frame gets updated right away:

   [aView setFrame: newFrame];

If, instead, you use the animator proxy to set the frame, the frame will animate to the new value over time:

   [[aView animator] setFrame: newFrame];

Besides the frame, other animatable properties include the alpha value, rotation, and background Core Image filters.

If you want to fully utilize the power of Core Animation, you'll need to dig deeper into the lower-level API and work with layers. Layers are similar to views, in that they contain drawable content at a specific geometry, but they are much more lightweight. For example, it's possible to have hundreds of layers being rendered at once. Layers can be transformed, rotated, and zipped around using animations. Unfortunately, this is too large of a large topic to provide many details here. I suggest you read the "Core Animation Programming Guide" and look at the sample code for more information.

Cocoa Application Framework

The Cocoa Application Framework, affectionately known as AppKit gets a nice update in Leopard. AppKit is now 64-bit capable, meaning you can write 64-bit GUI applications to work with large amounts of data. In previous versions of Mac OS X, only Unix command line applications could be 64-bit. The nice thing is that there are not separate 32-bit and 64-bit versions of Leopard. 32- and 64-bit applications can be run side-by-side on the same machine, and you can even include both 32- and 64-bit versions of your binary in the same application bundle. Thus, you can ship a single binary to all your customers and not worry about what kind of machine they have.

There are quite a few new views and controls, too. Some of the standouts include:

NSCollectionView to provide an animatable list of views, like the pictures in iPhoto. The Library in Interface Builder is a nice example of NSCollectionView.

NSGradient, a class to easily create and display color gradients.

Native support for Heads Up Display (HUD) style windows. This is the dark gray, transparent window seen in many of the iLife applications, and it's available in Interface Builder.

Better Cocoa Bindings support with improvements to NSTreeController and NSArrayController and the addition of NSDictionaryController.

NSRuleEditor view to configure "rules" similar to Mail.

NSPredicateEditor view to create complex predicate expressions used in queries.

See the "Mac OS X v10.5 Developer Release Notes Cocoa Application Framework" document for all the changes to AppKit in Leopard.

Quartz Composer

Developers can now make their own Quartz Composer patches by subclassing QCPlugIn. This opens up the door for third party patches to make Quartz Composer even cooler than it already is. I am really looking forward to seeing what developers come up with, and how this is used inside of applications.

See the "Quartz Composer Custom Patch Programming Guide" for the full details on creating custom patches.

Other APIs

Other new and improved APIs and features include:

FSEvents to monitor file system updates.

Core Data 2.0, which includes support for versioning of managed object models and migration of data from one version to another.

Scripting Bridge to seamlessly interact with scriptable applications. For example, to get the current track in iTunes would look like:

   NSString * currentTrackName = [[iTunes currentTrack] name];

The Calendar Store framework to provide access to data from the iCal application.

Updates to the Instant Message framework to support injecting audio or video content into a running conference.

The Image Kit framework to support drawing of images and easier image manipulation.

The PubSub framework to support RSS and Atom.

Updates to QuickTime Kit to support audio and video capture.

And much, much more! See "What's New In Mac OS X" for the complete list.

Resolution Independence

LCD monitor technology is improving rapidly, cramming more and more pixels into an inch than ever before. Ultimately this means crisper images and text. Unfortunately, there is currently little OS and application support for these higher resolution monitors. If no scaling is done, then text becomes too small and unreadable. If the OS tries to scale the user interface, then graphics can look pixelated or show artifacts.

With Leopard, Apple is pushing developers to make their applications resolution independent. Resolution independent means that the graphics and text should look crisp and clear on all monitors, no matter their resolution. In practice this means updating your artwork so that it scales properly. You also need to update any custom drawing code to make sure it does not assume a specific screen resolution. You can test your application to see what it would look like at different resolutions using the Quartz Debug tool.

Apple is obviously preparing developers so it can start using these higher resolution monitors in their products at some point in the future. We don't know when this is, so it's better to start early and begin updating your applications when Leopard comes out. Consult the "Resolution Independence Guidelines" document for more information on this topic.

Other Languages

The final feature I'm going to highlight is the new support for scripting languages, such as Ruby and Python. It is now possible to write full-blown Cocoa applications using Ruby and Python instead of Objective-C. This has been possible on previous versions of Mac OS X by downloading third party bridge frameworks, but Apple is now including RubyCocoa and PyObjc as part of the standard installation. This means you no longer have to bundle these frameworks with your finished application. It also means that Xcode includes templates for Ruby- and Python-based applications out of the box. Finally, it means that Apple will be supporting any bugs and issues that crop up with these bridges.

To give you a small taste of what this means, here is a short example of subsclassng NSView in Ruby, taken from the DotView sample RubyCocoa application:

require 'osx/cocoa'
class DotView < OSX::NSView
  ib_outlets   :colorWell, :sizeSlider
  def awakeFromNib
    @color = OSX::NSColor.redColor
    @radius = 10.0
    @center = OSX::NSPoint.new(bounds.size.width / 2,
                bounds.size.height / 2)
    @colorWell.setColor(@color)
    @sizeSlider.setFloatValue(@radius)
  end
  def drawRect (rect)
    OSX::NSColor.whiteColor.set
    OSX::NSRectFill(bounds)
    dot_rect = OSX::NSRect.new(@center.x - @radius, @center.y - @radius,
                2 * @radius, 2 * @radius)
    @color.set
    OSX::NSBezierPath.bezierPathWithOvalInRect(dot_rect).fill
  end
  def isOpaque
    true
  end
  def mouseUp (event)
    @center = convertPoint(event.locationInWindow, :fromView, nil)
    setNeedsDisplay true
  end
  def setColor (sender)
    @color = sender.color
    setNeedsDisplay true
  end
  ib_action :setColor
  def setRadius (sender)
    @radius = sender.floatValue
    setNeedsDisplay true
  end
  ib_action :setRadius
end

Apple is also making it easier for other Objective-C and Cocoa bridges by creating a new framework called Bridge Support.

Conclusion

Well, that's a whirlwind introduction to Leopard. The developer has a lot to look forward to, and I think it is a very exciting release. Next month, we'll be back to our regular scheduled programming: learning the basics of Objective-C and programming for Mac OS X.


Dave Dribin has been writing professional software for over eleven years. After five years programming embedded C in the telecom industry and a brief stint riding the Internet bubble, he decided to venture out on his own. Since 2001, he has been providing independent consulting services, and in 2006, he founded Bit Maki, Inc. Find out more at http://www.bitmaki.com/ and http://www.dribin.org/dave/.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Microsoft Remote Desktop 8.0.16 - Connec...
With Microsoft Remote Desktop, you can connect to a remote PC and your work resources from almost anywhere. Experience the power of Windows with RemoteFX in a Remote Desktop client designed to help... Read more
Spotify 1.0.4.90. - Stream music, create...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
djay Pro 1.1 - Transform your Mac into a...
djay Pro provides a complete toolkit for performing DJs. Its unique modern interface is built around a sophisticated integration with iTunes and Spotify, giving you instant access to millions of... Read more
Vivaldi 1.0.118.19 - Lightweight browser...
Vivaldi browser. In 1994, two programmers started working on a web browser. Our idea was to make a really fast browser, capable of running on limited hardware, keeping in mind that users are... Read more
Stacks 2.6.11 - New way to create pages...
Stacks is a new way to create pages in RapidWeaver. It's a plugin designed to combine drag-and-drop simplicity with the power of fluid layout. Features: Fluid Layout: Stacks lets you build pages... Read more
xScope 4.1.3 - Onscreen graphic measurem...
xScope is powerful set of tools that are ideal for measuring, inspecting, and testing on-screen graphics and layouts. Its tools float above your desktop windows and can be accessed via a toolbar,... Read more
Cyberduck 4.7 - 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
Labels & Addresses 1.7 - Powerful la...
Labels & Addresses is a home and office tool for printing all sorts of labels, envelopes, inventory labels, and price tags. Merge-printing capability makes the program a great tool for holiday... Read more
teleport 1.2.1 - Use one mouse/keyboard...
teleport is a simple utility to let you use one single mouse and keyboard to control several of your Macs. Simply reach the edge of your screen, and your mouse teleports to your other Mac! The... Read more
Apple iMovie 10.0.8 - Edit personal vide...
With an all-new design, Apple iMovie lets you enjoy your videos like never before. Browse your clips more easily, instantly share your favorite moments, and create beautiful HD movies and Hollywood-... Read more

Use Batting Average and the Apple Watch...
Batting Average, by Pixolini, is designed to help you manage your statistics. Every time you go to bat, you can use your Apple Watch to track  your swings, strikes, and hits. [Read more] | Read more »
Celebrate Studio Pango's 3rd Annive...
It is time to party, Pangoland pals! Studio Pango is celebrating their 3rd birthday and their gift to you is a new update to Pangoland. [Read more] | Read more »
Become the World's Most Important D...
Must Deliver, by cherrypick games, is a top-down endless-runner witha healthy dose of the living dead. [Read more] | Read more »
SoundHound + LiveLyrics is Making its De...
SoundHound Inc. has announced that SoundHound + LiveLyrics, will be one of the first third-party apps to hit the Apple Watch. With  SoundHound you'll be able to tap on your watch and have the app recognize the music you are listening to, then have... | Read more »
Adobe Joins the Apple Watch Lineup With...
A whole tidal wave of apps are headed for the Apple Watch, and Adobe has joined in with 3 new ways to enhance your creativity and collaborate with others. The watch apps pair with iPad/iPhone apps to give you total control over your Adobe projects... | Read more »
Z Steel Soldiers, Sequel to Kavcom'...
Kavcom has released Z Steel Soldiers, which continues the story of the comedic RTS originally created by the Bitmap Brothers. [Read more] | Read more »
Seene Lets You Create 3D Images With You...
Seene, by Obvious Engineering, is a 3D capture app that's meant to allow you to create visually stunning 3D images with a tap of your finger, and then share them as a 3D photo, video or gif. [Read more] | Read more »
Lost Within - Tips, Tricks, and Strategi...
Have you just downloaded Lost Within and are you in need of a guiding hand? While it’s not the toughest of games out there you might still want some helpful tips to get you started. [Read more] | Read more »
Entertain Your Pet With Your Watch With...
The Petcube Camera is a device that lets you use live video to check in on your pet, talk to them, and play with them using a laser pointer - all while you're away. And the Petcube app is coming to the Apple Watch, so you'll be able to hang out with... | Read more »
Now You Can Manage Your Line2 Calls With...
You'll be able to get your Line2 cloud phone service on the Apple Watch very soon. The watch app can send and receive messages using hands-free voice dictation, or by selecting from a list of provided responses. [Read more] | Read more »

Price Scanner via MacPrices.net

Intel Compute Stick: A New Mini-Computing For...
The Intel Compute Stick, a new pocket-sized computer based on a quad-core Intel Atom processor running Windows 8.1 with Bing, is available now through Intel Authorized Dealers across much of the... Read more
Heal to Launch First One-Touch House Call Doc...
Santa Monica, California based Heal, a pioneer in on-demand personal health care services — will offer the first one-touch, on-demand house call doctor app for the Apple Watch. Heal’s Watch app,... Read more
Mac Notebooks: Avoiding MagSafe Power Adapter...
Apple Support says proper usage, care, and maintenance of Your Mac notebook’s MagSafe power adapter can substantially increase the the adapter’s service life. Of course, MagSafe itself is an Apple... Read more
12″ Retina MacBook In Shootout With Air And P...
BareFeats’ rob-ART morgan has posted another comparison of the 12″ MacBook with other Mac laptops, noting that the general goodness of all Mac laptops can make which one to purchase a tough decision... Read more
FileMaker Go for iPad and iPhone: Over 1.5 Mi...
FileMaker has announced that its FileMaker Go for iPad and iPhone app has surpassed 1.5 million downloads from the iTunes App Store. The milestone confirms the continued popularity of the FileMaker... Read more
Sale! 13-inch 2.7GHz Retina MacBook Pro for $...
 Best Buy has the new 2015 13″ 2.7GHz/128GB Retina MacBook Pro on sale for $1099 – $200 off MSRP. Choose free shipping or free local store pickup (if available). Price for online orders only, in-... Read more
Minimalist MacBook Confirms Death of Steve Jo...
ReadWrite’s Adriana Lee has posted a eulogy for the “Digital Hub” concept Steve Jobs first proposed back in 2001, declaring the new 12-inch MacBook with its single, over-subscribed USB-C port to be... Read more
13-inch 2.7GHz Retina MacBook Pro for $1234 w...
Adorama has the 13″ 2.7GHz/128GB Retina MacBook Pro in stock for $1234.99 ($65 off MSRP) including free shipping plus a free LG external DVD/CD optical drive. Adorama charges sales tax in NY & NJ... Read more
13-inch 2.5GHz MacBook Pro available for $999...
 Adorama has the 13-inch 2.5GHz MacBook Pro on sale for $999 including free shipping plus NY & NJ sales tax only. Their price is $100 off MSRP. Read more
Save up to $600 with Apple refurbished Mac Pr...
The Apple Store is offering Apple Certified Refurbished Mac Pros for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... 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* Support Technician IV - Jack Henry a...
Job Description Jack Henry & Associates is seeking an Apple Support Technician. This position while acting independently, ensures the proper day-to-day control of Read more
*Apple* Client Systems Solution Specialist -...
…drive revenue and profit in assigned sales segment and/or region specific to the Apple brand and product sets. This person will work directly with CDW Account Managers Read more
*Apple* Software Support - Casper (Can work...
…experience . Full knowledge of Mac OS X and prior . Mac OSX / Server . Apple Remote Desktop . Process Documentation . Ability to prioritize multiple tasks in a fast pace Read more
*Apple* Software Support - Xerox Corporation...
…Imaging experience Full knowledge of Mac OS X and prior Mac OSX / Server Apple Remote Desktop Process Documentation Ability to prioritize multiple tasks in a fast pace Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.