TweetFollow Us on Twitter

Pascal Man Submerges Self in MacApp 3

Pascal Man Submerges Self in MacApp 3

Jesse Feiler

Jesse Feiler knows that Elvis lives-in Michigan-and that he's busy writing MacApp software. Perhaps any Pascal programmer can reach this level of mental acuity just by writing a small application in MacApp 3. See for yourself-follow Feiler, prior Pascal programmer, as he is baptized by total immersion into a new life of C++.

This article relates the travails of a Pascal programmer who learned C++-the why, the how, and the wherefore. In spite of all the words that have been written and shouted in the language wars, perhaps this will add something to the conversation and help those who follow a similar path to MacApp 3.

Into the comfort zone

It took two weeks for me to feel comfortable with the C++ language. That meant being able to write code that compiled the first time (or the second time), and did what I expected it to do. That also meant knowing enough about the language's capabilities to know what constructs were appropriate in various places-even though I had to look up the syntax for those constructs in the manuals (as I still do in Pascal).

While I was learning C++, a colleague working on the same project was learning both MacApp and C++ (he knew Pascal). We both felt MacApp was much more important and difficult to learn. In terms of designing an application, knowing the MacApp classes and methods provides far more advantage than knowing C++ or Pascal.

Although I will return to these points below, it is important to note two things. First, I didn't need to learn C++ to program with MacApp 3. Second, I was able to read and understand MacApp 3 code from the beginning-but only with the assistance of MacsBug and my prior knowledge of MacApp. If you've ever cuddled up in bed with the MacApp source code on a cold winter night (yecch!), I'm sure you'll agree that you could probably understand DoMenuCommand even if it were written in an Urdu derivative of BASIC.

An assuaged concern

Along the way I learned that C++ is a more disciplined language than C, and many of my complaints about C are answered in C++. One indication is this section from the MPW C++ Appendix E: MPW C++ Style Guide:
    "It's possible to partially circumvent the strong type checking C++ imposes on function arguments. You should avoid doing this if at all possible. C++, like ANSI C, allows you to cling to C's past by declaring functions that take unspecified numbers and types of arguments, the classic being…"

Obviously, the sort of undisciplined code I associated with C is discouraged in C++.

Pride and prejudice

I've been programming in Pascal and in its direct antecedent, ALGOL, for over 20 years. I know the language very well. I've programmed, taught it, and designed systems based around the language and stack based machines.

As a manager, I've also formed a few opinions about languages. I don't present these as facts, merely as personal prejudices. Here are some of them:

  • People who are taught programming using Pascal tend to make better programmers than people who are taught with other languages. Not surprising, since Pascal was designed as a teaching language. Pascal-taught programmers can in general be relied upon to be better programmers no matter what their ultimate language is-even if it is COBOL.
  • C programmers can be sloppy and careless. This prejudice arose from noticing that C programmers learning Pascal seemed to rebel at Pascal's rigid type declarations and lack of automatic coercion.
  • Good programmers can write good programs in any language.
  • Bad programmers can write worse programs in BASIC and C than in other languages.
  • C seemed to have been designed for people who can't type, since strange symbols seem to substitute for words which I relate to better (like "begin" and "end").
  • As sort of a corollary, C is hard to read aloud.

As you may realize from this list, in my own work, I stuck to Pascal. When I subscribed to ETO, the one piece of the puzzle I had to buy was C++, so I did. I never installed it, and didn't even look at the documentation. And when it was announced that MacApp 3 would be written in C++, I didn't feel that the world was coming to an end, since everyone stressed that we'd still be able to use Pascal for our applications.

Then the language war broke out. As noted in the sidebar accompanying this article, our language war was a bush-league event. Still, as my kilobyte charges on AppleLink kept increasing, I began to get more curious.

On the sidelines

Despite the prejudices outlined above, I didn't feel qualified to participate in the language wars (and even had trouble understanding some of the terms), since I didn't know C++. I looked at the documentation I had on the shelf, and decided that the several hundred pages involved were too much of an investment to make at that time. I bought the two Addison Wesley books-Elements of C++ Macintosh Programming and C++ Programming with MacApp-and browsed through them. Eric Berdahl's articles in FrameWorks were also very interesting, but I didn't feel that I knew much yet.

