TweetFollow Us on Twitter

December 93 - DRAG AND DROP FROM THE FINDER

DRAG AND DROP FROM THE FINDER

DAVE EVANS AND GREG ROBBINS

[IMAGE 066-075_Evans_Robbins_re1.GIF]

Some users navigate Standard File dialogs with no problem, but many others find them tedious or even confusing. Users want to find and organize their files without having to learn the intricacies of the hierarchical file system and Standard File dialogs. With applications that use the Drag Manager, users will be able to work with files the way they expect: by dragging files from the Finder into an application window. This article and the accompanying sample program show how easily your application can provide this valuable feature.


The Drag Manager is so new you won't find it in Inside Macintosh yet, but if your application works with files, you'll want to learn more about what it can do for you. This new Macintosh Toolbox manager lets users drag and drop data (such as text and pictures) between windows in an application and between different applications. It also allows users to drag document icons to and from the Finder.

Rather than describing the Drag Manager in depth, this article and its sample application focus on using the Drag Manager to drag picture files (files of type 'PICT') from the Finder into an application. The techniques used by the sample application can easily be generalized to cover other cases.

The Drag Manager is currently packaged as a system software extension that you can license to include with your products. It requires System 7, and to take advantage of the Finder dragging described in this article you need Finder version 7.1.1 or later. You can order the full Macintosh Drag and Drop Developer's Kit from APDA. The Drag Manager will also be included in future system software releases.

Along with the sample application, called SimpleDrag, this issue's CD contains the programmer's guide for the Drag Manager as well as theDrag and Drop Human Interface Guidelines. After you've read this article and looked at the SimpleDrag code, you should read these two documents to get a deeper understanding of the Drag Manager. SimpleDrag not only allows picture files to be dragged from the Finder but also lets PICT data be dragged from one application window into another; for the full story on this, look at the code and documentation on the CD.

THE INTERFACE: IT'S NOT SUCH A DRAG

Dragging is a skill that every Macintosh user has mastered. It provides a quick, simple alternative to commands as a way of performing common operations such as moving or deleting files. This use of dragging gives users a sense of control because they can manipulate objects directly with excellent visual feedback. And it's faster and more intuitive than commands because it's not hidden in a menu.

Since all Macintosh users use dragging to arrange and manipulate files in the Finder, it only makes sense that they should be able to drag files from the Finder into an application window. But until now, the only way to select and specify files within an application has been with Standard File dialogs. Now you can use the Drag Manager to provide an alternate, more intuitive way to work with files: the user can open a file in your application simply by dragging the file's icon into an application window.

FIRST, A FEW TERMS

Before we look at the sample code, we need to clarify a few terms that the Drag manager introduces: drag items, drag flavors, drag handlers, senders, and receivers.

The objects that a user drags are called drag items. For example, a user who selects and drags three files is dragging three different drag items.

Drag flavorsdescribe the kind of data that a drag item contains. When a user drags an item to an application window, the receiving application must determine whether it can accept the data in the drag item. Each item can have more than one flavor, because data can usually be described in more than one format or data type. For example, you can describe text data as ASCII data, styled text data, or RTF interchange format; if a program can't accept the more elaborate RTF format, it may be able to use the plain ASCII text. The Drag Manager uses a four-character ResType to identify a flavor. In our sample application, we use only two drag flavors: one that identifies files dragged from the Finder, and another that identifies PICT data dragged from an application window.

The Drag Manager uses an application'sdrag handlersto provide dragging feedback and to complete a drag. There are two types of drag handlers:tracking handlersand receive handlers. A tracking handler is called while an item is being dragged over an application's windows; a receive handler is called when the user releases the mouse button to drop the item in a window. Each window has a tracking handler and receive handler installed for it, though several windows may use the same handler. When you initialize your application or open a new window, you call the Drag Manager to install your drag handler callback routines.

Because the Drag Manager provides interapplication drag and drop services, it's important to know where the drag starts and where it ends. The application in which the drag starts is called thesender. Any application that the item is dragged over is a potentialreceiverof the drag; the application it's dropped into is the actual receiver. The sender and receiver might be the same application -- but with interapplication dragging, another application could be the receiver of the drag.

NOW, ON TO THE CODE

With the lingo out of the way, let's look at our SimpleDrag application. This application displays pictures in its windows. One way the user specifies a picture file to be displayed is by choosing the application's Open command and then selecting a file from the Standard File dialog. But since the application uses the Drag Manager, the user can also drag a picture file from the Finder into a SimpleDrag window. PICT data displayed in a SimpleDrag window can even be dragged into another SimpleDrag window.

