TweetFollow Us on Twitter

Porting Code to the BeOS

Volume Number: 13 (1997)
Issue Number: 1
Column Tag: Betech™

Porting Code to the BeOS

By Michael Rutman, independent consultant

A look at how developing for the BeOS differs from other platforms

The BeBox and the Macintosh Developer

I was curious what would happen if a BeBox was dropped on my desk and I was told, "This is the platform we want all our software running on - make it so." As a Macintosh developer, would this be the end of the world as I know it, or would it be a smooth transition as enjoyable as MacOS 8.0 was expected to be?

Despite my love for Macintosh, there is tons of free software for Unix and dos that I would love to port to Macintosh, but porting Unix software to Macintosh has always been difficult. Each time I tried it was very painful. The BeOS claim to support Unix software was intriguing, so I decided I would port some Unix code as well as Macintosh code to the BeOS.

I've had the BeBox for a week now, and I have had a good time with it. Playing with it has made me think a lot about the BeOS and how it would fit into a Macintosh developers' life. The Macintosh user experience, especially for developers, has always been important. This article describes my experiences setting up the BeBox, porting Unix code, and the steps I would need to take to port Macintosh code.

Getting Started

Be gave me a BeBox all ready to go. All I needed to do was plug it in and start porting code to it. However, setting it up proved to be an interesting experience. The BeBox has 24 ports on the back, not including the 3 on cards, and none of them are labeled. Normally, I can guess a port by the number of pins, but the BeBox supports every port I can think of, and some that I have never heard of before, and several of them look identical.

There is a nice diagram in the User Manual to identify each port; I recommend you make sure you never lose the User Manual. Once you have the diagram, hooking up the BeBox is just plug and play. In fact, the manual says that the BeBox will automatically detect such things as the mouse plugged into a port, and configures itself to use that port. Having once had to set up a Windows machine, I appreciate Be's effort at making it easy to set up their computer.

All of the BeOS preference applications are in one folder, and each preference is in a well named application. Contrast that with whenever I need to configure my Macintosh, I never seem to know exactly where to find the correct configuration panel. I didn't have that problem with the BeOS. On the other hand, I spent over an hour configuring the BeOS until things worked, and I am still having some problems with the Ethernet. It's never taken me that long to get any Macintosh configured, except when MacTCP was first released. Overall, configuring the BeOS was in some ways easier than configuring a Macintosh, in other ways more difficult.

Once I had everything set up and ready to go, the applications worked as I would expect. I was able to find several shortcuts by just trying things. The shortcuts I found were nicely done. If you are used to Macintosh shortcuts, then you won't be disappointed by the BeOS shortcuts. They implemented many of the Macintosh shortcuts, and the new shortcuts they have introduced make sense and work well. They did miss command-clicking a window title to get a path, but that was the only shortcut I regularly use that the BeOS did not implement.

I must say that the BeOS is not Macintosh, and I doubt it ever will be confused with Macintosh - but on its own merits, I must say that the BeOS is nice. I am using DR8, which, near as I can tell, is 2 releases away from 1.0. Having used NeXTSTEP at 0.8, and seen how much NeXT cleaned it up for 1.0, I expect future versions of the BeOS to be very nice, but it is as yet unfinished. There is very little that "doesn't work," and much of it works well. In many ways, it's an improvement over other GUI's that are already shipping, but not much of its UI is revolutionary.

About the Development Environment

Metrowerks, on their CodeWarrior 10 CD, provides tools to cross-compile Be applications on your Macintosh. You can even do remote debugging over the network. However, Metrowerks also ported their IDE to the BeOS, and the BeIDE is included with the BeOS.

You can also use the compiler from the command line. Make is supported, as is calling the compiler directly. You can edit your files under the BeOS using their low end graphical editor called Edit. After using Edit, though, I recommend using CodeWarrior.

The command line make uses mwcc and mwld. The mwld shipped with the BeOS is a demo limited to 64K applications. This limit prevents anything useful from being created, but the commercial linker from Metrowerks will work from the command line. You will have to copy a folder from your CodeWarrior CD to the BeBox and place the new linker in the correct place. If you unzip the folder from the root volume, it should install automatically in the correct place for you. I used ftp, but later versions of the BeOS, I'm told, will be able to read Macintosh CD-Roms.

If you have Metrowerks CodeWarrior 10, then you have the full Be development environment. However, Metrowerks will no longer be including the Be development kit on their CodeWarrior CD. You will have to buy it from Metrowerks for $299/year; currently discounted to $149 if you act now.