Then a new project came up, and I decided to implement it not only with MacApp 3 but to use C++ as well. I used C++ on this project in order to find out enough about C++ to take a side in the language wars. You don't have to use C++ in order to use MacApp 3. I only learned C++ to find out what the fuss was about.

LEARNING C++

I used the total immersion principle, now commonly used for teaching natural languages, to learn C++. I didn't worry about the theory or the background. I put myself in a position where I had to use the language and-most important-where it was not unreasonable for me to be able to use the language.

While this technique (if you want to dignify it with that term) was an ad hoc, idiosyncratic approach, some of the things I did may be useful to others. The steps I took had the virtues of getting me up to speed in two weeks and getting an application that uses MacApp 3 and C++ into a basic shape in four weeks.

A small, new project

Having the right project to try this with was the most crucial requirement. We were lucky; a new project came along that was small, with a flexible deadline, so a bit of experimentation seemed reasonable. Still, I didn't know where to start. I designed my basic MacApp objects and their methods, then sat at the computer and wondered what to do next.

Implement the basic shell with familiar tools

While I was cogitating, I realized an important design meeting was coming up and I needed the shell of the application so we could talk about menu items and get the artists started on the graphics (of which there were to be many). In half a day, I put up the shell using Pascal and MacApp 2. At least I knew how to do that, and it gave us enough to discuss and get the artists started.

Automatically convert to "C++"

Using the MPW PascalToCPlus tool, I converted the Pascal files to whatever it was that came out the back end of the tool. I looked at it, but wasn't sure I could recognize it as any computer language at all. I also installed MacApp 3 and compiled the libraries and the Nothing sample. (For newcomers to MacApp, the compilation of Nothing is part of the normal routine. Compiling Nothing after installing MacApp confirms that your libraries are all in the right places and that MacApp itself is undamaged.) Then I turned to the "code" that was output by the PascalToCPlus tool.

The advantage of this approach was that I had the structure of my still tiny application visible to me, and I had at least pseudo-C++ code generated by the PascalToCPlus tool.

The PascalToCPlus tool is a good start, but the new P2CPlus tool distributed with MacApp 3.0b1 (on ETO 5) is far superior. Also of help is the "cheat sheet" located in the tools folder of MacApp 3.0b1. It contains samples of failure handling code, switch statements, and comparisons of Pascal and C++ common words and phrases.

Compile and laugh-or cry

I tried compiling. Boy, did I get errors! While I found my reference books to be of some help, the most powerful tool at this point was MacBrowse. If I had an error in DoSetupMenus, I looked at TApplication->DoSetupMenus. I tried to find similar code to what I needed, and just copied it in. I didn't try to figure out what every "->", "::", and "&" meant.

If I couldn't find clues from MacApp itself, the next easiest way to get rid of errors was to simply comment out the offending lines. Since the application at this point did little except put up its menu bar, removing code didn't decrease its functionality very much.

I found two MacApp 3 documents to be critical: "Release Notes" and "Conversion Notes." They are included in the MacApp 3 documentation on ETO, and have been updated with new releases of MacApp.

As I started to compile, I started learning very fast. Here is the fruit of my labors-may they help others to make fruit salad, to go with Eric Berdahl's soup.

The pascal programmer's guide to C++ compile errors

The C++ compiler (technically, the CFront tool), is a two-pass compiler. Those of us who are used to MPW's single-pass Pascal compiler need to get used to a two-pass compiler.

With a two-pass compiler, it's important to remember that errors are not necessarily emitted in the order they occur in the source file. Since compilers frequently generate errors on lines other than those where the actual errors occur (such as when quotes are mismatched), this can make debugging harder. Also, some syntax that is legal in Pascal is lethal in C++.

Herewith, a few of our more common errors. They are described along with the compile errors they generate and their most common cause-which is not necessarily related to what the compiler thinks is the problem!

These errors are the most common problems we've experienced that are not immediately caught and presented in an intuitive way by the C++ compiler. They're not to be interpreted as complaints about the C++ compiler, or about the Pascal compiler, or about the languages themselves. They are just the traps we hit most often. Some of them may hit any novice C++ programmer; others (like the absence of the word "case", below) are more likely to hit Pascal programmers because the two languages share similar syntax.