Before you call any Drag Manager routines, make sure that the Drag Manager is available by calling Gestalt with the selector gestaltDragMgrAttr and checking the gestaltDragMgrPresent bit of the response. *

First let's consider the code for the Open command case. When the user chooses the Open command, SimpleDrag calls the Standard File Package to present a dialog that lists the picture files. Once the user has selected a file, SimpleDrag calls its SetWindowPictureFromFile routine to read the file and display it.

To support dragging files from the Finder into the application, SimpleDrag installs two drag handlers for each new window. While the user drags a PICT drag item over a SimpleDrag window, the tracking handler provides visual feedback. If the user drops the item in a SimpleDrag window, the Drag Manager calls the receive handler to read and display the PICT information, which may be not only a picture file but also PICT data dragged from another window; the receive handler calls itsSetWindowPictureFromFile routine if the drag item is a picture file (just as when the user chooses Open from the File menu).

The following routine installs the tracking and receive handlers:

OSErr InstallDragHandlers(WindowPtr theWindow)
{ 
    OSErr retCode;

    retCode = InstallTrackingHandler(MyTrackingHandler, theWindow,
                  nil);
    if (retCode == noErr) {
        retCode = InstallReceiveHandler(MyReceiveHandler, theWindow,
                      nil);
        if (retCode != noErr)
            (void) RemoveTrackingHandler(MyTrackingHandler,
                  theWindow);
    }
    return retCode;
}

That's all you need to do to set up tracking and receive handlers for the given window. You can also install a default handler, to be used for any window that you don't explicitly install a handler for, by passing nil as the window pointer to the install routine.

TRACKING THE DRAG
Now let's see what happens while the user drags an item around. Our main objective is to indicate, with visual feedback, where it's OK to drop the item. SimpleDrag provides the standard feedback highlighting for its type of windows and data -- a thin frame highlight within the content region of the window. This highlight signals the user that the item can be dropped there.

While the user drags an item (or items) over one of the application's windows, the mouse movement determines what messages the tracking handler receives, as follows:

  • The tracking handler receives an EnterHandler message the first time it's called (that is, the first time the drag enters a window that uses that handler). You can allocate memory or, as in our application, check whether you can receive the drag.
  • The handler receives an EnterWindow message when the drag enters a window. This message is distinct from EnterHandler because you may be using the same handler for more than one window, in which case there might be many EnterWindow messages between an EnterHandler/LeaveHandler pair.
  • While the user drags within a window, the handler receives multiple InWindow messages.
  • When the drag leaves the window, the handler receives a LeaveWindow message.
  • When the user drags to a window that uses a different tracking handler, the handler receives a LeaveHandler message.

The tracking handler for SimpleDrag is as follows:

pascal OSErr MyTrackingHandler(DragTrackingMessage theMessage,
    WindowPtr theWindow, void *handlerRefCon, DragReference theDrag)
{
#pragma unused (handlerRefCon)

    RgnHandle   tempRgn;
    Boolean     mouseInContentFlag;
    OSErr           retCode;
    
    retCode = noErr;
    switch (theMessage) {
        case dragTrackingEnterHandler:
            // Determine whether the drag item is acceptable and
            // store that flag in the globals, plus reset the
            // highlighted global flag.
            gDragHandlerGlobals.acceptableDragFlag = 
                DragItemsAreAcceptable(theDrag);
            gDragHandlerGlobals.windowIsHilightedFlag = false;
            break;
            
        case dragTrackingEnterWindow: 
        case dragTrackingInWindow:
        case dragTrackingLeaveWindow:
            // Highlighting of the window during a drag is done here.
            // Do it only if we can accept this item and we're not
            // in the source window.
            if (gDragHandlerGlobals.acceptableDragFlag &&
                    DragIsNotInSourceWindow(theDrag)) {
                if (theMessage == dragTrackingLeaveWindow)
                    mouseInContentFlag = false;
                else
                    mouseInContentFlag = MouseIsInContentRgn(theDrag,
                                            theWindow);
                if (mouseInContentFlag &&
                       !gDragHandlerGlobals.windowIsHilightedFlag) {
                    ClipRect(&theWindow->portRect);
                    tempRgn = NewRgn();
                    RectRgn(tempRgn, &theWindow->portRect);
                    if (ShowDragHilite(theDrag, tempRgn, true) == 
                            noErr)
                        gDragHandlerGlobals.windowIsHilightedFlag =
                            true;
                    DisposeRgn(tempRgn);
                }
                else if (!mouseInContentFlag &&
                        gDragHandlerGlobals.windowIsHilightedFlag) {
                    ClipRect(&theWindow->portRect);
                    if (HideDragHilite(theDrag) == noErr)
                        gDragHandlerGlobals.windowIsHilightedFlag =
                            false;
                }
            }
            break;

        case dragTrackingLeaveHandler:
            // Do nothing for the LeaveHandler message.
            break;
        
        default:
            // Let the Drag Manager know we didn't recognize the
            // message.
            retCode = paramErr;
    }
    return retCode;
}

