TweetFollow Us on Twitter

MacApp Objects
Volume Number:3
Issue Number:9
Column Tag:MacApp Objects

Programming in the Closet

By David A. Wilson, Personal Concepts, Palo Alto, CA

or

“How to write a program without really writing a program”

Dave Wilson is the owner of Personal Concepts, a consulting firm specializing in software development for the Macintosh. He currently is teaching courses for Apple on both beginning Macintosh programming and object-oriented programming.

This article can be blamed on Howard Katz, who is the newsletter Editor for the MacApp Developer’s Association. Howard knew that I present four-day Seminars for Apple entitled MacApp™ and Object Oriented Programming , and thought that experiences from the first five of these seminars might be useful to others who are learning MacApp. Much of this article first appeared in the May 1987 issue of the MacAppDA’s newsletter, and is reprinted with their permission. I might add that you should definitely join us in the MacAppDA if you have an interest in object-oriented programming for the Macintosh. You can join by sending $15.00 to:

MacApp Developer’s Association

P.O. Box 23

Everett, WA 98206-0023.

First, some background to put the article in perspective. I have taught Apple’s beginning Macintosh Programming Seminars for the last two and one-half years, and have developed a healthy respect for the difficulties of writing Mac applications during this time. Starting about two years ago, I began to hear about this strange beast called MacApp that was claimed to make Mac programing relatively easy, so I got a copy to try out.

I didn’t begin seriously learning to use it until last Fall, when Apple agreed that a monthly Seminar was needed to help people get up to speed quickly on this new and powerful tool, so I started learning MacApp with more urgency. It took me about three man-months to feel comfortable with it, and the seminar is designed to fit as much of those experiences as possible into four days.

By the way, Apple also decided to provide a separate one-day seminar on Using MPW the day before each MacApp class, so we could cover Make files, Rez, etc. before worrying about MacApp itself. More about that below. By now you should be wondering if I am ever going to explain the weird title, so here goes

A History Lesson

A long, long time ago, in an operating system far, far away, applications programmers wrote code that directed the user along a certain path. As the programmer, you were clearly in control of what happened, so you gave orders to the user, and the user did what he or she was told. If the user did not follow orders, you displayed friendly error message such as “Syntax Error 5”, and hoped the user would shape up.

Then the Macintosh came along, and you were instructed to write friendly, “modeless” programs, with the operation controlled by the user. (Incidentally, humor writer Dave Barry defines “User” as the word that programmers use when they mean “idiot”). You wrote modeless programs by basing your application on a Main Event Loop. This had you calling the GetNextEvent ROM routine, and responding accordingly to events caused by the user. I liken this to programming in a room with the door closed. You can’t see the user, but when the user clicks the mouse down or types a key, the Event Manager slides a piece of paper under the door that contains the Event Record. You read the piece of paper, and respond accordingly.

Some programmers who are new to the Macintosh feel a bit nervous with this style because they don’t feel in control, but users certainly prefer it - because they are in control.

What happens with MacApp? It gets even worse. MacApp is an expandable generic application, consisting of hundreds of pages of Object Pascal source code written by some of Apple’s best programmers. All you have to do is customize the application through the special hooks provided by object-oriented programming, and, presto: you have your program!

Fig. 1 Getting into Objects in the Class Lab

Are you still all alone in the room, looking at pieces of paper slid under the door by the Event Manager? Uh-uh, MacApp is. Where are you? You are in the closet. Most of the time the program runs without needing your code at all, so MacApp will handle moving and resizing windows, operating scroll bars, opening Desk Accessories, etc. Once in a while MacApp needs you to do something specific to your program, so it opens the closet door, barks at you to “Draw yourself” or “Save the data to disk”, and then closes the door. You just do what your told, and stay out of the way the rest of the time.

With MacApp, you are no longer writing an applications program, but rather you are writing a few code fragments that customize the generic program written by Apple. Apple’s code runs the Main Event Loop, and does most of the event handling, so be sure to take a good book in the closet, because most of the time, you won’t have anything to do.

Your only problem will be in learning to use MacApp, and getting used to this new style of writing code. Which brings us

Back to the Seminars

