TweetFollow Us on Twitter

WebObjects Overview

Volume Number: 13 (1997)
Issue Number: 5
Column Tag: OPENSTEP

An Introduction to WebObjects

by David Neumann, System Engineer, NeXT Software

An overview of Apple's new high end application development & deployment vehicle for the Internet

This article gives a technical introduction to NeXT's WebObjects web application development platform. The content is primarily geared toward developers with at least some Internet-based application building experience.

First and foremost, WebObjects means server-based application development. It is not an authoring tool. When you layout a page with WebObjects, you are laying out your application's user interface.

WebObjects as a product ships with three major components: a cross-platform set of object-oriented frameworks, developer tools on top of those frameworks, and a deployment infrastructure for running apps built on those frameworks. This article will go into detail on all three components. First, we'll delve into "Logical Architecture" of the frameworks, and then "Physical Architecture" of deployment, and finally tools & custom code used to wire the functionality together.

Although WebObjects is full of highly extensible objects ideal for heavy-duty customization, WebObjects also includes tools that make it a first-class "RAD" (rapid application development) environment for the web. For instance, WebObjects includes drag-&-drop access to industrial-strength relational databases and offers a Database Wizard for creating complete database-aware applications (or parts of applications) with a few mouse clicks.

Note that a developer may elect to write a WebObjects application in either Java, Objective-C, or WebScript. Virtually all of NeXT's examples ship with both Java and Objective-C/WebScript equivalents. However, the developer does not have to stick to a single language, all three may be used simultaneously. For example, NeXT encourages the use of a compiled language like Java or Objective-C for business logic (for example, rules, policy, and vertical-oriented computations) and WebScript for "application" logic (such as, when you punch this button, select this field and jump to page XYZ, etc.).

Logical Architecture

Below is a look at the logical architecture of the WebObjects family of frameworks. Frameworks are the programming building blocks of the largest granularity. These frameworks include: Foundation (the non-GUI aspect of the OpenStep spec), Enterprise Objects Access (bidirectional RDBMS-to-object mapping), Enterprise Objects Control (persistent object transaction management), and WebObjects (web presentation & deployment).

Note that you may have an application split into separate services or tiers that use all of the frameworks and/or only Foundation and/or only Foundation+Enterprise Objects Access & Control. It is also possible to write a WebObjects application that only uses Foundation and WebObjects (no object/relational datasource). See the side-bar "WebObject Class Functional Groupings" for details about classes available in the WebObjects Frameworks.

All applications must include the Foundation Framework. It provides basic services needed by any program. It is also the layer of objects that provides operating system independence. In other words, you should never have to make a direct system call again for most applications when you have the luxury of using Foundation. Foundation provides operating system independence across the upcoming Rhapsody OS for Mac, Windows NT, Solaris, HP-UX, and of course NeXT's OPENSTEP/Mach operating system.

Figure 1. WebObjects Frameworks. Foundation provides operating system independence, Enterprise Objects Access provides RDBMS independence for object persistence, Enterprise Objects Control provides object persistence transaction management, and WebObjects provides objects useful for web based presentation and deployment. Note that actual linking dependencies are different than implied in the figure.

The Enterprise Objects Frameworks (Control & Access) also known collectively as "EOF" are extremely feature rich. Truly doing EOF technology justice would require an entire article unto itself and so unfortunately this discussion can only skim the surface. Consider that EOF is NeXT's third generation solution for database aware applications. The sidebar on "WebObjects Class Functional Groupings" should give the reader at least a flavor for what's available in the technology.

It's EOF that facilitates the use of true business objects in WebObjects. EOF makes your application completely database and schema independent. With it, you can create "live" entity-relationship diagrams in a tool called "Enterprise Objects Modeler" (or just "EOModeler") that ships with WebObjects. EOModeler will emit new schema and (perhaps more importantly) let you reverse engineer an existing relational database into a default object mapping - that you can then enhance without affecting the underlying schema. You can write business logic in the same language you write your application code and take advantage of both composition and inheritance relationships in that business logic. This is highly different from "normal" approaches to database driven applications: 1) forcing policy into a proprietary, database-specific stored procedure language (not object-oriented) or 2) scattering business logic across applications in event handlers. Furthermore, EOF makes it trivial to build applications that integrate resources from several databases - not just one. Add-in technology from third parties allows you to extend this integration to mainframe applications via 3270, 5250, and ASCII data streams.

Figure 2. EOModeler application. This tool ships with WebObjects to let developers graphically create "live" entity relationship model of their business objects. The model can be targeted to any datasource known to WebObjects including Oracle, Informix, Sybase, and ODBC. Note how the attribute (name) on the selected entity (Studio) is abstracted from its external database name and type. If the datasource changes, only the external information need change insulating application code from the database implementation.