Switch and case statements

It's not too hard to adjust to C++'s case syntax:
switch (selection)
    {   
    case x:
            …
            break;
    case y:
            …
            break;
    default:
            …
            break;
    };

If you revert to Pascal case syntax, you'll get compile errors and know to fix them. But two important things may confuse the compiler. If the word "case" is missing, then "x" and "y" above are interpreted as labels. An error is generated-usually at the beginning of the function, that says:

# warning: label cAddSequenceComponent not used

Since we rarely use labels and often use case and switch statements, we've found this message almost always means a missing "case" in a switch statement.

A more dangerous trap is that "break" is required to get out of the switch statement. Without it, the subsequent lines of code are executed. While this allows some neat programming, it's not something we're used to, and it doesn't generate a warning or error message.

Headers are sensitive

It's important to remember that CFront is a much younger product than the Pascal compiler. Not only is the Pascal compiler more stable; many of us know it very well. (This doesn't mean one is better than the other. If I had found CFront so unstable as to be unusable, we would have completed the project in Pascal, and that would have been the end of that.)

All compilers are prone to conniption fits in their headers or interfaces. (Try leaving "USES" out of a Pascal interface file!) CFront is particularly unhappy with misspellings. In order to declare a constant, you can type:

const short i = 2;

Try typing:

cosnt short i = 2; //s-n reversed

…and you'll get:

line 35 # error: syntax error
line 36 # error: syntax error
line 36 # error: argument type expected for AddDependent()
line 37 # error: syntax error
line 37 # error: syntax error
line 37 # error: syntax error
line 37 # error: argument type expected for Insert()

Needless to say, line 35 is several lines beyond the const declaration. When the C++ compiler gives up the ghost and gives you the plain unvarnished "syntax error," we've gotten used to poring over code before the line in question, hoping to find a typo.

"If" statements may change a variable's value!

This is a double-whammy. First of all, the expression of an if statement must be enclosed in parenthesis. This isn't really a problem for most programmers. More tricky is the fact that in both Pascal and C++, the equality operator and replacement operator are different symbols- and they don't match up!

OPERATOR C++ PASCAL

replacement    =   :=
equality       ==  =

Thus, the phrase:

a=b

is a boolean expression in Pascal and a replacement operation in C++. The fun arrives when you code the following in C++:

if (a=b)

To a Pascal programmer, the code looks perfectly correct, and hours (trust me!) can be spent tracking down why the program executes strangely. As a result, Pascal programmers have to spend extra attention to if statements until they get them under their skin.

Missing "()" may generate an error

Another common Pascal programmer's error is forgetting that C++ functions always take some parameters (unless void is specifically meant). Since we're not used to this, we're quite capable of writing something like:
aSummaryView = aComponent->CreateSummaryView;

To a Pascal programmer, this looks pretty decent. Unfortunately, you will not call the CreateSummaryView(void) function and, in this case, you'll get the error:

 line 75 # error: bad assignment type:
                 TView * = pascal TView *TComponent:: ()

…or missing "()" may generate a warning

More insidious is the case where a function is called and doesn't return a result which the compiler could check:
aWindow->Open

instead of:

aWindow->Open();

will produce:

line 86 # warning: result of -> expression not used

This is a warning, not a compile error, so you'll be able to link, and run, and tear your hair out as a result of making the error and ignoring the warning. By now we know: this message means missing "()".

Missing "*" will generate an error

Types must be declared as pointers-that is, with a "*" following their name. Declaring:
TView aView

instead of:

TView* aView

gives these errors:

line 61 # error: can't declare a handle/pascal object: aSummaryView
line 75 # error: bad argument list for TView::TView() 
                     (no match against any TView::TView())
line 81 # error: non pointer -> Locate

Again, this is a fairly common mistake for Pascal programmers, because the "*" isn't something we usually worry about. So, translate "can't declare a handle/pascal object" to "missing *" and don't worry about what the message means. [1]

Missing ";" will generate an error