Who takes these seminars? So far, we have had programmers from large corporations and universities, independent developers, Apple systems engineers, and Apple internal software developers. I expect to see many VARs (Value Added Resellers) and consultants during the next year - particularly as the powerful Macintosh II stimulates new interest in programming the Mac.

The MacApp seminar itself is a mixture of lectures and hands-on labs. We probably spend about 25% of the first two days programming, and perhaps 50% of the last two days. Each person has a Mac Plus with an HD-20 or HD-20SC with MPW and MacApp installed to use during class. We also provide some new sample programs and a 500-page Notebook.

The programming Labs begin with the Nothing program provided by Apple as a standard MacApp sample. You then add features to this program over the next four days until you have a text editor that, just for fun, can draw rectangles on top of the text. A palette controls part of the program’s operation, and the text and graphics can be saved to a document file on disk. This process is described in a 13-part exercise that you work on for the whole four days - at your own pace. The majority of people will not finish this project during class, but do leave with the “solution” on disk, so they can finish it on their own if they wish. A screen dump from the finished Lab is shown below in figure 1.

At this point, you might ask “Is MacApp easy to learn?”, and I would have to answer a definite “maybe”. Perhaps 25% of the students so far find that they are writing MacApp programs within four days. The other 75% find that they know much more about MacApp, but still feel that they need to invest more time on their own before they are ready to write a program. The major obstacle seems to be learning the new style and behavior of object-oriented programming, so people who have had experience with SmallTalk, Neon, Common LISP, etc. have a much easier time.

In the rest of this article, I’ll mention some of the common stumbling blocks, and suggest ways around them. This article will be most useful to you if you have already tried to learn MacApp on your own, and are having problems with understanding certain concepts. If you have never seen MPW or MacApp, you might want to read MacTutor’s introductory articles published in back issues first.

MPW

MPW (the Macintosh Programmer’s Workshop) seems to be easy for people to handle because of MacApp’s nifty MABuild command. There are a couple of things to keep in mind, however.

Remember to update your Make file when you use new building blocks (such as the text edit Unit UTEView), or new files containing resources (such as you might make with ResEdit). Otherwise, MABuild will not update everything properly if changes are made to these files.

MENU resources are not directly used in MacApp, so we instead need to use command menus, of resource type ‘cmnu’. These are easy to describe in a text file for Rez, as long as you can figure out which items to enable. The golden rule is that the least significant bit in the enable flag should be set to 1 to enable the first item in the menu, the next bit controls the second menu item, and so forth.

Object Oriented Programming

The major obstacles involve object-oriented programming(OOP), rather than Object Pascal or the MacApp libraries. Here are some of the common problems:

Program Design

Almost everyone has a hard time deciding which object types should be defined for the program that they wish to write. We spend a few hours in class on this subject, so I can’t make a simple answer here, but I’ll suggest a partial method to use (notice the great pun).

Step 1: Decide on what types of documents you need on disk. These will then correspond to your Document object types. For example, you might have text documents that will be displayed in windows, and Index documents that the user never manipulates, but that are used by data base access routines.

Step 2: Decide what views of your document’s data are to be shown in the windows. These will correspond to your View object types. For example, you might have a text view of your text document, a tabular view of some data base information, and a palette view that the user can use to control the program’s operation. Note that the palette view may not be associated with any specific document.

Step 3: Decide what data objects you need to manipulate. These might represent graphics objects, “customer” objects, or other objects that you might have formulated as Pascal Records in an earlier life. You still may decide to keep customer information in a record, but it is often better to create an Object Type, since you can then associate the methods that operate on the customer with the data about the customers.

INHERITED vs. SELF

A great strength of OOP is that we can Override a method, and substitute a new version of it with modified behavior. A common approach is to then reuse the old behavior in the new method by using the Object Pascal keyword INHERITED. This tells the program to use the ancestor’s method. Another common technique is for an object to call one of it’s own methods, using the optional keyword SELF.

That all sounds simple, but most people get confused as to when to call SELF.DoMenuCommand, and when to call INHERITED.DoMenuCommand, and in fact I have even been guilty of writing

INHERITED SELF.DoMenuCommand;

in my code. Not good. The rule to remember is that you use INHERITED to call a method of the ancestor to the object, while SELF refers to a method (or field) of the current object type.

Out of sight, out of mind

When you define an Object Type in the Interface of your Unit, you only define changes to the Object Type. Consider the example below:

TMyView = OBJECT(TView)
 TMyView.IMyView;
 TMyView.Draw(area:Rect); OVERRIDE;
 END;

This looks so simple that people often forget that an object of type TMyView also has all the fields and methods of TView, so that INHERITED Draw is definitely different than SELF.Draw. Furthermore, they forget that an object of type TMyView now has method IView in addition to method IMyView. It even has the method IEvtHandler that is inherited from the ancestor of TView.

This confusion leads to various strange things in people’s code, so remember that everything that we don’t override does get inherited from all the ancestors, including the ancestors of the immediate ancestors.

Fields that refer to other objects

A typical Interface might include the following:

TMyDocument = OBJECT(TDocument)
 fMyView: TMyView;
 TMyDocument.DoMakeViews; OVERRIDE;
 etc.

 TMyView = OBJECT(TView)
 fMyDocument: TMyDocument
 etc.

I find that people (a) often do not understand why they should include these cross-references, and (b) often forget to stuff correct values into these fields.

You should save a reference to an object so you can easily refer to a method or field of that object. You should then remember to initialize these fields with the proper values. If you do not, your program will crash into the MacApp interactive debugger with MacApp’s most common error, which is an ID = 03 crash. This usually means that your program is trying to use a field or method of an object that has an invalid address (i.e.,, an object reference that has never been initialized).

Inheritance Tree vs. Creation tree

Some people get confused about tree diagrams, since you may see more than one type. A typical inheritance diagram might look the one below, in figure 2, which means that TList, TCommand, and TEvtHandler each inherit all the fields and methods of TObject.

On the other hand, you might sometimes see a diagram that shows which objects create other objects, such as shown below in figure 3.

Fig. 2 Inheritance from TObject

Fig. 3 Objects from Objects

The confusion arises because people may think that the latter diagram represents property inheritance, rather than creation order. Remember, just because your application object creates your document objects does not imply that documents are descendents of applications.

Initialization methods

You need initialization methods to stuff correct values into the data fields of your object. This can be confusing because MacApp provides a number of initialization methods that you must call, but you usually also define some of your own. And, you should follow a certain style convention in doing this.

Consider defining a type of object TMyView that it a descendent of TView. That means that TMyView inherits an IView method. Now should you (1) use IView, (2) Override IView, or (3) define an new initialization method IMyView? The correct answers are “yes”, “no”, and “yes”. Let’s see why.

If your new Object Type has no new data fields to initialize, you may just want to use the following:

 New(aView):
 FailNil(aView);
 aView.IView( );

If your new Object Type does have data fields, you should not Override IView, but rather define a new method IMyView, and call IView from within that method. Why? Because if you keep IView and IMyView as separate methods, and never Override either one anywhere in your program, the compiler/linker can optimize them to be called as normal procedure calls rather than method calls. This will take place if you compile your program with the Optimize option turned on, and will improve performance and reduce overhead.

The MacApp Object Library

Managing all the goodies provided by MacApp.

We use a quick reference guide to MacApp when working in class, as an easier method to access all of MacApp Constants, Globals, fields, methods, etc. This Quick Reference is in the class Notebooks, but I will probably arrange for A.P.D.A. to distribute this so others can use it.

I also use a recipes file that contains sample Implementations to commonly used MacApp methods such as DoMenuCommand, TrackMouse, ITEView, etc. I usually work with this file open in MPW and liberally steal from it. This saves having to type the long parameter lists that many of these routines need.

The MacApp Developer’s Association is now selling a Browser Desk Accessory, modeled after the Browser in SmallTalk, that should be of great help in accessing the source code.

Drawing in the wrong methods

A common mistake is to draw on the screen in other methods than your view object’s Draw method.

An advantage to having Draw do all the work is that both screen updating and printing call the draw method. If you were to instead call QuickDraw graphics routines from other methods, then your drawings may not appear after screen updates, or on the printouts.

Another advantage to using the Draw method is that MacApp will first call TFrame.Focus method before calling Draw. The Focus method insures that the origin and clip region are properly set. If this is not called, you may find that drawing takes place in the wrong part of your view, or that you draw all over the scroll bars - which you will find to be both ugly and embarrassing.

