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

Mellel 3.5.5 - The word processor for sc...
Mellel is the leading word processor for OS X and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
Bookends 12.8.3 - Reference management a...
Bookends is a full-featured bibliography/reference and information-management system for students and professionals. Bookends uses the cloud to sync reference libraries on all the Macs you use.... Read more
Carbon Copy Cloner 4.1.18 - Easy-to-use...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
Hopper Disassembler 4.2.14- - Binary dis...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more
BetterTouchTool 2.291 - Customize Multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom... Read more
Sound Studio 4.8.11 - Robust audio recor...
Sound Studio lets you easily record and professionally edit audio on your Mac. Easily rip vinyls and digitize cassette tapes, or record lectures and voice memos. Prepare for live shows with live... Read more
Sound Studio 4.8.11 - Robust audio recor...
Sound Studio lets you easily record and professionally edit audio on your Mac. Easily rip vinyls and digitize cassette tapes, or record lectures and voice memos. Prepare for live shows with live... Read more
BetterTouchTool 2.291 - Customize Multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom... Read more
Carbon Copy Cloner 4.1.18 - Easy-to-use...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
Hopper Disassembler 4.2.14- - Binary dis...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more

The best 2v2 card combos in Clash Royale
2v2 is making it's grand return toClash Royalequite soon. 2v2 has quickly become one of the game's most popular gameplay modes, though they still have yet to make it a permanent fixture in the game. 2v2 is exciting and adds some new flavor to... | Read more »
The best games we played this week - Aug...
Another busy week has come to a close. We played a lot of excellent games this week and now it's time to look back and reflect on some our favorites. Here are our picks for the week of August 18. [Read more] | Read more »
War Wings beginner's guide - how to...
War Wings is the newest project from well-established game maker Miniclip. It's a World War II aerial dogfighting game with loads of different airplane models to unlock and battle. The game offers plenty of single player and multiplayer action. We... | Read more »
How to win every 2v2 battle in Clash Roy...
2v2 is coming back to Clash Royale in a big way. Although it's only been available for temporary periods of time, 2v2 has seen a hugely positive fan response, with players clamoring for more team-based gameplay. Soon we'll get yet another taste of... | Read more »
Roll to Win with Game of Dice’s new upda...
Joycity’s hit Game of Dice gets a big new update this week, introducing new maps, mechanics, and even costumes. The update sets players loose on an exciting new map, The Cursed Tower, that allows folks to use special Runes mid-match. If you feel... | Read more »
Bottom of the 9th (Games)
Bottom of the 9th 1.0.1 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Play the most exciting moment of baseball in this fast-paced dice and card game! | Read more »
The best apps for viewing the solar ecli...
If you somehow missed the news, many parts of the United States will be witness to a total solar eclipse on August 21 for the first time in over 90 years. It'll be possible to see the eclipse in at least some capacity throughout the continental U... | Read more »
The 5 best mobile survival games
Games like ARK: Survival Evolved and Conan Exiles have taken the world of gaming by storm. The market is now flooded with hardcore survival games that send players off into the game's world with nothing but maybe the clothes on their back. Never... | Read more »
Portal Walk (Games)
Portal Walk 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Portal Walk is adventure and relaxing platform game about Eugene. Eugene stuck between worlds and trying to find way back home.... | Read more »
Technobabylon (Games)
Technobabylon 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: City of Newton, 2087. Genetic engineering is the norm, the addictive Trance has replaced almost any need for human interaction,... | Read more »

Price Scanner via MacPrices.net

15-inch 2.2GHz Retina MacBook Pro, Apple refu...
Apple has Certified Refurbished 2015 15″ 2.2GHz Retina MacBook Pros available for $1699. That’s $300 off MSRP, and it’s the lowest price available for a 15″ MacBook Pro. An Apple one-year warranty is... Read more
Apple refurbished Mac minis available startin...
Apple has Certified Refurbished Mac minis available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: – 1.4GHz Mac mini: $419 $80 off MSRP – 2.6GHz Mac... Read more
Apple refurbished iPad Pros available startin...
Apple has Certified Refurbished 2016 12″ WiFi iPad Pros available starting at $589. An Apple one-year warranty is included with each model, and shipping is free: – 32GB 12″ iPad Pro WiFi: $589... Read more
Weekend sale: 13-inch MacBook Pros for up to...
Amazon has new 2017 13″ MacBook Pros on sale today for up to $200 off MSRP, each including free shipping: – 13″ 3.1GHz/256GB Space Gray MacBook Pro (MPXV2LL/A): $1599.99 $200 off MSRP – 13″ 3.1GHz/... Read more
Back To School With The Edge Desk All-in-one...
Back to school is just around the corner, and the ergonomically correct Edge Desk all-in-one portable kneeling desk is ideal for students living in dorms and small apartments, Edge Desk features:... Read more
Norton Core Secure Wi-Fi Router Now Available...
First introduced at the 2017 Consumer Electronics Show (CES), Norton Core, a secure, high-performance Wi-Fi router, fundamentally changed the concept of Wi-Fi routers by making security the primary... Read more
ViewSonic Adds New 27-inch 4K UHD Monitor to...
ViewSonic Corp. has introduced the VP2785-4K, a 27-inch 4K UHD (3840×2160) monitor that delivers precise and consistent color representation and performance to ensure incredible image quality. Built... Read more
Apple now offering Certified Refurbished 2017...
Apple is now offering Certified Refurbished 2017 27″ iMacs for up to $350 off original MSRP. Apple’s one-year warranty is standard, and shipping is free. The following models are available: – 27″ 3.... Read more
13-inch 2.3GHz MacBook Pros on sale for $100...
Amazon has the new 2017 13″ 2.3GHz MacBook Pros on sale today for $100 off MSRP, each including free shipping: – 13″ 2.3GHz/128GB Space Gray MacBook Pro (MPXQ2LL/A): $1199.99 $100 off MSRP – 13″ 2.... Read more
Clearance 2016 13-inch MacBook Airs available...
B&H Photo has clearance 2016 13″ MacBook Airs available for up to $200 off original MSRP. Shipping is free, and B&H charges NY & NJ sales tax only: – 13″ 1.6GHz/128GB MacBook Air (MMGF2LL... Read more

Jobs Board

Development Operations and Site Reliability E...
Development Operations and Site Reliability Engineer, Apple Payment Gateway Job Number: 57572631 Santa Clara Valley, California, United States Posted: Jul. 27, 2017 Read more
Frameworks Engineering Manager, *Apple* Wat...
Frameworks Engineering Manager, Apple Watch Job Number: 41632321 Santa Clara Valley, California, United States Posted: Jun. 15, 2017 Weekly Hours: 40.00 Job Summary Read more
Map Quality Analyst Lead, *Apple* Maps Eval...
…a team of subject matter experts measuring the quality of a range of Apple Maps algorithms, such as Map search, recommendations, and routing. Our group works with Read more
Business Development Manager, *Apple* Pay -...
Job Summary Apple Pay is seeking an experienced Business Development professional to join the Apple Pay team to develop partnerships and strategic alliances with Read more
Information Systems Engineer, *Apple* Retai...
Job Summary Do you have a passion for the technology and systems that make Apple amazing? Are you interested in joining IS&T Retail on what they do best? This is an Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.