The EnterWindow message is sent when the drag enters the structure region of a window, not the content region. The Drag and Drop Human Interface Guidelines specify that the title bar of a window, which is outside the content region, should not be able to receive drags. So upon receiving an EnterWindow message, the tracking handler needs to check the mouse location before calling ShowDragHilite.*

To give the user visual feedback, the tracking handler uses the Drag Manager's ShowDragHilite routine. This routine takes a region to be highlighted and draws an inset or outset frame of that region. Here we use it to highlight inside the content region of the window, but you can also use it to highlight panes within a window or any arbitrary region that accepts a drag. We later call HideDragHilite when the drag leaves the content region of our window.

As you can see in the above code, there are several conditions to check for before calling the highlight routines. The DragItemsAreAcceptable routine, which the tracking handler calls when it gets an EnterHandler message, checks that only one item is being dragged (a limitation of our simple example) and that the drag item is PICT data or a picture file.

Boolean DragItemsAreAcceptable(DragReference theDrag)
{
    OSErr           retCode;
    unsigned short  totalItems;
    ItemReference   itemRef;
    Boolean         acceptableFlag;
    HFSFlavor       currHFSFlavor;
    Size            flavorDataSize;
    FlavorFlags     currFlavorFlags;
    
    acceptableFlag = false;

    // This application can only accept the drag of a single item.
    retCode = CountDragItems(theDrag, &totalItems);
    if (retCode == noErr && totalItems == 1) {
        retCode = GetDragItemReferenceNumber(theDrag, 1, &itemRef);
        if (retCode == noErr) {
            // Use GetFlavorFlags to see if the drag item is PICT
            // data.
            retCode = GetFlavorFlags(theDrag, itemRef, 'PICT', 
                         &currFlavorFlags);
            if (retCode == noErr)
                acceptableFlag = true;
            else {
                // Check if the item is a file spec for a picture
                // file.
                flavorDataSize = sizeof(HFSFlavor);
                retCode = GetFlavorData(theDrag, itemRef, 
                             flavorTypeHFS, &currHFSFlavor,
                             &flavorDataSize, 0);
                if (retCode == noErr &&
                        currHFSFlavor.fileType == 'PICT') 
                    acceptableFlag = true;
            }
        }
    }
    return acceptableFlag;
}

DragItemsAreAcceptable calls GetFlavorFlags with type 'PICT' to determine whether the drag item is PICT data. If it isn't PICT data, GetFlavorFlags returns cantGetFlavorErr; DragItemsAreAcceptable then checks to see if the drag item is a picture file, by calling GetFlavorData with flavorTypeHFS. This is a special flavor that identifies files dragged from the Finder into an application. Data of type HFSFlavor contains the file's Finder information and an FSSpec that you can use to open and read the file.

typedef struct HFSFlavor {
    OSType          fileType;       // file type
    OSType          fileCreator;    // file creator
    unsigned short  fdFlags;        // Finder flags
    FSSpec          fileSpec;       // file system specification
};
typedef struct HFSFlavor HFSFlavor;

Another check made in the tracking handler is to ensure (with the routine MouseIsInContentRegion) that the drag isn't over the title bar or over controls in the application window. To implement drag and drop according to the guidelines, we accept drags only in the content region of a window. Also, since SimpleDrag doesn't support drag and drop within the same window, the tracking handler checks (with its DragIsNotInSourceWindow routine) to make sure that the user isn't dragging over the same window in which the drag originated.

RECEIVING THE DRAG
The receive handler is similar to the tracking handler, but it's called once, and we must ask for all the data we want. We also make sure that the drag stopped in the content region of the window and that the user isn't dragging back into the source window.