The best technique is usually to have other methods invalidate a region or rectangle in the view, and then wait for an update event to force your view object to draw itself. It is, of course, perfectly O.K. to have your Draw method ask individual objects to draw themselves, as is done in the DrawShapes sample program. If you can’t wait for an update event, be sure to call Focus before calling Draw.

The mysterious command object

Command objects are very difficult for newcomers to MacApp to understand. People are usually pleased when I tell them that they can ignore command objects if they do not wish to implement Undo. Unfortunately, you should implement Undo for any operation that changes the data in a document, and therefore you often should use command objects.

What are command objects? They are merely temporary objects that save enough information so that the last operation can be undone. Keep in mind is that MacApp will call the methods of TCommand at certain times during the operation of your program. All you have to learn is when these methods will be called, and what any OVERRIDEs of these methods should do when they are called.

For example, MacApp will call the current command object’s DoIt method after a menu item is chosen by the user. All you have to do is create the command object in your DoMenuCommand method, and then have a DoIt method to do what you want done in response to that menu command. What could be easier? Don’t answer.

Some methods create command objects

This brings up another source of confusion. There are three common methods that create command objects: DoKeyCommand, DoMouseCommand, and DoMenuCommand. These are not methods of command objects, but merely methods that create new instances of command objects. For example, TYourView.DoMouseCommand may create an object of Type TSketcher, so it is TSketcher that needs a DoIt method, not TView.

Frames, views, and windows

It is easy to get confused as to the difference between a frame, a view, and a window. Consider the screen dump shown below in figure 4.

The resizable window contains a large, resizable frame which displays part of a view of type TParentView. There are three smaller frames installed in the large frame, and each frame has it’s own set of scroll bars (you can see that the scroll bars clearly belong to the frame, and not the window). Each frame displays part of a view, with the frame being a “porthole” through which the user can see part of what might be a very large view.

By the way, the key to handling more than one view in a window is to remember that each view lives in its own coordinate system, with each origin at (0,0). Resist the temptation to offset the origin just because the view will live in a frame in the middle of the window. The frame’s job is to take care of the origin - all the view needs to do is pretend it is the only view in the world.

Using TextEdit objects

It is easy to use a view of type TTEView, and create a cute little text editor with only a few lines of code. The tricky part is remembering to add UTEView to your USES statement in both your Unit and in the main program. If you forget this, you will get compiler error messages that mumble about there being no methods of that type for this object, and so forth. What we need is a compiler that says “Hey dummy, you forgot to add the UTEView Unit to the Uses statement!” Perhaps in version 2.0

When will MacApp call its methods, and will it ever call yours?

A major source of confusion has to do with how MacApp works. MacApp is based on hundreds of pages of source code, written in the OOP style, leading to what Howard Katz called “ a futile search for where the buck stops”. This means that newcomers to MacApp have to deal with a mysterious program that calls hundreds of its methods when it feels like it, and you often do not know when that is going to be. There is a rule to guide us, however.

The Rule: MacApp can only call methods that are defined as part of MacApp. This means that MacApp will call the DoMouseCommand method for a view, if that view is the “target”. This DoMouseCommand method will be the one provided with MacApp if you have not Overriden it, but it will be your DoMouseCommand if you have done an Override. The Rule also means that MacApp will never call the IYourDocument method that you created to initialize objects of type TYourDocument, because that method was unknown to the people who wrote MacApp. Remember Wilson’s Conjecture: MacApp is just computer code - its not magic.

The Rule, Part B: When you define new types of objects, with new methods, you are providing a set of tools for MacApp and you to use. When you Override an existing method, you are, in a sense, leaving that customized tool on the table for MacApp to use, and MacApp will generally use that tool when appropriate. When you define a method that is unique to your program, then MacApp cannot use that tool, so it is up to you to use it when necessary.

Fig. 4 MacApp in Operation

Andy Seligman’s Poem

The following poem was written by a student in the first MacApp class. It makes MacApp sound challenging, which it is, but it will show you that we have interesting and talented people learning MacApp.

There was a young hacker from Apple

Who haplessly started to grapple

With Windows and mice, and Inside Mac vice

He thought “User Friendly’s not nice!”

He told his boss of his confusion,

Who answered “I see that your usin’

Old coding technique, that’s now quite antique,

I’ll send you to class all next week!”

He went there to master MacApp,