If you know how to program in NeXTSTEP, the Be operating system will seem very familiar. Most of the people I met at Be were NeXTSTEP programmers at one time or another. There is a lot in Be's framework that other framework developers should look at. Again, I didn't see anything revolutionary over NeXTSTEP, but it's the first time I've seen a really good framework written in C++.

A Simple Port: Unix Code

The BeOS has a mini-Unix environment to make porting Unix code to the BeOS easier. The theory, according to Be, is that you only need to unpack the source code, cd to the directory, and type make. I thought this would be a quick, easy test of the development environment. I attempted to port tf, a mud client. Unfortunately, it needed a bit more of the Unix environment than Be provided. My problems seemed to be with the configuration script, though, not with the actual program. Here are the details.

tf uses a configuration script to determine on what kind of box it is being built. When attempting to run the configuration script, I had no output to the terminal window. After some exploration, I found that tf uses tee to log the session to a file as the user configures tf. Though for whatever reason, tee was only sending the session to the file, not to standard out. By removing all calls to tee, I got through my first hitch.

Once I removed tee, the configuration script choked because of Be's naming convention. All Unix boxes name their default compiler cc, and many Unix boxes have gcc installed. Be calls their compiler mwcc. I don't know of any software packages out there that expect to call a compiler mwcc. Rather than edit every makefile, I made copies of mwcc and mwld, and called them cc and ld.

Another minor problem I had with Be's naming convention is their use of bash for the standard /bin/sh. /bin/sh is normally standard bourne shell on every Unix box I've ever used. Instead, Be provides bash for /bin/sh. While bash is a nice shell, and it is mostly compatible with /bin/sh, it's not /bin/sh, and some configuration scripts will only work with /bin/sh.

The only serious problem was with how the configuration script works. The configuration script for tf works by changing to the Unix directory and running another script. Somewhere in the scripts, something had not recognized the directory had changed. This is a major problem for tf because it relies on changing directories and doing makes. If all the source is in the same file, then there should not be a problem, but most configuration scripts put sources in multiple directories, and changing directories must propagate. I was able to work around this problem by changing where the config scripts placed files.

Now that the make scripts were going, I ran into problems with the header files. in.h and inet.h are the standard headers for tcp programs, but Be uses net/socket.h instead. Usually, socket.h is found under sys, but Be put it under net. I edited the config script to use net/socket instead of in.h. I also had to edit one file to change the sys/socket.h to be net/socket.h. These things are minor, but they are just more stalls in getting started.

There were several standard library routines that tf could not find in the BeOS, but none of them were critical for tf. The configuration script was able to automatically turn off those features as needed. Unfortunately this is likely to be a problem for other programs. The missing library calls are getwd, hstrerror, srandom, strcmpi, stricmp. Be also put gethostbyname and connect in a different library.

After these changes, the configuration ran and started the compile. The first error hit in the compile was a doubly defined macro for bcopy. Because bcopy was used by every file, every compile failed. I couldn't figure out how to stop a runaway process; neither control-C, nor atl-. stopped the compile. Each file failed, and I had to sit there and watch each file fail. A minor edit of one header file corrected the doubly defined bcopy.

After much editing of the configuration script I was able to cd to the directory, type make and get a working Unix program. A bit more work than I was led to believe, but much less than porting any Unix code to Macintosh or Windows.

Porting Macintosh Code

If your application is already written in a C++ framework, then porting to the BeOS and their framework will not be very difficult; just don't expect to finish it overnight. If you have a legacy application with multiple event loops, and absolutely no code encapsulation, it would probably be easier to start from scratch than port your code.

First, you must split your application into 5 parts: setup, event loop, user interface, file I/O, and the back end. Throw out the first three, because Be does it their own way. Next, modify your code for Be's File I/O, and set up the back end so you can call it from C++. You are ready to start your port. If you have printing or networking in your application, then you also will have to redo them. Because the BeOS uses standard Unix networking calls, your network rewrite may be quite painful. At least you get to keep your back end.

Application Setup

A Be application is set up differently than a Macintosh application, but it's straight forward enough. Once you know how to do it, it's more or less the same each time. You must have an icon, a signature, launch information stored in the launch resource, and one short routine to instantiate and run your App object.

