TweetFollow Us on Twitter

Counting To X

Volume Number: 15 (1999)
Issue Number: 3
Column Tag: ExplainIt

Counting to X

by Dave Evans and Mark Turner

Ten Steps Toward Carbon Compatibility

Carbon is the basic element in Apple's plan to take Mac OS applications into the next millennium. Together with Mac OS X, Carbon delivers exactly what developers have been asking for -; an easy way of allowing Mac applications to enjoy all the advantages of a memory protected, preemptively scheduled, multitasking operating system.

A preliminary version of the Carbon SDK has already been released to members of the Apple Developer Program, but even if you're not a member, there's a lot you can do now to make your transition to Mac OS X easier. And the good news is that these changes will also provide a better experience for your customers running Mac OS 8. In this article we'll discuss ten steps you can take to prepare for Carbon. But first, a brief overview of Carbon and why it's important that you prepare for it now.

Carbon Defined

Carbon is a set of APIs that run on both Mac OS 8 and Mac OS X. It's a hybrid that includes over 70 percent of the existing Mac OS APIs, covering about 95 percent of the functions used by applications. Because it includes most of the functions you rely on today, converting to Carbon is relatively painless. And by weeding out or modifying certain difficult-to-support functions, Carbon provides a more streamlined and stable base for application development.

What this means for you is that by making a small investment in Carbon, your programs will gain these benefits when running under Mac OS X:

  • Greater stability.
    Preemptive multitasking and protected address spaces will help prevent other people's bugs from crashing your application. (It goes without saying that there are no bugs in your code!)
  • Improved responsiveness.
    Because all applications are guaranteed processing time through preemptive scheduling, you don't have to worry about being locked out by another program that's hogging the CPU. And since Mac OS X and Carbon are 100% PowerPC native, there's no 68K emulation and no mode-switching overhead to slow down your applications.
  • Efficient use of system resources.
    Your application isn't limited to a fixed heap size and can dynamically allocate memory and other system resources based on actual needs rather than predetermined values.

Although your current applications will continue to run unmodified in Mac OS X through a technology code-named the Blue Box, they won't enjoy all the performance and reliability enhancements of Mac OS X until you update them for Carbon.

That all sounds great, but the best part is that you don't have to wait for Mac OS X to appreciate the benefits of Carbon. By cleaning up old code and adopting Carbon-compatible APIs, your applications will run more reliably on today's Mac OS while taking advantage of the latest Apple technologies and human interface improvements.

Nothing's free in this world, and Carbon is no exception. It'll cost you about two weeks work to update a typical application. But by preparing for Carbon now, your applications will not only run better on Mac OS 8, they'll be ready to rock when Mac OS X rolls out later this year.

Carbon Coding

Okay, time to roll up your sleeves, fire up your Mac, and give your app a tune-up.

I. Read the Carbon Paper

Before you change a single line of code, you should read Transitioning to Mac OS X: An Overview of the Carbon Programming Interface. This white paper explains why Carbon is so important, and defines Apple's goals for the project. It also lists the expected level of support for all existing Mac OS APIs. You'll find the Carbon Paper, and a lot of other helpful information, on the Carbon web site at http://developer.apple.com/macosx/carbon/.

While you're visiting the web site, be sure to check out the official Carbon Specification for the most up-to-date list of supported APIs. Then download the Carbon Dater tool, because we're going to talk about it next.

II. Run Carbon Dater