The fundamental difference between WebObjects database access compared to traditional data access methods is this; when you fetch a "row" from a database, you do not get naked data, you get an object with behavior, an object that knows about its relationships to other objects. You get an object that is watched, uniqued, deleted, and updated from within a document context (kind of like a super transaction) with automatic support of undo, redo, revert, and efficient change flushing to the underlying database or databases. You specify the kind of object you get for a row (for example, its Class) using EOModeler.

Since the business objects you create with EOF don't care about the underlying database or how their values are presented in user interfaces, they may be re-used over and over in any number of different applications (web, Windows, or Macintosh Rhapsody) and indeed may be maintained by a crew of developers only loosely coupled to those building specific apps.

Physical Architecture

Now that we know what kinds of building blocks are available from a developer's perspective, how does that logical architecture get laid out physically into a running application? Figure 3 shows the tiers involved in a typical deployed WebObjects application.

Unlike traditional modes of Internet programming such as Perl scrips, a WebObjects application does not "disappear" between page processing/generation transactions. It stays up and maintains a persistent database connection. The task of state management is completely subsumed by the WebObjects framework. State management is also abstracted to the point that alternative state management policies may be implemented with little or no impact on existing code (such as, state in the process, state in the file system, state in the page, state in the someplace-not-invented-yet, etc.).

With WebObjects, browsers interact with HTTP servers in their normal way taking advantage of any technologies that enhance this browser-to-web server link. For example, secure socket layer communication protocols in Netscape and Microsoft browser/server products.

Figure 3. WebObjects Deployment. Browsers communicate with HTTP servers which communicate with the WebObjects web server adaptor. The WebObjects adaptor load balances across one or more application server processes (also called instances) running on one or more machines. Once running, WebObjects application instances do not go away between user requests; they maintain themselves, their sessions' state for users, and their database connections. They are efficient, fast, and by definition, redundant.

It's the job of the HTTP server adaptor, as indicated in Figure 3, to communicate with a given HTTP server and forward requests to one or more application "instances" - an instance is a separate copy of a given application process. A WebObjects app serving a few users may have only one instance. A large application may have tens or hundreds of instances running on one or more machines. If an application has more than one instance, the WebObjects adaptor is essentially acting as load balancing agent. If an instance fails, it is only affected - other instances and/or the site's web server is unaffected.

WebObjects HTTP Server adaptors come in three flavors: an NSAPI plug-in, an ISAPI DLL, and a very low overhead CGI program. These adaptors are written in pure C and all of their source is included with WebObjects. This was provided as a portability & integration strategy. Consider that WebObjects applications may reside on the forthcoming Rhapsody, Solaris, Windows NT, etc., but not all operating systems. To facilitate plugging in a cluster of WebObjects Application server boxes into an existing infrastructure of, say, SGI HTTP servers, the developer may recompile the desired web server adaptor flavor for their target operating system.

The adaptor will forward requests over the network as easily as it will forward requests to applications running on the same box as the HTTP server. In fact, from a load sharing perspective, it is ideal for the HTTP server and Application servers to reside on separate boxes. This way, WebObjects can generate pages on the fly without competing with the HTTP server's CPU(s) that may already be quite busy vending out the web site's "static" HTML pages.

Since WebObjects applications are server based, database access happens behind the firewall. Browsers need never make direct connections to a database server. Database connections are therefore highly secure (only accessible via actual application API), and conserved (that is, you never have more than one connection per instance regardless of the number of users supported - unless this is specifically something the developer desires).

Any browser can be a WebObjects client since only standard HTML need be generated on the fly by the WebObjects server. If the developer desires a more advanced look & feel, then other content types may also be generated such as Java applets. WebObjects essentially makes a distinction between client Java and server Java. Client Java is used to enhance the user interface (e.g. a Calendar applet, a simple field validation applet, etc.). Server Java (and/or server Objective-C/WebScript) is used to customize the WebObjects frameworks to the business logic and behavior requirements of your application (for example, a Customer object, a stat-gathering Advertisement component, etc.).

In addition to HTML and HTML embedded with Java applets (and/or any other client side technology driven by HTML content, e.g. ActiveX, RealAudio, etc.), WebObjects 3.1 includes one new content generation feature: support for dynamically filling in "blanks" in PDF documents using Adobe's new FDF protocol. This capability lets WebObjects applications create visually appealing and printable reports, forms, and catalog pages dynamically.

Programming a WebObjects Application