but soon realized his mishap,

The instructor strode in and proclaimed with a grin

I can talk longer than you can listen!

He froze as he sat in the room,

and felt with a keen sense of gloom

“The problem with me, is I can not see

Which object sends what and to whom.”

He labored until his mind reeled,

through Object and Method and Field,

The class was sure great, but now he can’t wait,

To read Dave’s book MacApp Revealed!

Conclusion

What should we conclude from all this? I feel that MacApp is a bit tricky to learn to use, but I also feel that it is well worth the investment. I haven’t dwelled on the advantages to using MacApp in this article, but they are very compelling. MacApp’s value lies in four major areas:

(1) You can get a complete Mac application running in much less time than if you use a traditional development system,

(2) The user interface will conform very well to Apple’s recommendations,

(3) The MacApp code follows the compatibility guidelines, so that your application will run unchanged on everything from an old Mac 512K to a Macintosh II, and

(4) The program will be relatively bullet-proof, in that most errors will generally be trapped by the error handling routines. This latter point is often overlooked, but it is much better to present the user with an alert box that says that the window cannot be opened because of a lack of memory, instead of the program crashing with the dreaded bomb.

For those who might be interested in attending Apple’s monthly MPW and/or MacApp seminars, you should contact Karen Frazier at Apple for data sheets and prices. She can be reached at (408) 973-2726.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