If you completed Step I, you already know that Apple's Carbon Dater tool provides a detailed report of your code's current Carbon compliance level. (If you didn't follow Step I, shame on you! Go back and read the Carbon Paper.) Carbon Dater works by examining PEF containers in application binaries and CFM libraries. It compares the list of Mac OS symbols your code imports against Apple's database of Carbon-supported functions and issues a spiffy report formatted in HTML.

In addition to analyzing your Mac OS function calls, Carbon Dater tries to identify any attempts to read or write directly to low-memory, and it also reports if any of your resources have the system heap bit set. Carbon applications don't have access to the system heap in Mac OS X, so you can't load resources there.

As we discuss in Step IV, all access to low-memory system global data must be through accessor functions. Because many of today's accessor functions are simply macros that implement a load or store to memory, Carbon Dater can't determine if your low-memory accesses are illegal -; it's up to you to make sure you're using the proper functions.

Apple is working very hard to make the Carbon transition an easy one, and the Carbon Dater statistics bear this out. As Figure 1 shows, of the thousands of applications tested, the average compliance level is over 95 percent.


Figure 1. Carbon Dater Results

For step-by-step instructions on running Carbon Dater and interpreting the results, see the Getting Started column, Carbon: Getting Ready for Mac OS X, in the January 1999 issue of MacTech.

III. Use the Most Recent Universal Headers

Okay, so you've read up on Carbon, tested your application, and most likely discovered that it's pretty close to 95 percent compatible. What do you do next? Sync up with the latest Universal Header files!

You can start by downloading the current headers from Apple's web site. As of this writing, Apple has released version 3.2 of the Universal Headers, incorporating all the new technologies in Mac OS 8.5. In addition to new APIs, there are minor changes from previous 3.x versions. For example, the KeyMap definition has changed from an array of longs to an array of Uint32 values. Be sure to read the release notes for more information about what has changed.

After successfully building your application on the current headers, you should download and install the Carbon headers. The Carbon headers incorporate additional changes, including new conditionals to use when building Carbon applications and new APIs to replace some of the older functions that aren't supported in Carbon.

The Carbon headers eventually will be rolled into future versions of the Universal Headers, and you can use them for building non-Carbon applications today. To build a Carbon application, just add the following statement to one of your source files before including any of the Carbon headers:

#define TARGET_CARBON 1

The TARGET_CARBON conditional specifies that the included header files should allow only Carbon-compatible APIs and data structures. When you throw this switch and rebuild, you're likely to get a number of errors and warnings from the compiler. For now, stifle the urge to hack your way through those errors. You'll save yourself a lot of time if you read the rest of this article and address each issue methodically.

IV. Avoid Using Low-Memory Globals

Low-memory globals are system and application global data located below the system heap in Mac OS 8. They typically fall between the hexadecimal addresses $100 and $2800. Since the transition to PowerPC, Apple has provided accessor routines for getting and setting these global variables. Prior to that, you would simply dereference the absolute address of the global to modify it.

Carbon applications still have access to many of the low-memory globals, although in some cases the scope and impact of the global has changed. But in all cases, Carbon applications must use the supplied accessor routines to examine or change global variables. Attempting to access them directly with an absolute address will crash your application when running on Mac OS X.

The complete list of low-memory globals supported in Carbon hasn't been published yet, but you'll be better prepared if you take the time now to review your use of low memory. The transition to Carbon will be easier if you follow these guidelines:

  • Use high-level Toolbox calls instead of low-memory accessors whenever possible.
  • If a high-level call is not available, use an accessor function.
  • Rely on global data only from Toolbox managers supported in Carbon.

Make your best guess about the last point until Apple publishes a definitive list. For example, because the driver-related calls in the Device Manager are not supported in Carbon, low-memory accessors like LMGetUTableBase are not likely to be available. Similarly, direct access to hardware is not supported in Carbon, so calls like LMGetVIA will no longer be useful.

Some low-memory accessors have Toolbox equivalents -; applications must switch to these Toolbox calls instead. For example, use GetMouse instead of LMGetMouse, Ticks instead of LMGetTicks, and MemError instead of LMGetMemErr.

V. Go Native

Because Carbon requires 100% native PowerPC code, you must remove any dependencies on 68K instructions. Unless you have written your application entirely in assembly language, this should not be a big issue for your main application code. Where you are more likely to have 68K code is in custom definition procedures (defprocs) and plug-ins.

Custom defprocs (for example, MDEFs, CDEFs, and LDEFs) must be compiled as PowerPC code and no longer can be stored in resources. Carbon will introduce new variants of CreateWindow and similar calls (NewControl, NewMenu, etc.) that will take a universal ProcPtr for a definition procedure. Instead of providing a WDEF in a resource, you would instead call a new Toolbox routine that might look something like this:

OSStatus CreateCustomWindow(WindowClass windowClass, 
      WindowAttributes attributes, const Rect *bounds, 
      WindowDefUPP customProc, WindowPtr *outWindow);

For all Mac OS functions that expect definition procedures in resources today, there will be new routines to specify the custom procedure. But before you spend a lot of time updating old defprocs, you should think about whether there is any need to continue rolling your own interface elements. New APIs like the Appearance Manager and Navigation Services may provide all the features you want.

That said, if you want to compile custom defprocs into your code today, the following snippet shows a clever way to do it. This will not work in the future for Carbon applications on Mac OS X, but for a Mac OS 8 application, it will allow defprocs in native code using stub routines as shown here.

// Using a 6-byte stub WDEF resource (ID 128 for example),
// fill in a 680x0 'jmp' opcode and the address of a UPP
// to the native definition proc. Note: NewWindowDefProc
// will allocate memory in Mac OS 8.x

Handle theStub;
theStub = GetResource('WDEF', 128);
if (theStub && *theStub)
{
   WindowDefUPP theProcUPP;

   theProcUPP = NewWindowDefProc(&MyWDEF);
   *((long *) (*theStub + 2)) = theProcUPP;
   *((short *) *theStub) = 0x4EF9;

   // We just modified code, flush the emulator cache
   FlushCodeCacheRange(*theStub, 6);
}

VI. Get Used to Opaque Toolbox Data Structures

Some familiar Toolbox data structures are not directly accessible in Carbon. There are new functions to inspect the contents of these opaque structures. For example, you can no longer dereference a CGrafPtr to inspect the contents of the GrafPort structure. Instead of addressing a port bounds rectangle directly with &myport->bounds, you must call the new routine GetPortBounds(myport, &myrect) with a local variable for the result. For each accessible element of an opaque data structure there is a corresponding new routine for getting or setting that element.

Supporting opaque Toolbox structures likely will take some work in your code. To begin with, you probably will have to create new local variables for return results. Almost all accessor functions return a copy of the data and not a pointer to the actual data. This passing of data by value instead of by reference requires that you allocate space for results either in memory or as local variables on the stack. For efficiency, you should place calls to accessors strategically in your code and use them minimally.

Window records are opaque in Carbon, and are not just extended versions of GrafPorts. Windows and ports are no longer synonymous, and code that treats them interchangeably will crash on Mac OS X. For example, the following statement casts a WindowPtr to a GrafPtr:

SetPort( (GrafPtr) myWindow );          // don't do this!

Look familiar? Code like this will cause you grief in the future because your program will compile and run just fine on Mac OS 8 but crash on Mac OS X. The right way to get the port for a window is with the GetWindowPort function, like this:

SetPort( GetWindowPort( myWindow ));   // do this instead

Another practice to avoid is hanging your own data off the end of Toolbox structures. For example, because the internal representation of a window record is no longer visible, you can't save private data by adding it to the end of the window record and passing a pStorage value to NewWindow. In Carbon, you must pass NULL in the pStorage field. If you need extra storage for windows, keep a reference to your data in the refCon field. If you are currently using pStorage in this way, switching to refCon is something you can do today to prepare for Carbon.

The upside to these changes is that Apple can take steps to ensure that the internal representation of data is aligned in memory for fastest access, and new elements can be added for Carbon-specific features. With opaque data structures in Carbon, the Toolbox easily can be extended in the future.

Not all data structures are opaque in Carbon, though. TextEdit data in a TERecord, for example, still is directly accessible. The Apple Event AEDesc structure also is directly accessible, but the type of the dataHandle in the structure is opaque. Some data structures were not made opaque because they're so simple, like the AEDesc structure, and others because the Toolbox component is not expected to change in the future. This is why the TERecord is not opaque, as TextEdit will be replaced outright by a Unicode aware text engine.

VII. Adopt Supported Technologies

A number of Mac OS functions are not being carried forward in Carbon. For these you must adopt Apple's suggested replacement functions or find other ways of accomplishing those functions. Carbon is a work in progress, and you may run across a few APIs that are listed as unsupported in Carbon but for which replacement APIs or workarounds are not yet defined. If you feel strongly that Apple should support an API that is listed as unsupported or under evaluation in the Carbon Specification, make your voice heard by sending e-mail to <carbon@apple.com>.

Three important Carbon-supported technologies that you should adopt today are the Appearance Manager, Navigation Services, and Open Transport. The Appearance Manager coordinates the look and feel of the Mac OS human interface and provides a rational and supported API for adding custom interface elements.

Navigation Services replaces the venerable Standard File Package, and is shipping now in Mac OS 8.5. Using sample code provided in the Navigation Services SDK (available on Apple's web site), we were able to replace all the Standard File calls in AppleWorks in one day. You also should read Keith Mortensen's excellent article on the subject in the August 1998 issue of MacTech.

Open Transport replaces MacTCP and classic AppleTalk in Carbon. If you have not already adopted OT, now is definitely the time. First introduced in System 7.5.2, Open Transport has evolved into a mature, efficient, and extensible networking architecture capable of saturating 100Mbit Ethernet.

VIII. Don't Patch Traps

You cannot patch traps in Mac OS X for one simple reason: there is no trap table. Because the operating system is PowerPC native, no 68K trap table is needed. Unlike Mac OS 8, most calls to Mac OS X Toolbox functions are implemented as a jump directly to the specified routine. In Mac OS 8 you can patch traps to intercept Toolbox calls and modify their behavior, but with no central dispatch mechanism to hook into, this is not possible in Mac OS X.

Consequently, GetTrapAddress, SetTrapAddress, and related functions are not available in Carbon. You can, of course, conditionalize your code and continue to patch traps when running under Mac OS 8, but your programs will be much easier to maintain if you avoid patching entirely.

Apple is considering a variety of mechanisms to allow programmatic extensibility. The goal is to provide you with system-level APIs for altering certain default behaviors. If you have suggestions or specific requirements that you would like Apple to support, send them to <carbon@apple.com>.

For now you should take a close look at any trap patches in your code and ask yourself if they could be replaced with another approach. Instead of patching ExitToShell, for example, try using a CFM termination proc for your main fragment.

IX. Draw Only Within Your Own Windows

Because Mac OS X is a truly preemptive system, any number of applications may be drawing into their windows at the same time. And of course, a user may be dragging a window or other object around the screen while background applications are drawing in their windows. In order to make all this work, Carbon applications must play by these rules:

First, you should no longer try to draw outside of your windows. In the past you could call the GetWMgrPort function and use that port to draw anywhere on the screen. This port no longer exists in Mac OS X. If you were using this technique for custom dragging or zooming feedback, use DragWindow or other Drag Manager functions instead.

Second, if you draw directly into the bitmap of your windows (without using QuickDraw) you must wrap those blits with two new calls that will tell the Window Manager to get out of the way. We are still working on these functions, so for now you might just want to insert some comments to remind you that you eventually must update this kind of code for Carbon.

X. Manage Memory Efficiently

Memory management does not change much for Carbon applications running on Mac OS 8. You will need all the code you use today to manage heap fragmentation, low memory situations, and stack depth.

However, there are some things you must do to perform well when running in a Mac OS X environment. In that world, your application will run in a very different heap structure with different allocation behavior. Your memory will not tend to move as much and your stack will be far away from your heap, with guard pages below it. The most significant change you must make is in determining amounts of free memory and stack space available.

In the future, when your Carbon application is intended to run only on Mac OS X, you will be able to take full advantage of new memory behavior. You might switch from handle-based to pointer-based allocations, for example. But as long as your application runs on Mac OS 8, you should prepare for the same issues you always have.

The functions FreeMem, PurgeMem, MaxMem, and StackSpace are all available in Carbon. You should, however, think about how and why you are using them. You will probably want to consider additional code to better tune your performance.

The FreeMem, PurgeMem, and MaxMem functions behave as expected when your Carbon application is running on Mac OS 8, but they are almost meaningless when it is running on Mac OS X, where you have essentially unlimited virtual memory. Although you can still use these calls to ensure that your memory allocations will not fail, you should not use them to allocate all available memory. Allocating too much virtual memory will cause excessive page faults and reduce system performance. Instead, determine how much memory you really need for your data, and allocate that amount.

Before Carbon you would use the StackSpace function to determine how much space was left before the stack collided with the heap. This routine could not be called at interrupt time, but was useful for preventing heap corruption in code using recursion or deep call chains. But, since a Carbon application may have different stack sizes under Mac OS 8 and Mac OS X, the StackSpace function is no longer very useful. You should not rely on it for your logic to terminate a recursive function. It might still be useful as a safety check to prevent heap corruption, but for terminating runaway recursion you should consider passing a counter or the address of a stack local variable instead of calling StackSpace.

The Carbon API does not include any subzone creation or manipulation routines. If you use subzones today to track Toolbox or plug-in memory allocations, you will have to use a different mechanism. For plug-ins, you might switch to using your own allocator routines. To prevent leaks of Toolbox data, make sure all Toolbox allocations are matched with the appropriate dispose calls.

The Carbon API also removes the definition of zone headers. You no longer can modify the variables in a zone header to change the behavior of Toolbox routines like MoreMasters. Simply call MoreMasters multiple times instead, which will allocate 128 master pointers each time.

Summary

Everything you do now to make your application run great on Mac OS 8 is a step toward Carbon compatibility. Adopting the Appearance Manager, Navigation Services, and Open Transport is a great way to start. And by following the steps outlined in this article, your transition to Carbon will be that much easier.

While it has been our experience that a typical application can be "Carbonized" in a couple of weeks, a lot depends on how zealously you have followed Apple's programming recommendations in the past. If you have not cracked a copy of Inside Macintosh in a couple of years, or do not remember the last time you synchronized with Apple's latest header release, it might take you a bit longer to whip your code into shape. All the more reason to get started early!


Dave Evans is an engineer on the Carbon team and Mark Turner is a technical writer at Apple Computer.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

LibreOffice 4.4.1.2 - Free, open-source...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
Freeway Pro 7.0.3 - Drag-and-drop Web de...
Freeway Pro lets you build websites with speed and precision... without writing a line of code! With its user-oriented drag-and-drop interface, Freeway Pro helps you piece together the website of... Read more
Cloud 3.3.0 - File sharing from your men...
Cloud is simple file sharing for the Mac. Drag a file from your Mac to the CloudApp icon in the menubar and we take care of the rest. A link to the file will automatically be copied to your clipboard... Read more
Cyberduck 4.6.5 - FTP and SFTP browser....
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
Firefox 36.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals and... Read more
Thunderbird 31.5.0 - Email client from M...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more
VOX 2.4 - Music player that supports man...
VoxIt just sounds better! The beauty is in its simplicity, yet behind the minimal exterior lies a powerful music player with a ton of features & support for all audio formats you should ever need... Read more
A Better Finder Rename 9.46 - File, phot...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more
WALTR 1.0.9 - Drag-and-drop any media fi...
WALTR is designed to make it easy to upload and convert any music or video file to an iPad or iPhone format for native playback. It supports a huge variety of media file types, including MP3, MP4,... Read more
Default Folder X 4.6.14 - Enhances Open...
Default Folder X attaches a toolbar to the right side of the Open and Save dialogs in any OS X-native application. The toolbar gives you fast access to various folders and commands. You just click on... Read more

Check Out the Trailer for the Upcoming F...
Check Out the Trailer for the Upcoming FINAL FANTASY: Record Keeper Posted by Jessica Fisher on February 26th, 2015 [ permalink ] DeNA and Square Enix have announced that | Read more »
Legacy Quest is an Upcoming Rouge-like T...
Legacy Quest is an Upcoming Rouge-like That’ll Kill the Whole Family Posted by Jessica Fisher on February 26th, 2015 [ permalink ] Nexon Co. | Read more »
Grudgeball: Enter the Chaosphere Review
Grudgeball: Enter the Chaosphere Review By Jordan Minor on February 26th, 2015 Our Rating: :: MUSCLE MENUniversal App - Designed for iPhone and iPad Regular Show gets an above average game.   | Read more »
Action RPG League of Angels – Fire Raide...
Gaia is being invaded by the Devil Prince and the demonic Devil Army at his disposal, and it’s up to you and your avatar to defeat him in League of Angels – Fire Raiders. Raise a mighty army from hundreds of recruitable angel heroes and take the... | Read more »
Burn Rubber on the Ice With a New Cars:...
Burn Rubber on the Ice With a New Cars: Fast as Lightning Update Posted by Jessica Fisher on February 26th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
AdVenture Capitalist Review
AdVenture Capitalist Review By Jordan Minor on February 26th, 2015 Our Rating: :: DAS KAPITALUniversal App - Designed for iPhone and iPad An inadvertent Marxist manifesto.   | Read more »
Monster vs Sheep Review
Monster vs Sheep Review By Jennifer Allen on February 25th, 2015 Our Rating: :: SAMEY FUNUniversal App - Designed for iPhone and iPad What Monster vs Sheep lacks in variety it makes up for with stress relieving fun. At least, for a... | Read more »
Is Your Face Ready for the New Outwitter...
Is Your Face Ready for the New Outwitters 2.0 Trailer? Posted by Jessica Fisher on February 25th, 2015 [ permalink ] One Man Left Studios has announced that their turn-based strategy game, | Read more »
HowToFormat Review
HowToFormat Review By Jennifer Allen on February 25th, 2015 Our Rating: :: USEFUL TIPSiPhone App - Designed for the iPhone, compatible with the iPad Making a presentation and want to get it just right? HowToFormat teaches you how... | Read more »
Thermo Diem Review
Thermo Diem Review By Jennifer Allen on February 25th, 2015 Our Rating: :: GETS TO THE POINTUniversal App - Designed for iPhone and iPad Want to know whether it’s warmer or colder tomorrow? That’s precisely what Thermo Diem will... | Read more »

Price Scanner via MacPrices.net

New Travel Health App “My Travel Health” iOS...
Rochester, Minnesota based Travel Health and Wellness LLC has announced that its new iOS app help safeguard the user’s health when traveling abroad — “My Travel Health” is now available on the Apple... Read more
Sale! MacBook Airs for up to $115 off MSRP
B&H Photo has MacBook Airs on sale for up to $100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 11″ 128GB MacBook Air: $799 100 off MSRP - 11″ 256GB MacBook Air: $999 $100... Read more
15-inch 2.0GHz Retina MacBook Pro (refurbishe...
The Apple Store has Apple Certified Refurbished previous-generation 15″ 2.0GHz Retina MacBook Pros available for $1489 including free shipping plus Apple’s standard one-year warranty. Their price is... Read more
Wither The iPad mini? End Of The Road Imminen...
AppleDailyReport’s Dennis Sellers predicts that the iPad mini is going to be left to wither on the vine, as it were, and then just allowed to fade away — a casualty of the IPhone 6 Plus and other... Read more
Android and iOS Duopoly Owns 96.3% of Smartph...
IDC reports that Android and iOS inched closer to total domination of the worldwide smartphone market in both the fourth quarter (4Q14) and the calendar year 2014 (CY14). According to data from the... Read more
13-inch 2.4GHz Retina MacBook Pro available f...
MacMall has the 2013 13″ 2.4GHz/128GB Retina MacBook Pro available for $999.99 for a limited time. Shipping is free. Their price is $300 off original MSRP, and it’s the only sub-$1000 new Retina... Read more
Save up to $300 on a new Mac, $30 on an iPad,...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Mac minis available for up to $75 off MSRP
MacMall has Mac minis on sale for up to $75 off MSRP including free shipping. Their prices are the lowest available for these models from any reseller: - 1.4GHz Mac mini: $459.99 $40 off - 2.6GHz Mac... Read more
WaterField Unveils Versatile Padded Gear Pouc...
San Francisco manufacturer WaterField Design’s new Padded Gear Pouch is a light and handy-sized, yet protective, organizer for every kind of take-along gear: technology, travel, toiletries,... Read more
College Student Deals: Additional $50 off Mac...
Take an additional $50 off all MacBooks and iMacs at Best Buy Online with their College Students Deals Savings, valid through April 11, 2015. Anyone with a valid .EDU email address can take advantage... Read more

Jobs Board

*Apple* Solutions Consultant - Retail Sales...
**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 - 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* 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
*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
Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.