Both the Pascal and C++ compilers have quirks with respect to their header or interface files and implementation or definition files. In Pascal, the word "override" is optional in the implementation file, but the semicolon following the word "override" is optional in the interface file. This is of little import to most programmers, since we tend to use cut and paste to duplicate the interface and implementation code for a procedure heading.

In C++, however, cut and paste can't be used, since the semicolon at the end of the function definition (i.e., interface) is required, and a semicolon at the end of the function declaration (i.e., implementation) is forbidden.

As with most header or interface errors in all compilers, errors in this area can cause nasty results. Omitting the semicolon after the definition in the header file will generate a small novel of the following sort:

line 70 # error: syntax error: unexpected pascal
                                        (did you forget a `;'?)
line 70 # error: function declared as both pascal and non-pascal
line 41 # error: function declared as both pascal and non-pascal

In our experience, the first (and most welcome) message, suggesting the missing semicolon, is not reliably produced. The giveaway to the missing semicolon is more often the error "function declared as both pascal and non-pascal." Note the non-sequential error messages, with line 41's message following the messages for line 70. This is typical of two-pass compilers. Also of interest is the fact that this group of error messages was generated by one missing semicolon-and that was on line 70. Line 41 is the beginning of the class definition.

Extra ";" will generate an error

The companion error, that of including a semicolon after the first line of the function definition, generates a similar bevy of error messages:
line 229 # error: qualified name THEComponent::
GetControlParms() in function declaration
line 230 # error: syntax error
line 237 # error: syntax error
line 237 # error: function declared as both pascal and non-pascal
line 237 # error: two different return value types for TickCount():
unsigned long and int 
line 239 # error: syntax error
line 239 # error: syntax error
line 239 # error: syntax error
line 240 # error: syntax error
line 241 # error: syntax error
line 241 # error: anachronism `.' used for qualification; 
please use `::'
line 241 # error: bad qualifier fi for Try()
line 310 # error: syntax error
line 311 # error: syntax error

As in all cases where a compiler has gone off the deep end, errors multiply, generating more and more esoteric (and incorrect) messages. In our experience, the words "qualified name <> in function declaration" are the tip-off to the extra semicolon.

Hide and seek

C++ lets you overload its functions, allowing alternate arguments to be used to the same function. Most often, Pascal programmers overload functions by accident. The compiler is nice enough to warn you when this happens:
warning: TCommComponent::HandleMouseUp() hides virtual 
TView::HandleMouseUp()

Unless you really meant to overload the function, check the definition of your function and its ancestor's for differences in spelling, type, and number of arguments. Of course, if you meant to overload the function, ignore the warning.

Heed my warning!

One final note: read both the warnings and the error messages! While any compiler will sometimes throw up its hands and simply tell you "syntax error" and a line number, more often it will give you a specific message and a line number. Too many programmers go to the line given, but ignore the message.

Warnings are easy to ignore, since they don't stop the compilation process. But compilers rarely emit warnings that should go unheeded. As noted above, some of the errors Pascal programmers are likely to make in C++ will only generate warnings. So it's a good idea, one way or another, to eliminate warnings from your compilation.

YOU'VE GOT TO HAVE IT

MacBrowse (formerly Mouser) in an essential tool for learning C++. It is a fast way to analyze the body of C++ source code that every MacApp programmer has access to-the MacApp source code itself.

SourceBug provides line-by-line tracing of program execution. This is crucial for debugging- particularly in cases where control of execution goes in places where it's not expected to.

MAMake deserves to be mentioned because the dependencies in your MAMake file have to be absolutely correct (as indeed they should be with Pascal). Unfortunately, since C++ assumes that you may want to overload functions and change their parameters, some of the typos that the Pascal compiler would catch are treated by C++ as conscious, deliberate choices. So, in a back-handed way, the Pascal compiler catches some MAMake errors that the C++ compiler won't.

Hard copy? Hundreds of pages have been written about C++ and MacApp. The most useful, in my opinion, is Appendix E of the MPW C++ reference, entitled "MPW C++ Style Guide." In 35 pages, the essentials of C++ programming are set forth. It's not a tutorial; it's the sort of thing that's helpful in this kind of total immersion learning. It isn't theoretical and analytic; if you want to know why things work the way they do, consult the other (excellent) reference materials, including those mentioned above.

A surprising comfort level

It surprised me a great deal, but I felt comfortable with C++ after only two weeks. I found that the choice of object oriented programming in general and MacApp in particular is far more critical than the choice between Pascal and C++. And I'm pleasantly surprised at some of the rigor that C++ can enforce. Private members, for instance, are definitely a good thing.

C++'s flexibility does allow typos to pass into compiled code a little more easily than in Pascal. But on the whole, while I realize there are critical differences between Pascal and C++- particularly when you examine how the languages actually run-from a user's point of view, both seem to serve well for implementing MacApp applications.

While my "total immersion" method may not work for everyone, I do think it's worth a try. Its prime advantage, at least to one who is as untheoretical as I am, is that it causes you to spend your time developing software rather than discussing it or reading about it.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

TinkerTool 5.4 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Tinderbox 6.3.1 - Store and organize you...
Tinderbox is a personal content management assistant. It stores your notes, ideas, and plans. It can help you organize and understand them. And Tinderbox helps you share ideas through Web journals... Read more
Parallels Desktop 10.2.2 - Run Windows a...
Parallels Desktop is simply the world's bestselling, top-rated, and most trusted solution for running Windows applications on your Mac. With Parallels Desktop for Mac, you can seamlessly run both... Read more
Adobe Premiere Pro CC 2015 9.0.1 - Digit...
Premiere Pro CC 2015 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Premiere Pro customer). Premiere Pro CS6 is still available for... Read more
Adobe After Effects CC 2015 13.5.1 - Cre...
After Effects CC 2015 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous After Effects customer). After Effects CS6 is still available... Read more
Adobe Creative Cloud 2.2.0.129 - Access...
Adobe Creative Cloud costs $49.99/month (or less if you're a previous Creative Suite customer). Creative Suite 6 is still available for purchase (without a monthly plan) if you prefer. Introducing... Read more
Tower 2.2.3 - Version control with Git m...
Tower is a powerful Git client for OS X that makes using Git easy and more efficient. Users benefit from its elegant and comprehensive interface and a feature set that lets them enjoy the full power... Read more
Apple Java 2015-001 - For OS X 10.7, 10....
Apple Java for OS X 2015-001 installs the legacy Java 6 runtime for OS X 10.11 El Capitan, OS X 10.10 Yosemite, OS X 10.9 Mavericks, OS X 10.8 Mountain Lion, and OS X 10.7 Lion. This package is... Read more
Adobe Muse CC 2015 2015.0.1 - Design and...
Muse CC 2015 is available as part of Adobe Creative Cloud for as little as $14.99/month (or $9.99/month if you're a previous Muse customer). Muse CS6 is still available for purchase (without a... Read more
Adobe Illustrator CC 2015 19.1.0 - Profe...
Illustrator CC 2015 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Illustrator customer). Illustrator CS6 is still available for... Read more

Tap Delay (Music)
Tap Delay 1.0.0 Device: iOS Universal Category: Music Price: $4.99, Version: 1.0.0 (iTunes) Description: Back in the “old days”, producers and engineers created delay and echo effects using tape machines. Tap Delay combines the warm... | Read more »
This Week at 148Apps: July 20-24, 2015
July is Heating Up With 148Apps How do you know what apps are worth your time and money? Just look to the review team at 148Apps. We sort through the chaos and find the apps you're looking for. The ones we love become Editor’s Choice, standing out... | Read more »
Red Game Without A Great Name (Games)
Red Game Without A Great Name 1.0.3 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.3 (iTunes) Description: The mechanical bird is flying through an unfriendly, Steampunk world. Help it avoid obstacles and deadly... | Read more »
Warhammer: Arcane Magic (Games)
Warhammer: Arcane Magic 1.0.2 Device: iOS Universal Category: Games Price: $9.99, Version: 1.0.2 (iTunes) Description: Engage in epic battles and tactical gameplay that challenge both novice and veteran in Warhammer: Arcane Magic, a... | Read more »
Mazes of Karradash (Games)
Mazes of Karradash 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The city of Karradash is under attack: the monsters of the Shadow Realms are emerging from the depths.No adventurer is... | Read more »
Battle Golf is the Newest Game from the...
Wrassling was a pretty weird - and equally great - little wressling game. Now the developers, Folmer Kelly and Colin Lane, have turned their attention to a different sport: golfing. This is gonna be weird. [Read more] | Read more »
Qbert Rebooted has the App Store Going...
The weird little orange... whatever... is back, mostly thanks to that movie which shall remain nameless (you know the one). But anyway it's been "rebooted" and now you can play the fancy-looking Qbert Rebooted on iOS devices. [Read more] | Read more »
Giant Monsters Run Amok in The Sandbox...
So The Sandbox has just hit version number 1.99987 (seriously), and it's added a lot more stuff. Just like every other update, really. [Read more] | Read more »
Fish Pond Park (Games)
Fish Pond Park 1.0.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.0 (iTunes) Description: Nurture an idyllic slice of tourist's heaven into the top nature spot of the nation, furnishing it with a variety of... | Read more »
Look after Baby Buddy on your Apple Watc...
Parigami Gold is the new premium version of the match three puzzler that includes Apple Watch support and all new content. You won't simply be sliding tiles around on your wrist, the Apple Watch companion app is an all new mini-game in itself. You'... | Read more »

Price Scanner via MacPrices.net

2.8GHz Mac mini available for $988, includes...
Adorama has the 2.8GHz Mac mini available for $988, $11 off MSRP, including a free copy of Apple’s 3-Year AppleCare Protection Plan. Shipping is free, and Adorama charges sales tax in NY & NJ... Read more
Sale! 13″ 1.6GHz/256GB MacBook Air for $1099,...
B&H Photo has the 13″ 1.6GHz/256GB MacBook Air on sale for $1099 including free shipping plus NY tax only. Their price is $100 off MSRP, and it’s the lowest price available for this model. Read more
iPad mini 4 To Be Upgraded To iPad Air 2 Spec...
There’s a certain inevitability about making Apple product predictions this time of year. Come September, we can pretty reliably count on the release of refreshed iPhones, along with the iOS 9... Read more
Apple restocks refurbished Mac minis for up t...
The Apple Store has restocked Apple Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz... Read more
13-inch 2.5GHz MacBook Pro on sale for $899,...
Best Buy has the 13″ 2.5GHz MacBook Pro available for $899.99 on their online store. Choose free shipping or free instant local store pickup (if available). Their price is $200 off MSRP. Price is... Read more
21-inch 2.9GHz iMac on sale for $1299, save $...
Best Buy has the 21″ 2.9GHz iMac on sale today for $1299.99 on their online store. Choose free shipping or free local store pickup (if available). Their price is $200 off MSRP, and it’s the lowest... Read more
Free Image Sizer 1.3 for iOS Offers Photo Edi...
Xi’An, China based G-Power has announced the release of Image Sizer 1.3 for the iPhone, iPad, and iPod touch, an important update to their free photo editing app. Image Sizer’s collection of easy to... Read more
Sale! 13″ 1.6GHz/128GB MacBook Air for $899,...
B&H Photo has the 13″ 1.6GHz/128GB MacBook Air on sale for $899 including free shipping plus NY tax only. Their price is $100 off MSRP, and it’s the lowest price available for this model. Read more
13-inch Retina MacBook Pros on sale for $100...
Best Buy has 13-inch Retina MacBook Pros on sale for $100 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Prices are for online orders only, in-store... Read more
Will BMW’s i3 Electric Vehicle Be The Automo...
The German-language business journal Manager Magazin’s Michael Freitag reports that Apple and the German performance/luxury automaker Bayerishe Motoren Werke (BMW) are back at far-reaching... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales. Specialist - Retail Customer Service and Sales. Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Customer Experience (ACE) Leader - A...
…management to deliver on business objectives Training partner store staff on Apple products, services, and merchandising guidelines Coaching partner store staff on Read more
Project Manager - *Apple* Pay Security - Ap...
**Job Summary** The Apple Pay Security team is seeking a highly organized, results-driven Project Manager to drive the development of Apple Pay Security. If you are Read more
*Apple* TV Product Design Internship (Spring...
…the mechanical design effort associated with creating world-class products with the Apple TV PD Group. Responsibilities will include working closely with manufacturing, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.