While all operating systems supported by WebObjects are development platforms in the sense that they all support building WebObjects application executables, Windows NT, OPENSTEP/Mach, and Rhapsody are considered the "preferred" development platforms because only on these platforms are all of the graphical tools supported. These tools include WebObjects Builder (a web-oriented user interface layout tool with drag & drop database access), EOModeler (the object to RDBMS mapping tool for abstracting your datasources), and Project Builder (a project management, compiling, & debugging environment). If your application uses only WebScript, you will not need the management services of Project Builder.

All resources in a WebObjects application are placed underneath the application's "wrapper" which has a "woa" extension. For example the DodgeDemo database-fed catalog application that ships with WebObjects is actually a directory with the name "DodgeDemo.woa" filled with resources. These resources include components, pages, images, scripts, source files, etc.

You use WebObjects Builder to create your application's "components" which are assembled into the pages the user sees. Some components represent a page in total. Some represent a part of a page (like a footer). Components can be nested within each other. Action handlers representing a component's behavior may be expressed in WebScript, Objective-C, or Java (or no code at all if all the behavior is in components prebuilt by you or NeXT). Figure 4 shows the WebObjects Builder while a standard reusable component (the WebObjects active image logo) is being dragged & dropped on the Main component of the HelloWorldJava application.

Figure 4. WebObjects Builder user interface layout. Here a prebuilt component (the WebObjects active image logo) is being dragged and dropped onto the HelloWorldJava application's "Main" page HTML "canvas."

Note that the upper pane shows the component's visual layout while the lower pane shows all of the methods and objects known to the component. Methods are listed below the line in the left-most browser column, variables above it. We see that this component has defined an action method called "sayHello" and an instance variable called visitorName. Notice that all components have access to any variables and methods implemented on the Session and Application via their respective entries in this browser.

Using WebObjects Builder can be summed up as the act of associating methods and variables in the lower pane with the properties of custom and NeXT components placed on the page canvas in the top pane and repeating this process for however many of your custom components make up the application.

When you add code to a component (regardless of the language used), you are subclassing the WebObjects class WOComponent (or your own subclass of WOComponent). A component definition is stored in a folder with a "wo" extension. Every component includes three basic files: an HTML template (which defines pure layout), a code file (defining pure behavior), and a "declaration" file that maps the two together. Using this approach, code can change without impacting layout and format/look can change without impacting code. It also makes it straightforward to delegate HTML look issues to a third party that may have special expertise in page layout. Developers can import the HTML at a later date for the final application release (or change the look dynamically while the application is running). When you edit a component in WebObjects Builder, it manages all of the component's resource files transparently.

