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.

 
AAPL
$501.11
Apple Inc.
+2.43
MSFT
$34.64
Microsoft Corpora
+0.15
GOOG
$898.03
Google Inc.
+16.02

MacTech Search:
Community Search:

Software Updates via MacUpdate

Paperless 2.3.1 - Digital documents mana...
Paperless is a digital documents manager. Remember when everyone talked about how we would soon be a paperless society? Now it seems like we use paper more than ever. Let's face it - we need and we... Read more
Apple HP Printer Drivers 2.16.1 - For OS...
Apple HP Printer Drivers includes the latest HP printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.16.1: This... Read more
Yep 3.5.1 - Organize and manage all your...
Yep is a document organization and management tool. Like iTunes for music or iPhoto for photos, Yep lets you search and view your documents in a comfortable interface, while offering the ability to... Read more
Apple Canon Laser Printer Drivers 2.11 -...
Apple Canon Laser Printer Drivers is the latest Canon Laser printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.11... Read more
Apple Java for Mac OS X 10.6 Update 17 -...
Apple Java for Mac OS X 10.6 delivers improved security, reliability, and compatibility by updating Java SE 6.Version Update 17: Java for Mac OS X 10.6 Update 17 delivers improved security,... Read more
Arq 3.3 - Online backup (requires Amazon...
Arq is online backup for the Mac using Amazon S3 and Amazon Glacier. It backs-up and faithfully restores all the special metadata of Mac files that other products don't, including resource forks,... Read more
Apple Java 2013-005 - For OS X 10.7 and...
Apple Java for OS X 2013-005 delivers improved security, reliability, and compatibility by updating Java SE 6 to 1.6.0_65. On systems that have not already installed Java for OS X 2012-006, this... Read more
DEVONthink Pro 2.7 - Knowledge base, inf...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
VirtualBox 4.3.0 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more
Merlin 2.9.2 - Project management softwa...
Merlin is the only native network-based collaborative Project Management solution for Mac OS X. This version offers many features propelling Merlin to the top of Mac OS X professional project... Read more

Briquid Gets Updated with New Undo Butto...
Briquid Gets Updated with New Undo Button, Achievements, and Leaderboards, on Sale for $0.99 Posted by Andrew Stevens on October 16th, 2013 [ | Read more »
Halloween – iLovecraft Brings Frightenin...
Halloween – iLovecraft Brings Frightening Stories From Author H.P. | Read more »
The Blockheads Creator David Frampton Gi...
The Blockheads Creator David Frampton Gives a Postmortem on the Creation Process of the Game Posted by Andrew Stevens on October 16th, 2013 [ permalink ] Hey, a | Read more »
Sorcery! Enhances the Gameplay in Latest...
Sorcery! | Read more »
It Came From Australia: Tiny Death Star
NimbleBit and Disney have teamed up to make Star Wars: Tiny Death Star, a Star Wars take on Tiny Tower. Right now, the game is in testing in Australia (you will never find a more wretched hive of scum and villainy) but we were able to sneak past... | Read more »
FIST OF AWESOME Review
FIST OF AWESOME Review By Rob Rich on October 16th, 2013 Our Rating: :: TALK TO THE FISTUniversal App - Designed for iPhone and iPad A totalitarian society of bears is only the tip of the iceberg in this throwback brawler.   | Read more »
PROVERBidioms Paints English Sayings in...
PROVERBidioms Paints English Sayings in a Picture for Users to Find Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
OmniFocus 2 for iPhone Review
OmniFocus 2 for iPhone Review By Carter Dotson on October 16th, 2013 Our Rating: :: OMNIPOTENTiPhone App - Designed for the iPhone, compatible with the iPad OmniFocus 2 for iPhone is a task management app for people who absolutely... | Read more »
Ingress – Google’s Augmented-Reality Gam...
Ingress – Google’s Augmented-Reality Game to Make its Way to iOS Next Year Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
CSR Classics is Full of Ridiculously Pre...
CSR Classics is Full of Ridiculously Pretty Classic Automobiles Posted by Rob Rich on October 16th, 2013 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Apple Store Canada offers refurbished 11-inch...
 The Apple Store Canada has Apple Certified Refurbished 2013 11″ MacBook Airs available starting at CDN$ 849. Save up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
Updated MacBook Price Trackers
We’ve updated our MacBook Price Trackers with the latest information on prices, bundles, and availability on MacBook Airs, MacBook Pros, and the MacBook Pros with Retina Displays from Apple’s... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has the 13″ 2.5GHz Retina MacBook Pro on sale for $1399 including free shipping. Their price is $100 off MSRP. They have the 13″ 2.6GHz Retina MacBook Pro on sale for $1580 which is $... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more
Apple’s 64-bit A7 Processor: One Step Closer...
PC Pro’s Darien Graham-Smith reported that Canonical founder and Ubuntu Linux creator Mark Shuttleworth believes Apple intends to follow Ubuntu’s lead and merge its desktop and mobile operating... Read more
MacBook Pro First, Followed By iPad At The En...
French site Info MacG’s Florian Innocente says he has received availability dates and order of arrival for the next MacBook Pro and the iPad from the same contact who had warned hom of the arrival of... Read more
Chart: iPad Value Decline From NextWorth
With every announcement of a new Apple device, serial upgraders begin selling off their previous models – driving down the resale value. So, with the Oct. 22 Apple announcement date approaching,... Read more
SOASTA Survey: What App Do You Check First in...
SOASTA Inc., the leader in cloud and mobile testing announced the results of its recent survey showing which mobile apps are popular with smartphone owners in major American markets. SOASTA’s survey... Read more
Apple, Samsung Reportedly Both Developing 12-...
Digitimes’ Aaron Lee and Joseph Tsai report that Apple and Samsung Electronics are said to both be planning to release 12-inch tablets, and that Apple is currently cooperating with Quanta Computer on... Read more
Apple’s 2011 MacBook Pro Lineup Suffering Fro...
Appleinsider’s Shane Cole says that owners of early-2011 15-inch and 17-inch MacBook Pros are reporting issues with those models’ discrete AMD graphics processors, which in some cases results in the... Read more

Jobs Board

Senior Mac / *Apple* Systems Engineer - 318...
318 Inc, a top provider of Apple solutions is seeking a new Senior Apple Systems Engineer to be based out of our Santa Monica, California location. We are a Read more
*Apple* Retail - Manager - Apple Inc. (Unite...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Solutions Consultant - Apple (United...
**Job Summary** Apple Solutions Consultant (ASC) - Retail Representatives Apple Solutions Consultants are trained by Apple on selling Apple -branded products Read more
Associate *Apple* Solutions Consultant - Ap...
**Job Summary** The Associate ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The Associate ASC's role is to Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.