You can create your icon in Be's IconWorld. You also use IconWorld to edit your application's launch resources such as signature, launch exclusivity, background app, and argv-only settings. Unfortunately it only lets you edit the resources needed for launch.

On Macintosh, each application is supposed to have a unique signature. On the BeOS, every application must have a unique signature, or you may be unable to launch the application. Be will be happy to give you one through email each time you need one.

The BeOS centers everything around windows, and multiple instances of the same application are a lot like multiple windows in one application. Be allows the application developer to set a launch preference for one of the following:

  • Launch each time it is clicked.
  • Launch only once per copy of the application.
  • Launch only once no matter how many copies there are.

The BeOS uses the signature to tell if two copies of an application are the same. Hence, it is very important that you do not duplicate signatures.

A typical main routine is pretty straightforward.

Listing 1: main.c

#include "MyApplication.h"

main()
int InstallDesktop()
{
 new MyApplication(‘abcd');
    // other initialization goes here
 be_app->Run();
 delete be_app;
}

The signature in this routine is ignored if the application has it in a resource. It's just there in case that resource is missing.

Event Loop

Be handles events by passing BMessage objects to BLooper objects, which in turn pass the BMessage object to a BHandler. The BApplication object and BWindow objects are subclasses of BLooper, and handle most of your system messages for you. For most of the items in your Macintosh event loop, you can just throw out your event handling code, since the BeOS framework handles the entire thing for you. In the rare case where you want to do something special, there are filters you can place on the BLoopers.

You override the BLoopers MessageReceived method to handle menu commands and button clicks. The easiest way to do this is to subclass BWindow, which is a subclass of BLooper that receives all the UI messages. The code in this BLooper looks a lot like a Macintosh event loop, but instead of dealing with low level events and turning them into concepts, the BeOS sends you messages that could have come from anywhere. For example, on Macintosh, you might have an Apple event and a menu command that do the same thing. The Apple event processing, however, would have to figure out what was going on, then call the appropriate routine. Likewise, the menu command would call MenuSelect, then determine which routine it's referring to, then calls the appropriate routine. On the BeOS, much like most frameworks, all that is handled for you, and you only have to look for a message of a particular type. No matter how the event was generated, it always appears as the same message by the time you see it.

Each message can have additional data inserted into it. In the sample code used in Listing 2, we pull the target out of our button's message. When the button was set up, the target could be placed into the button with an AddObject call. You can not only add objects, but any data type, as well as multiple data types. Adding multiple data items of the same name and type will create an array of those items, so a button could have multiple targets.

Listing 2: MessageReceived

MyWindow::MessageReceived(BMessage *message)
{
 switch(message->what)
 {
 case MYBUTTON:
 MyTarget *target = (MyTarget *)message->FindObject("target");
 target->DoIt();
 break;
 case MYMENU:
 DoFunkyMenuCall();
 break;
 default:
 BWindow::MessageReceived(message);
 break;
 }
}

Building a User Interface

First, the BeOS UI is as different from the Macintosh as is Windows, but in its own way. A Be application expects to be a window, and each window acts like its own application. Unlike a Macintosh application, which has a no document state, Be applications are usually only the one visible window. If you want a second window, the BeOS treats it like a second application. Each window gets its own menu bar, its own thread for execution, its own event BLooper, everything. Furthermore, BeOS messaging makes little distinction between communicating between two threads of one application, or two applications. To fully appreciate this, I brought up the Save As panel and then continued editing my document. The Save panel happily went into the background while I finished editing my document, then came to the foreground when I clicked it so I could save the changed document.

Each window and dialog you have for your Macintosh will have to be redesigned to look good on the BeOS. Be applications can have two menus, one pull-down menu in the upper left corner, and one optional menu bar in the window. Unfortunately, I could not find any interface builder application, such as Constructor, for the BeOS. All the sample source code from Metrowerks builds the user interface on the fly. I feel this is a major setback for developing on the BeOS, but I would expect it to be remedied soon by either Be or a third party developer.

The pull down menu in the upper left has default values for About This Application and Quit Application, but you will probably want to add some of your menu items to this menu. Other menu items generally belong in a menu bar for the window, and those must be hand coded. Listing 3 provides an example.

Listing 3: BuildMenuBar

MyWindow::BuildMenuBar(BRect winRect)
{
 BRect barRect;
 barRect = winRect;
 barRect.bottom = barRect.top + MENUBARHEIGHT;
 menuBar = new BMenuBar(barRect, "menu bar");
 myMenu = new BMenu("MyMenu", B_ITEMS_IN_COLUMN);
 myMenuItem = new BMenuItem("MyItem", new BMessage(MYMENU));
 myMenu->AddItem(myMenuItem);

    // The rest of your menus and menu items would continue on

}

Like the menus, buttons and other user interface objects have to be hand coded. If you have a really old application, you might already have the hand coded UI, but if you have used Constructor, you are almost starting from scratch. If you have become used to using any interface builder at all, then you are really going to be missing it.

Most of the standard UI elements are objects, so creating them is easy, but placing and modifying them is a code change. Localizing for international applications may require a lot of work. I would have preferred to load strings from a resource of the main application, but I did not find an easy way to do this. All the sample code hard coded all strings.

All of the typical UI objects you would expect are included in the BeOS. Unfortunately, all of them require hand coding, such as the Menu code in Listing 3. All of the code is almost identical, and it is screaming out for the use of templates. If not templates, I would have to at least use #defines to create macros for building the UI.

Setting up macros for each of the UI elements would not be that much work. Setting up the menus would be as simple as

#define NewMenu(name) new BMenu((name), B_ITEMS_IN_COLUMN); 
#define NewMenuItem(menuItem, name, menu, message) \ 
{\
 menuItem = new BMenuItem((name), new BMessage((message)));\
 menu->AddItem((menuItem)); \
}

Then the Menu code would shorten to

MyWindow::BuildMenuBar(BRect winRect)
{
 BRect barRect;
 barRect = winRect;
 barRect.bottom = barRect.top + MENUBARHEIGHT; 
 menuBar = new BMenuBar(barRect, "menu bar"); 
 myMenu = NewMenu("MyMenu");
 NewMenuItem(myMenuItem, "MyItem", myMenu, MYMENU); 

    // The rest of your menus and menu items would continue on 

}

Creating buttons is almost identical to creating the menus. The main difference I found was the ability to set a target so your main window does not have to handle the button messages. Once again, I would create templates or macros before creating any buttons. Likewise, the other user interface items have to be hand coded, and each has its own parameters, but each one is very similar to the menus I've already described.

File I/O

The BeOS uses a database to store its files. I was quite excited about this until I found out that it is not a very powerful database. Each entry in the database is tagged for querying, and finding a file on the hard drive is extremely fast, but you cannot do any searches on contents of files.

Even limited to table entries, there is a lot that can be done, and the BeOS applications that take advantage of it are very powerful. For example, the BeOS dumps all of the email it receives into individual files in the database, and any application can search for email based on the email messages' attributes. Unfortunately, you cannot search for an email message based on the contents of the email message.

When porting a Macintosh application, you probably won't be able to take advantage of the BeOS database, but you should not be hindered by it either. The BeOS has a BFile and BResourceFile object, and despite not being identical to a Macintosh FSSpec, they are close enough. The hardest part you will encounter will probably be the non-modality of the Save File Panel. Many Macintosh applications assume the document cannot change when the save panel is up. On the BeOS, there is no rule against it. The opening, reading, and writing of files should be very easy to convert.

Back End

Hopefully, this is the meat of your application. The BeOS uses Metrowerks C++ compiler. If you already use Metrowerks, you shouldn't have much trouble porting the rest of your code to the BeOS. If you have already been using good object oriented techniques, then you should not have any problem putting a new UI on your back end.

Be careful about reentrancy. A significant amount of Macintosh code is not reentrant, and it's a bit of extra work to make BeOS code non-reentrant. If your code is non-reentrant, you may have some real problems here. You might be best off making the back end an exclusive launch server with no front end, and have a multi-launch front end that messages the server. As the BeOS makes no difference between a UI messaging itself and a UI messaging another application, you can easily make a non-reentrant server to be the back end to your UI.

Conclusions

If a BeOS was dumped on my desk, which one was, and I was told to port some existing code to it, which I did, I would not be upset, which I am not. It's not a Macintosh, and the user experience of the BeOS is not the same, but it does stand on its own.

Porting Unix code could, and should, be a bit easier, but it's not difficult - I can forgive a lot because the BeOS is still a prerelease. I would expect Be to fix any problems they come across over the next several months.

Porting Macintosh code, on the other hand, is a major undertaking. However, porting Macintosh code to Windows is an even larger commitment - so, relatively speaking, it is not that difficult. If you are using PowerPlant or some other framework, you can expect your port to be a large project, but most of your back end should easily transfer. On the other hand, if your code is a legacy application written before the invention of C++, then you are in for a world of hurt.

The BeOS has a lot of potential, and I look forward to seeing it develop. It is a young system. Many parts of it sound very nice, and have the potential to develop into very useful features on all computer programming environments. Just as features of NeXTSTEP's development environment have migrated to other platforms, the BeOS is definitely worth getting just to see the new ideas they have put into their computer.

 
AAPL
$99.76
Apple Inc.
+2.09
MSFT
$44.08
Microsoft Corpora
+0.45
GOOG
$520.84
Google Inc.
+9.67

MacTech Search:
Community Search:

Software Updates via MacUpdate

RestoreMeNot 2.0.3 - Disable window rest...
RestoreMeNot provides a simple way to disable the window restoration for individual applications so that you can fine-tune this behavior to suit your needs. Please note that RestoreMeNot is designed... Read more
Macgo Blu-ray Player 2.10.9.1750 - Blu-r...
Macgo Mac Blu-ray Player can bring you the most unforgettable Blu-ray experience on your Mac. Overview Macgo Mac Blu-ray Player can satisfy just about every need you could possibly have in a Blu-ray... Read more
Apple iOS 8.1 - The latest version of Ap...
The latest version of iOS can be downloaded through iTunes. Apple iOS 8 comes with big updates to apps you use every day, like Messages and Photos. A whole new way to share content with your family.... Read more
TechTool Pro 7.0.5 - Hard drive and syst...
TechTool Pro is now 7, and this is the most advanced version of the acclaimed Macintosh troubleshooting utility created in its 20-year history. Micromat has redeveloped TechTool Pro 7 to be fully 64... Read more
PDFKey Pro 4.0.2 - Edit and print passwo...
PDFKey Pro can unlock PDF documents protected for printing and copying when you've forgotten your password. It can now also protect your PDF files with a password to prevent unauthorized access and/... Read more
Yasu 2.9.1 - System maintenance app; per...
Yasu was originally created with System Administrators who service large groups of workstations in mind, Yasu (Yet Another System Utility) was made to do a specific group of maintenance tasks... Read more
Hazel 3.3 - Create rules for organizing...
Hazel is your personal housekeeper, organizing and cleaning folders based on rules you define. Hazel can also manage your trash and uninstall your applications. Organize your files using a... Read more
Autopano Giga 3.7 - Stitch multiple imag...
Autopano Giga allows you to stitch 2, 20, or 2,000 images. Version 3.0 integrates impressive new features that will definitely make you adopt Autopano Pro or Autopano Giga: Choose between 9... Read more
MenuMeters 1.8 - CPU, memory, disk, and...
MenuMeters is a set of CPU, memory, disk, and network monitoring tools for Mac OS X. Although there are numerous other programs which do the same thing, none had quite the feature set I was looking... Read more
Coda 2.5 - One-window Web development su...
Coda is a powerful Web editor that puts everything in one place. An editor. Terminal. CSS. Files. With Coda 2, we went beyond expectations. With loads of new, much-requested features, a few... Read more

Latest Forum Discussions

See All

This Week at 148Apps: October 13-17, 201...
Expert App Reviewers   So little time and so very many apps. What’s a poor iPhone/iPad lover to do? Fortunately, 148Apps is here to give you the rundown on the latest and greatest releases. And we even have a tremendous back catalog of reviews; just... | Read more »
Angry Birds Transformers Review
Angry Birds Transformers Review By Jennifer Allen on October 20th, 2014 Our Rating: :: TRANSFORMED BIRDSUniversal App - Designed for iPhone and iPad Transformed in a way you wouldn’t expect, Angry Birds Transformers is a quite... | Read more »
GAMEVIL Announces the Upcoming Launch of...
GAMEVIL Announces the Upcoming Launch of Mark of the Dragon Posted by Jessica Fisher on October 20th, 2014 [ permalink ] Mark of the Dragon, by GAMEVIL, put | Read more »
Interview With the Angry Birds Transform...
Angry Birds Transformers recently transformed and rolled out worldwide. This run-and-gun title is a hit with young Transformers fans, but the ample references to classic Transformers fandom has also earned it a place in the hearts of long-time... | Read more »
Find Free Food on Campus with Ypay
Find Free Food on Campus with Ypay Posted by Jessica Fisher on October 20th, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »
Strung Along Review
Strung Along Review By Jordan Minor on October 20th, 2014 Our Rating: :: GOT NO STRINGSUniversal App - Designed for iPhone and iPad A cool gimmick and a great art style keep Strung Along from completely falling apart.   | Read more »
P2P file transferring app Send Anywhere...
File sharing services like Dropbox have security issues. Email attachments can be problematic when it comes to sharing large files. USB dongles don’t fit into your phone. Send Anywhere, a peer-to-peer file transferring application, solves all of... | Read more »
Zero Age Review
Zero Age Review By Jordan Minor on October 20th, 2014 Our Rating: :: MORE THAN ZEROiPad Only App - Designed for the iPad With its mind-bending puzzles and spellbinding visuals, Zero Age has it all.   | Read more »
Hay Ewe Review
Hay Ewe Review By Campbell Bird on October 20th, 2014 Our Rating: :: SAVE YOUR SHEEPLEUniversal App - Designed for iPhone and iPad Pave the way for your flock in this line drawing puzzle game from the creators of Worms.   | Read more »
My Very Hungry Caterpillar (Education)
My Very Hungry Caterpillar 1.0.0 Device: iOS Universal Category: Education Price: $3.99, Version: 1.0.0 (iTunes) Description: Care for your very own Very Hungry Caterpillar! My Very Hungry Caterpillar will captivate you as he crawls... | Read more »

Price Scanner via MacPrices.net

Deals on 2011 13-inch MacBook Airs, from $649
Daily Steals has the Mid-2011 13″ 1.7GHz i5 MacBook Air (4GB/128GB) available for $699 with a 90 day warranty. The Mid-2011 13″ 1.7GHz i5 MacBook Air (4GB/128GB SSD) is available for $649 at Other... Read more
2013 15-inch 2.0GHz Retina MacBook Pro availa...
B&H Photo has leftover previous-generation 15″ 2.0GHz Retina MacBook Pros now available for $1599 including free shipping plus NY sales tax only. Their price is $400 off original MSRP. B&H... Read more
Updated iPad Prices
We’ve updated our iPad Air Price Tracker and our iPad mini Price Tracker with the latest information on prices and availability from Apple and other resellers, including the new iPad Air 2 and the... Read more
Apple Pay Available to Millions of Visa Cardh...
Visa Inc. brings secure, convenient payments to iPad Air 2 and iPad mini 3as well as iPhone 6 and 6 Plus. Starting October 20th, eligible Visa cardholders in the U.S. will be able to use Apple Pay,... Read more
Textkraft Pocket – the missing TextEdit for i...
infovole GmbH has announced the release and immediate availability of Textkraft Pocket 1.0, a professional text editor and note taking app for Apple’s iPhone. In March 2014 rumors were all about... Read more
C Spire to offer iPad Air 2 and iPad mini 3,...
C Spire on Friday announced that it will offer iPad Air 2 and iPad mini 3, both with Wi-Fi + Cellular, on its 4G+ LTE network in the coming weeks. C Spire will offer the new iPads with a range of... Read more
Belkin Announces Full Line of Keyboards and C...
Belkin International has unveiled a new lineup of keyboard cases and accessories for Apple’s newest iPads, featuring three QODE keyboards and a collection of thin, lightweight folios for both the... Read more
Verizon offers new iPad Air 2 preorders for $...
Verizon Wireless is accepting preorders for the new iPad Air 2, cellular models, for $100 off MSRP with a 2-year service agreement: - 16GB iPad Air 2 WiFi + Cellular: $529.99 - 64GB iPad Air 2 WiFi... Read more
Price drops on refurbished Mac minis, now ava...
The Apple Store has dropped prices on Apple Certified Refurbished previous-generation Mac minis, with models now available starting at $419. Apple’s one-year warranty is included with each mini, and... Read more
Apple refurbished 2014 MacBook Airs available...
The Apple Store has Apple Certified Refurbished 2014 MacBook Airs available for up to $180 off the cost of new models. An Apple one-year warranty is included with each MacBook, and shipping is free.... Read more

Jobs Board

Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Position Opening at *Apple* - Apple (United...
…customers purchase our products, you're the one who helps them get more out of their new Apple technology. Your day in the Apple Store is filled with a range of Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** At the Apple Store, you connect business professionals and entrepreneurs with the tools they need in order to put Apple solutions to work in their Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** The Apple Store is a retail environment like no other - uniquely focused on delivering amazing customer experiences. As an Expert, you introduce people Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.