Below is the code for SimpleDrag's receive handler. In a receive handler, you first ask for the data type you prefer, whether picture, text, or some other type, and whether a file from the Finder or data dragged directly from another window. In SimpleDrag, we prefer to receive PICT data directly, so we look for it first. If the drag item isn't PICT data, we use the HFS flavor to look for files of type 'PICT'.

pascal OSErr MyReceiveHandler(WindowPtr theWindow,
        void *handlerRefCon, DragReference theDrag)
{
#pragma unused (handlerRefCon)

    ItemReference   itemRef;
    Size                dataSize;
    Handle          tempHandle;
    HFSFlavor       theHFSFlavor;
    Boolean         dataObtainedFlag;
    OSErr               retCode;
    
    dataObtainedFlag = false;
    if (!DragItemsAreAcceptable(theDrag) ||
            !MouseIsInContentRgn(theDrag, theWindow) ||
            !DragIsNotInSourceWindow(theDrag)) 
        return dragNotAcceptedErr;

    // There is only one item, so get its reference number.
    retCode = GetDragItemReferenceNumber(theDrag, 1, &itemRef);
    if (retCode != noErr)
        return retCode;
    
    // PICT data is preferred, so get it if it's available.
    retCode = GetFlavorDataSize(theDrag, itemRef, 'PICT', &dataSize);
    if (retCode == noErr) {
        tempHandle = TempNewHandle(dataSize, &retCode);
        if (tempHandle == nil)
            tempHandle = NewHandle(dataSize);
        if (tempHandle != nil) {
            HLock(tempHandle);
            retCode = GetFlavorData(theDrag, itemRef, 'PICT',
                          *tempHandle, &dataSize, 0);
            if (retCode == noErr) {
                retCode = SetWindowPicture(theWindow,
                             (PicHandle) tempHandle);
                if (retCode == noErr)
                    dataObtainedFlag = true;
            }
            DisposeHandle(tempHandle);
        }
    }

    if (!dataObtainedFlag) {
        // Couldn't get PICT data so try to get HFS-flavor data.
        dataSize = sizeof(HFSFlavor);
        retCode = GetFlavorData(theDrag, itemRef, flavorTypeHFS, 
                      &theHFSFlavor, &dataSize, 0);
        if (retCode == noErr && theHFSFlavor.fileType == 'PICT') {
            retCode = SetWindowPictureFromFile
                          (&theHFSFlavor.fileSpec, theWindow);
        }
    }

    if (retCode != noErr)
        (void) ReportErrorInWindow(nil, 
                  "\pCannot display received picture. ", retCode);
    return retCode;
}

If there's an error, this receive handler just displays a simple string. For commercial products, you would never code strings inline as shown, for localization reasons.

GOTCHAS

Here we'll describe a couple of precautions you should take that will make your life easier when you use the Drag Manager.

FINDER GOTCHAS
The Drag Manager works for documents and other standard files, but what about folders and hard drive icons? The Finder uses the same HFS flavor to describe these items. If the user drags them to your application, you'll see the FSSpec for the folder's directory or the disk's root directory. The file type and creator information isn't relevant to the file system, but it's useful for identifying the items being dragged. For both folders and disk icons, the creator is set to 'MACS' to show that the system software created them. For folders, the file type is 'fold', and for disk icons the file type is 'disk'. In both cases the Finder flags for the folder or disk are set appropriately. Remember that these file types serve only to quickly identify the items being dragged and don't reflect what's in the catalog information of any volumes.

Some software that extends the functionality of the Finder, such as QuickDraw GX and PowerTalk (the client server software based on the Apple Open Collaboration Environment), adds new Finder icons such as desktop printers, letters, and mailboxes. These items don't actually represent the state of the file system, but they can be dragged like any Finder icon. This is a valuable and consistent metaphor for the Finder interface, but it creates an inconsistency for your receive handler when receiving drags from the Finder. Since these icons can't be described as FSSpecs, don't expect to receive HFS flavors for them.

Just for completeness, you should know that the Users & Groups control panel also uses the Drag Manager. The drag flavors that identify those icons make sense only to the Finder, and don't have relevant information you could extract. The same is true for contents of Finder suitcase files like the System file. Finder icons for sounds, keyboard layouts, and fonts that are in suitcases are representations of resources in the suitcase file, so they don't have HFS flavors to describe them. Note, however, that sound and fontfiles, which are not part of suitcases, use HFS flavors just like any other file.