GIMP 2.8.14p2 - Powerful, free image edi...
GIMP is a multi-platform photo manipulation tool. GIMP is an acronym for GNU Image Manipulation Program. The GIMP is suitable for a variety of image manipulation tasks, including photo retouching,... Read more
Sandvox 2.10.2 - Easily build eye-catchi...
Sandvox is for Mac users who want to create a professional looking website quickly and easily. With Sandvox, you don't need to be a Web genius to build a stylish, feature-rich, standards-compliant... Read more
LibreOffice 5.0.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
f.lux 36.1 - Adjusts the color of your d...
f.lux makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day. Ever notice how people texting at night have that eerie blue glow? Or wake... Read more
VirtualBox 5.0.2 - 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
File Juicer 4.43 - Extract images, video...
File Juicer is a drag-and-drop can opener and data archaeologist. Its specialty is to find and extract images, video, audio, or text from files which are hard to open in other ways. In computer... Read more
Apple MainStage 3.2 - Live performance t...
MainStage 3 makes it easy to bring to the stage all the same instruments and effects that you love in your recording. Everything from the Sound Library and Smart Controls you're familiar with from... Read more
formZ 8.5 - Solid and surface modeler. (...
formZ pro is a powerful 3D design application featuring a variety of modeling personalities and tools with an easy to use interface to express and communicate your imagination. It is based on... Read more
PopChar 7.2 - Floating window shows avai...
We're also selling a 5-license family pack for only $25.99! PopChar helps you get the most out of your font collection. With its crystal-clear interface, PopChar provides a frustration-free way to... Read more
FileMaker Pro 14.0.2 - Powerful, easy-to...
FileMaker Pro is powerful, easy-to-use software used to create custom solutions for your business that run on iPad, iPhone, Windows, Mac and the web. Use FileMaker Pro to manage and share information... Read more

ReBoard: Revolutionary Keyboard (Utilit...
ReBoard: Revolutionary Keyboard 1.0 Device: iOS Universal Category: Utilities Price: $1.99, Version: 1.0 (iTunes) Description: Do everything within the keyboard without switching apps! If you are in WhatsApp, how do you schedule a... | Read more »
Tiny Empire (Games)
Tiny Empire 1.1.3 Device: iOS Universal Category: Games Price: $2.99, Version: 1.1.3 (iTunes) Description: Launch cannonballs and blow tiny orcs into thousands of pieces in this intuitive fantasy-themed puzzle shooter! Embark on an... | Read more »
Astropad Mini (Productivity)
Astropad Mini 1.0 Device: iOS iPhone Category: Productivity Price: $4.99, Version: 1.0 (iTunes) Description: *** 50% off introductory price! ​*** Get the high-end experience of a Wacom tablet at a fraction of the price with Astropad... | Read more »
Emo Chorus (Music)
Emo Chorus 1.0.0 Device: iOS Universal Category: Music Price: $1.99, Version: 1.0.0 (iTunes) Description: Realistic Choir simulator ranging from simple Chorus emulation to full ensemble Choir with 128 members. ### introductory offer... | Read more »
Forest Spirit (Games)
Forest Spirit 1.0.5 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.5 (iTunes) Description: | Read more »
Ski Safari 2 (Games)
Ski Safari 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The world's most fantastical, fun, family-friendly skiing game is back and better than ever! Play as Sven's sister Evana, share... | Read more »
Lara Croft GO (Games)
Lara Croft GO 1.0.47768 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.47768 (iTunes) Description: Lara Croft GO is a turn based puzzle-adventure set in a long-forgotten world. Explore the ruins of an ancient... | Read more »
Whispering Willows (Games)
Whispering Willows 1.23 Device: iOS Universal Category: Games Price: $4.99, Version: 1.23 (iTunes) Description: **LAUNCH SALE 50% OFF** - Whispering Willows is on sale for 50% off ($4.99) until September 9th. | Read more »
Calvino Noir (Games)
Calvino Noir 1.1 Device: iOS iPhone Category: Games Price: $3.99, Version: 1.1 (iTunes) Description: The film noir stealth game. Calvino Noir is the exploratory, sneaking adventure through the 1930s European criminal underworld.... | Read more »
Angel Sword (Games)
Angel Sword 1.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.0 (iTunes) Description: Prepare to adventure in the most epic full scale multiplayer 3D RPG for mobile! Experience amazing detailed graphics in full HD.... | Read more »

Price Scanner via MacPrices.net

Tablet Screen Sizes Expanding as iPad Pro App...
Larger screen sizes are gaining favor as the tablet transforms into a productivity device, with shipments growing 185 percent year-over-year in 2015. According to a new Strategy Analytics’ Tablet... Read more
Today Only: Save US$50 on Adobe Elements 13;...
Keep the memories. lose the distractions. Summer’s winding down and it’s time to turn almost perfect shots into picture perfect memories with Elements 13. And get the power to edit both photos and... Read more
1.4GHz Mac mini on sale for $449, save $50
Best Buy has the 1.4GHz Mac mini on sale for $50 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Price for online orders only, in-store price may vary... Read more
12-inch 1.1GHz Gold MacBook on sale for $1149...
B&H Photo has the 12″ 1.1GHz Gold Retina MacBook on sale for $1149.99 including free shipping plus NY sales tax only. Their price is $150 off MSRP, and it’s the lowest price available for this... Read more
27-inch 3.3GHz 5K iMac on sale for $1849, sav...
Best Buy has the 27″ 3.3GHz 5K iMac on sale for $1849.99. Their price is $150 off MSRP, and it’s the lowest price available for this model. Choose free shipping or free local store pickup (if... Read more
Worldwide Tablet Shipments Expected to Declin...
Does Apple badly need a touchscreen convertible/hybrid laptop MacBook? Yes, judging from a new market forecast from the International Data Corporation (IDC) Worldwide Quarterly Tablet Tracker, which... Read more
Continued PC Shipment Shrinkage Expected Thro...
Worldwide PC shipments are expected to fall by -8.7 percent in 2015 and not stabilize until 2017, according to the latest International Data Corporation (IDC) Worldwide Quarterly PC Tracker data. The... Read more
Imminent iPhone 6s Announcement Leads To 103%...
NextWorth Solutions, with its online and in-store electronics trade-in programs including http://NextWorth.com, reports that it has experienced a 103 percent surge in quoted trade-in values over the... Read more
Weekend Deal: 13-inch Retina MacBook Pros for...
Save up to $100 on the purchase of a new 2015 13″ Retina MacBook Pro at the following resellers this weekend. Shipping is free with each model: 2.7GHz/128GB MSRP $1299 2.7GHz/... Read more
13-inch 2.5GHz MacBook Pro on sale for $999,...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999.99 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more

Jobs Board

*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
Product Design Engineer - *Apple* Watch - A...
**Job Summary** Product Design Engineer Job Description As a member of Apple 's Watch product design team, you will help to create the next generation of the world's Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Software QA Engineer, *Apple* Pay Security...
Changing the world is all in a day039s work at Apple . If you love innovation, here039s your chance to make a career of it. You039ll work hard. But the job comes with Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.