All applications include a WOSession and WOApplication object whose behavior you can customize with code in either WebScript, Objective-C, or Java. Any variables you declare in your WOApplication subclass represent Application scope (for example an array of URLs pointing to third party sites). Any variables declared in your WOSession subclass represent Session scope (for example, a user's shopping cart or active selection). Any variables declared in your WOComponent subclasses represent component scope unique to each component (for example, the disclaimer string in a footer component). Components tend to last for only a single transaction, sessions last for many transactions, and an Application contains many sessions.

At your discretion, you may elect to override several important methods that allow customization to the event handling process. These include, but are not limited to: "init" - called once and before anything else on object creation, "awake" - called before action handling on every request, "sleep" - called at the end of an event on every request, and "dealloc" - called right before the object is destroyed. All four methods may be implemented at all three scope levels (i.e. in your Application, Session, and Component subclasses).

Below is source code for the HelloWorld example's "Main" page. The Main page is the very first page that gets created when a new session is created. This example is implemented in Java. You can access a component's code via the code inspector as indicated in the Figure 5.

Figure 5. WebObjects Builder showing code inspector with Main component's sayHello event handler and visitorName instance variable defined inside.

Listing 1: Main.java

A custom subclass of the WebObjects Java class "Component" (WOComponent in
the Java name space).  The NeXT Java frameworks are imported as next.util.*
and next.wo.*. This subclass declares a Java String as an instance variable
and a single action method.

import next.util.*;
import next.wo.*;

public class Main extends Component
{
 String visitorName;

 public Component sayHello()
 {
 Hello nextPage = 

 (Hello)application().pageWithName("Hello");
 nextPage.setVisitorName(visitorName);
 return nextPage;
 }
}

We see that the class Main is a subclass of Component (the class name of WOComponent in the Java name space). This component is also the entire page. It declares a single page variable, visitorName, and a single event handler method, "sayHello()". The first line in the method invokes the method "pageWithName()" against the Application object. All WOComponents inherit a method "application()" that returns the application object for convenience. pageWithName() takes the name of the page instance you'd like to get a reference to as an argument. If it finds the page defined in your application wrapper, it returns it. Here we're taking the returned page object and assigning it to a variable "nextPage". In the next line, we invoke a method on nextPage "setVisitorName()". Finally, on the third line, we return nextPage which means this page will define the response for this transaction. If we had returned "self", the same page that handled the previous request would make up this response.

You may be wondering where the value for visitorName is getting set. In WebObjects Builder, HelloWorld's Main component has a single WOTextField object whose value property has been mapped to this component's visitorName instance variable. This means that whatever value it has on page generation will fill the textfield upon display, and any value the user enters will get automatically parsed and placed in this variable by the time your action method is invoked. In Figure 6, WebObjects Builder's element inspector is focussed on the textfield. Note that the textfield's value property is set to the component instance variable.

Figure 6. WebObjects Builder showing WOTextField inspector with its value property mapped to the highlighted visitorName component instance variable.

If we wanted the textfield to have an initial default, we could elect to set it in an awake method for the page as shown in Listing 2.

Listing 2: Main.java

awake
Set a default value for the visitorName instance variable by
implementing the WOComponent's awake method.

 public awake()
 {
 visitorName = "David";
 }

Listing 3 shows how the Hello page's custom behavior would be implemented in Java. The Hello page is another subclass of WOComponent used as the response to the "sayHello" action defined in the application's Main page.

Listing 3: Hello.java

This subclass of Component defines the custom behavior of the
Hello page used as a response for the Main page's action method.
It also declares a visitorName instance variable.

import next.util.*;
import next.wo.*;

public class Hello extends Component
{
 String visitorName;

 public void setVisitorName (String name)
 {
 visitorName = name;
 }

 public String visitorName ()
 {
 return visitorName;
 }
}

Note that using WebScript can reduce the number of lines of code you need to write because it automatically adds default "accessor" methods like those used in the Hello page above to set and get the visitorName instance variable. For example, Listing 4 shows the same Hello page implemented in WebScript.

Listing 4: Hello.wos

This WebScript file has one line - a declaration of the visitorName
instance variable. At runtime, this file is parsed by WebObjects
and a subclass of WOComponent is dynamically added to the runtime
with the developer's custom methods and instance variables.

id visitorName;

That's it.

When you're done editing your source, you use Project Builder to create the application's executable. Figure 7 is a screen shot of ProjectBuilder and its build panel being used to create the HelloWorldJava executable.

Figure 7. ProjectBuilder shown here while building the HelloWorldJava application in the background.

Figure 8 shows how to add database access to the HelloWorldJava application. In Figure 8, a Customer entity defined in EOModeler is dragged and dropped into the WebObjects Builder component window creating an instance of a WODisplayGroup that will manage Customer objects fetched from a database. By mapping properties of HTML widgets to attributes and methods provided by the WODisplayGroup, information from the underlying database management systems can be displayed in the user interface - with any business logic being enforced transparently, thanks to the intervening objects.

Figure 8. WebObjects Builder showing how to access objects for entities defined in the EOModeler application.

Figure 9 shows WebObjects Builder while the user is selecting options available in the Database Wizard tool. Specifically, WebObjects Builder is prompting the user for the database type the developer would like to connect to.

Figure 9. WebObjects Builder showing abrand new application being constructed with the Database Wizard.

HelloWorld is, of course, a very simple application. WebObjects however is most appropriate when building the most complicated applications. Figure 10 is a screen shot of a non-trivial example application that ships with WebObjects. It's called the WebObjects Monitor, it is used to remotely administer, monitor status, gauge performance, and provide fail-over for your application's instances during the deployment phase of your project.

Figure 10. WebObjects Monitor. An example of non-trivial WebObjects application. This particular app is used to administer a WebObjects application during deployment. In the above screen shot, we see that the DodgeLite application configuration is being inspected. The detail information shows that it has currently been configured with four instances (two of which are running).

Summary

WebObjects provides frameworks to give your app a logical head start, deployment infrastructure to give your application a scalable structure, and development tools to help you create, maintain, and extend your application throughout its life-cycle. Today the tools run on NeXT's OPENSTEP/Mach operating system as well as Microsoft's Windows NT. They will also be available soon on the next-generation Mac OS, Rhapsody, on top of PowerPC hardware. Regardless of what platform you use to develop your application, you can enjoy portability when you decide to deploy it. The WebObjects deployment runtime is available on Windows NT, OPENSTEP/Mach, Solaris, and HP-UX.

For detailed information about using WebObjects, class documentation, user guides, and training schedules, visit NeXT's web site at http://www.next.com.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

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
djay Pro 1.2 - Transform your Mac into a...
djay Pro provides a complete toolkit for performing DJs. Its unique modern interface is built around a sophisticated integration with iTunes and Spotify, giving you instant access to millions of... 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

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
*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
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.