WAITNEXTEVENT
Another precaution applies if, in drag handlers, you call WaitNextEvent, EventAvail, GetNextEvent, or any other routine that would normally cause a process switch or a background application to receive WaitNextEvent time. In these cases, don't expect other applications to receive any background time, because the Drag Manager disables process switching during a drag. Because process switching is disabled, you should be careful when interacting with the user in your receive handler. You may not be the frontmost process, and opening a dialog may hang the Macintosh.

DRAGGING AWAY

The Drag Manager makes it easy to add drag and drop functionality to your application. It gives users a familiar and intuitive way to manipulate files and data. This article and the sample application emphasize how to implement dragging files from the Finder into your application windows, but youcan do much more than that with the Drag Manager. So take a look at the documentation and guidelines on the CD and give it a go; your users will think it's anything but a drag!

DAVE EVANS can often be found coding for the User Experience team of the AppleSoft OS Platform Group. Although some still think he moonlights on the set of the TV show "Beverly Hills 90210," Dave actually finds entertainment by throwing himself off cliffs and cornices, plane struts and buildings (the last much to Apple Security's chagrin). Dave does admit, though, to being deathly afraid of bungee jumps! *

GREG ROBBINS has been insisting for three years that he doesn't work for Apple. But he has worked as a consultant to the Developer Technical Support and Macintosh System Software groups since 1991, having given up an earlier passion for neural networks to hack the Mac. Greg spends his off hours in the mountains of California, looking for people even more lost than he is.*

For more on letters and mailboxes, see the article "Building PowerTalk-Savvy Applications" in this issue of develop.*

THANKS TO OUR TECHNICAL REVIEWERSSteve Fisher, Rob Johnston, Jim Mensch, Andy Nicholas *

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Artlantis Studio 5.1.2.7 - 3D rendering...
Artlantis Studio is a unique and ideal tool for performing very high resolution rendering easily and in real time. The new FastRadiosity engine now lets you compute images in radiosity-even in... Read more
MacUpdate Desktop 6.0.5 - Search and ins...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
BitTorrent Sync 2.0.82 - Sync files secu...
BitTorrent Sync allows you to sync unlimited files between your own devices, or share a folder with friends and family to automatically sync anything. File transfers are encrypted. Your information... Read more
Google Drive 1.20 - File backup and shar...
Google Drive is a place where you can create, share, collaborate, and keep all of your stuff. Whether you're working with a friend on a joint research project, planning a wedding with your fiancé, or... Read more
Simon 4.0.3 - Monitor changes and crashe...
Simon monitors websites and alerts you of crashes and changes. Select pages to monitor, choose your alert options, and customize your settings. Simon does the rest. Keep a watchful eye on your... Read more
Vitamin-R 2.23 - Personal productivity t...
Vitamin-R creates the optimal conditions for your brain to work at its best by structuring your work into short bursts of distraction-free, highly focused activity alternating with opportunities for... Read more
iDefrag 5.0.0 - Disk defragmentation and...
iDefrag helps defragment and optimize your disk for improved performance. Features include: Supports HFS and HFS+ (Mac OS Extended). Supports case sensitive and journaled filesystems. Supports... Read more
PCalc 4.2 - Full-featured scientific cal...
PCalc is a full-featured, scriptable scientific calculator with support for hexadecimal, octal, and binary calculations, as well as an RPN mode, programmable functions, and an extensive set of unit... Read more
FileZilla 3.10.2 - Fast and reliable FTP...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.10.2: Note: Now requires a 64-bit Intel processor.... Read more
The Hit List 1.1.11 - Advanced reminder...
The Hit List manages the daily chaos of your modern life. It's easy to learn - it's as easy as making lists. And it's powerful enough to let you plan, then forget, then act when the time is right.... Read more

Protect Yourself from an Onslaught of Ca...
Surprise Attack Games has announced a Cat-astrophic new physics puzzler called Fort Meow! In the game, a young girl named Nia finds her grandfather’s journal which triggers an all mighty feline attack! Why do the cats want the journal? Who knows,... | Read more »
GDC 2015 – Jelly Reef will be Game Oven’...
GDC 2015 – Jelly Reef will be Game Oven’s Last Hurrah, and it Seems like a Good Note to Go Out on Posted by Rob Rich on March 4th, 2015 [ permalink ] It’s sad knowing that Game Oven ( | Read more »
daWindci Deluxe Review
daWindci Deluxe Review By Campbell Bird on March 4th, 2015 Our Rating: :: BLUSTERY PUZZLESUniversal App - Designed for iPhone and iPad This updated puzzle game offers some creative gameplay and new mechanics, but still suffers from... | Read more »
Dungeon Hunter 5 Coming on March 12
Gameloft has excitedly announced that Dungeon Hunter 5 is on its way! Once again, you will adventure across the land of Valenthia exploring dungeons and fighting monsters. The game will have a new asynchronous multiplayer mode called Strongholds... | Read more »
GDC 2015 – The Sandbox 2 is Coming, and...
GDC 2015 – The Sandbox 2 is Coming, and Now it has Textures! | Read more »
Warner Bros. Interactive Announces Mort...
Mortal Kombat X, by Warner Bros. and NetherRealm Studios, will be a a free-to-play fighting/card-battle Mortal Kombat game. The game promises card collecting, multiplayer team combat, classic characters such as Scorpion, Sub-Zero and Raiden, and the... | Read more »
GDC 2015 – Piloteer is Whitaker Trebella...
GDC 2015 – Piloteer is Whitaker Trebella’s Latest Project, and it’s Definitely Something DIfferent Posted by Rob Rich on March 3rd, 2015 [ permalink ] You know | Read more »
PangoLand Review
PangoLand Review By Amy Solomon on March 3rd, 2015 Our Rating: :: COME VISIT PANGO AND FRIENDSUniversal App - Designed for iPhone and iPad PangoLand is an open-ended world full of familiar characters, bright colors and interactive... | Read more »
Knights of Pen & Paper is Leveling U...
With the roll of a die and a critical success, Paradox Interactive has announced Knights of Pen & Paper 2! You’ll be taking your place at the table once again in this sequel to Knights of Pen & Paper +1 Edition. The game will introduce the... | Read more »
GDC 2015 – Project Highrise is an Intere...
GDC 2015 – Project Highrise is an Interesting Idea from SomaSim Posted by Rob Rich on March 3rd, 2015 [ permalink ] You might know SomaSim best from their gold rush sim, 1849< | Read more »

Price Scanner via MacPrices.net

Mac Pros on sale for up to $279 off MSRP
Amazon has Mac Pros in stock and on sale for up to $279 off MSRP. Shipping is free: - 4-Core Mac Pro: $2725.87, $273 off MSRP (9%) - 6-Core Mac Pro: $3719.99, $279 off MSRP (7%) Read more
Sale! 13-inch Retina MacBook Pros for up to $...
B&H Photo has 13″ Retina MacBook Pros on sale for up to $205 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.6GHz/128GB Retina MacBook Pro: $1219.99 save $80 - 13″ 2.... Read more
Another Tranche Of IBM MobileFirst For iOS Ap...
IBM has announced the next expansion phase for  its IBM MobileFirst for iOS portfolio, with a troika of new apps to address key priorities for the Banking and Financial Services, Airline and Retail... Read more
Sale! 15-inch Retina MacBook Pros for up to $...
B&H Photo has the new 2014 15″ Retina MacBook Pros on sale for up to $250 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $... Read more
WaterField Designs Introduces the Minimalist...
With Apple Pay gaining popularity, Android Pay coming in May 2015, and loyalty cards and receipts that can be accessed from smartphones, San Francisco’s WaterField Designs observes that it may be... Read more
Sale! 15-inch 2.2GHz Retina MacBook Pro for $...
 Best Buy has the 15″ 2.2GHz Retina MacBook Pro on sale for $1774.99 $1799.99, or $225 off MSRP. Choose free home shipping or free local store pickup (if available). Price valid for online orders... Read more
13-inch 2.5GHz MacBook Pro (refurbished) avai...
The Apple Store has Apple Certified Refurbished 13″ 2.5GHz MacBook Pros available for $170 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz... Read more
13-inch 2.5GHz MacBook Pro on sale for $100 o...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999.99 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more
27-inch 3.5GHz 5K iMac in stock today and on...
 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
Apple Launches Free Web-Based Pages and Other...
Apple’s new Web-only access to iWork productivity apps is a free level of iCloud service available to anyone, including people who don’t own or use Apple devices. The service includes access to Apple... Read more

Jobs Board

*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
Position Opening at *Apple* - Apple (United...
…Summary** As a Specialist, you help create the energy and excitement around Apple products, providing the right solutions and getting products into customers' hands. You Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** The Apple Store is a retail environment like no other - uniquely focused on delivering amazing customer experiences. As an Expert, you introduce people Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
*Apple* Pay Automation Engineer - iOS System...
**Job Summary** At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring passion and dedication to your job Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.