TweetFollow Us on Twitter

Aug 99 Getting Started

Volume Number: 15 (1999)
Issue Number: 8
Column Tag: Getting Started

Printing

By Dan Parks Sydow

How a Mac program sends document data to a printer

In the previous few Getting Started articles we've focused on the use of files to provide users of your Macintosh applications with the means to save program output. This month we'll look at a second data-saving technique - printing. By adding printing capabilities to your program, both text and graphics can be sent to any printer that's attached to the user's computer.

Printing Basics

In this article you'll see how to write a program that displays the two standard printing dialog boxes found in most Mac programs. The Printing Style dialog box, shown in Figure 1, allows the user to select page preferences such as page orientation. The Printing Job dialog box, pictured in Figure 2, lets the user specify the print quality and the page range. For reasons explained ahead, the dialog boxes you see on your Mac may look somewhat different than the ones shown here.



Figure 1.A typical Printing Style dialog box.



Figure 2.A typical Printing Job dialog box.

Your program can display both the Printing Style and Printing Job dialog boxes through the use of Printing Manager routines. Like other Toolbox managers, the Printing Manager is a collection of system software routines. Unlike the other managers, the code that makes up each Printing Manager routine isn't found in ROM or in the System File. Rather, the Toolbox printing routines are nothing more than empty shells, or stub routines. When your application makes a call to a Toolbox printing function, the program is directed to code that exists in a printer resource file. Printer resource files enable the Printing Manager to work with all printers that come with a Macintosh printer driver.

When an application calls a routine from a manager other than the Printing Manager, the program jumps to Toolbox code that originates in ROM or in the System File. The code that makes up that one routine - whatever routine it is - is then carried out. If the call is to, say, Line(100, 0), QuickDraw draws a line 100 pixels long to the current port. This is true regardless of the kind of monitor hooked up to the Mac. For printers, this “one generic code works on all” principle doesn't apply. There are countless third-party printers that can be hooked up to a Macintosh, and no uniform standard of how Toolbox calls should be handled by a printer. So Apple leaves it up to the manufacturer of each printer to supply the code that makes the printing functions work. This code is found in the printer resource file that accompanies a printer that is Mac-compatible.

Every printer that works with a Macintosh comes supplied with a printer resource file. This file, which is placed in the Extensions folder in the System Folder, holds the code that actually carries out Printing Manager routines. The file, which has a name that often includes the name of the printer, must be present in order for the printer to function. Since each type of printer has its own printer resource file, and since a Macintosh can have more than one printer connected to it, a Mac can have more than one printer resource file. The printer (and thus the printer resource file) that a Macintosh uses is governed by the Chooser program found under the Apple menu.

The printer resource file holds resources of several types. Resources of type PDEF are printer definition functions - they hold the compiled code that executes when a Printing Manager function is called. When a Mac application makes a call to a Printing Manager routine the call is routed to the printer resource file. There, the code that makes up one of the many PDEF resources is loaded and executed. By having each printer manufacturer support all the same Printing Manager routines, the burden of worrying about which printer is connected to a user's system is lifted from the Macintosh software developer. When you write an application that calls Printing Manager routines, you won't have to consider the type of printer that any one user might have. Instead, just make the function call. It will be up to the printer resource file to handle that function call as is appropriate for that printer.

Printing Manager Basics

Like all of the Toolbox managers, the Printing Manager consists of a wealth of functions. But to get started with printing, you'll need to use only a handful of them.

The Print Record

Before printing, your application must create a print record. This record holds information specific to the printer being used, such as its resolution, and information about the document that is to be printed, such as scaling, page orientation, and the number of copies to print.

In C, the print record is represented by a struct of the type TPrint. Before any printing takes place, your application must allocate memory for a TPrint structure and obtain a handle - a THPrint handle - to that memory. By the way, the T in THPrint stands for type, and the H stands for handle - you'll see this notation used throughout the functions of the Printing Manager. You can make a call to the Memory Manager routine NewHandle() or NewHandleClear() to reserve the needed memory and to receive a handle to that memory. Include the size of a print record as the parameter and cast the returned generic pointer to a THPrint handle.

THPrint	printRecord;
printRecord = (THPrint)NewHandleClear( sizeof (TPrint) );

After creating a new print record, call the Printing Manager routine PrintDefault() to fill the record with default values. These values will serve as initial values until the user selects Page Setup and Print from the File menu of your application. The values entered in the corresponding dialog boxes will overwrite some or all of the values supplied by PrintDefault().

PrintDefault( printRecord );

Printing Manager Functions

Knowledge of less than a dozen Printing Manager functions is all that's needed to get your Mac application printing. As you read this section, note that each of the three Open functions is paired with a Close function: calls to PrOpen(), PrOpenDoc(), and PrOpenPage() are balanced with calls to PrClose(), PrCloseDoc() and PrClosePage(), respectively.

The code to execute Printing Manager functions resides in a resource file, so your program needs to open this resource file before its code can be accessed. The Printing Manager function PrOpen() prepares the current printer resource file for use. The current printer is whichever printer was last selected in the Chooser. Preparation consists of opening both the Printing Manager and the printer resource file for the current printer. When finished with the resource file, a call to PrClose() closes the Printing Manager and the printer resource file.

PrOpen();
// printing-related code here
PrClose();

PrOpenDoc() initializes a printing graphics port. This graphics port isn't associated with any window - it's associated with the printer. When a window's graphics port is current (by way of a call to SetPort()), drawing takes place on the screen. When a printing graphics port is current (by way of a call to PrOpenDoc()), drawing operations are routed to the printer. Once a printing graphics port is current, all QuickDraw commands are sent to the printer.

When passed a handle to a print record, PrOpenDoc() allocates a new printing graphics port and returns a TPPrPort to the application. The TPPrPort is a pointer to a printing graphics port. PrOpenDoc() requires a second and third parameter, each of which can normally be set to nil. The second parameter can be used when an application wants to pass in a pointer to an existing printing graphics port, and the third parameter can be used to allocate a particular area in memory to serve as an input and output buffer.

PrCloseDoc() closes a printing graphics port. Make a single call to PrCloseDoc() after the last page of a document has been sent to the printer. Pass PrCloseDoc() the pointer to the printing graphics port that was returned by PrOpenDoc().

TPPrPort	printerPort;
printerPort = PrOpenDoc( printRecord, nil, nil );
// print page(s) here
PrCloseDoc( printerPort );

PrOpenPage() is used to begin printing a single page of a document. Pass PrOpenPage() the pointer to the printing graphics port that was obtained in the PrOpenDoc() call. The second parameter is used only for deferred printing - a delayed printing feature that is normally used only on older printers. You can usually set this parameter to nil. After a call to PrOpenPage() is made, all the QuickDraw commands necessary to output one page of a document should be made. After that, call PrClosePage().

PrClosePage() signals the end of the current page. Once a call to PrClosePage() is made, the Printing Manager will stop accumulating QuickDraw calls. PrClosePage() requires a single parameter - the pointer to the printing graphics port that was returned by PrOpenDoc().

PrOpenPage( printerPort, nil );
// QuickDraw calls that define what's to be printed
PrClosePage( printerPort );  

Before printing, you'll want to give the user the opportunity to specify printing style options. A call to PrStlDialog() displays a Printing Style dialog box that allows the user to do just that. If your application has a Page Setup menu item, make a call to PrStlDialog() in response to a user's selection of this menu item. The Printing Style dialog box is defined in the resource file of the printer driver, so its exact look is dependent on the printer in use - this is why a Printing Style dialog box that you view may not look just like the one shown back in Figure 1.

The PrStlDialog() function requires a handle to a TPrint record as its one parameter. If the user clicks the Printing Style dialog box OK button, the values entered in that dialog box (such as page orientation) will be placed in the TPrint record. PrStlDialog() will then return a value of true. If the user clicks the Cancel button, the TPrint record will be unaffected and the routine will return a value of false.

PrStlDialog( printRecord );

Displaying the Printing Style dialog box saves document printing information, but not the number of copies or the range of pages to print. To do that, call PrJobDialog(). This routine will display the Printing Job dialog box. Like the Printing Style dialog box, the look of the Printing Job dialog box is defined in the printer resource file. A call to PrJobDialog() should be made in response to a user's selection of the Print menu item in your application.

PrJobDialog() accepts a handle to a TPrint record as its only parameter. A mouse click on the OK button results in the values in the dialog box (such as number of copies to print) being entered into the TPrint record. PrJobDialog() then returns a value of true to the application. A click on the Cancel button leaves the TPrint record untouched and returns a value of false to the program.

Boolean		doPrint;
doPrint = PrJobDialog( printRecord );
if ( doPrint == false )
	// handle case of user canceling printing

PrintPict

This month's program is PrintPict. To provide you with a very concise, straightforward example of the primary functions of the Printing Manager, PrintPict is a simple, non-menu-driven program. When run, PrintPict displays the Printing Style dialog box - the dialog box normally brought on by choosing Page Setup from the File menu. After clicking the OK button, the program dismisses that dialog box and displays the Printing Job dialog box - the dialog box normally brought on by choosing Print from the File menu. After clicking the Print button, the program dismisses that dialog box and sends the printing job to the printer. After that the program quits. Without menus and without giving the user any control of what to print, the PrintPict program certainly doesn't qualify as user-friendly. But, much more importantly, it does show you, in just a page or two of code, how to make use of the Printing Manager.

Creating the PrintPict Resources

Start the project by creating a new folder named PrintPict in your CodeWarrior development folder. Launch ResEdit, then create a new resource file named PrintPict.rsrc. Make sure to specify the PrintPict folder as the resource file's destination. The resource file will hold resources of the types shown in Figure 3.



Figure 3.The PrintPict resources.

The one ALRT and one DITL resource are used to define the program's error-handling alert. The only other resource needed is a single PICT. It's this picture that will be printed by the PrintPict program. Feel free to use any picture of any reasonable size here. If you have a color printer, go ahead and include a color picture so that you can verify that the PrintPict program prints in color.

Creating the PrintPict Project

Start CodeWarrior and choose New Project from the File menu. Use the MacOS:C_C++:MacOS Toolbox:MacOS Toolbox Multi-Target project stationary for the new project. You've already created a project folder, so uncheck the Create Folder check box before clicking the OK button. Name the project PrintPict.mcp, and make sure the project's destination is the PrintPict folder.

Add the PrintPict.rsrc resource file to the new project. Remove the SillyBalls.rsrc file. Go ahead and remove the ANSI Libraries folder from the project window if you want - the project doesn't use any of these libraries.

Create a new source code window by choosing New from the File menu.. Save the window, giving it the name PrintPict.c. Now choose Add Window from the Project menu to add this empty file to the project. Remove the SillyBalls.c placeholder file from the project window. You're all set to type in the source code.

To save yourself some typing, go to MacTech's ftp site at ftp://ftp.mactech.com/src/mactech/volume15_1999/15.08.sit. There you'll find the PrintPict source code file available for downloading.

Walking Through the Source Code

Because the PrintPict program isn't event-driven, the listing is shorter than our other example listings. PrintPict.c starts with a couple of constants. kALRTResID defines the ID of the ALRT resource used to define the error-handling alert. kPICTResID defines the ID of the PICT resource that holds the picture to print.

/********************* constants *********************/
#define 		kALRTResID			128
#define		kPICTResID			128

PrintPict declares just one global variable. The THPrint variable gPrintRecord is the print record that holds information about the currently selected printer. While in PrintPict we could get away with declaring this variable local to main(), it's been declared global for future use. If we expand upon the PrintPict program we'll put the print record to use in a variety of routines. For instance, if we later implement a File menu that includes a Print item, then the display of the printing job dialog box will no doubt be handled by a separate application-defined function. A call to PrJobDialog() requires the print record as a parameter.

/****************** global variables *****************/
THPrint		gPrintRecord;

Next come the program's function prototypes.

/********************* functions *********************/
void		ToolBoxInit( void );
void		DrawToPort( void );
void		DoError( Str255 errorString );

The main() function begins with the declaration of a couple of variables. The TPPrPort variable printerPort is a pointer to a printing graphics port. This variable will get its value from a call to PrOpenDoc(). The Boolean variable doPrint tells the program whether the Printing Job dialog box was dismissed with a click on the Print or the Cancel button. Next, the Toolbox is initialized by way of a call to ToolBoxInit().

/********************** main *************************/
void		main( void )
{
	TPPrPort		printerPort;
	Boolean		doPrint;
	ToolBoxInit();

A new print record is then created. A call to PrOpen() prepares the current printer resource file for use. PrintDefault() fills the new print record with default values.

	gPrintRecord = (THPrint)NewHandleClear( sizeof( TPrint ) );
	PrOpen();
	PrintDefault( gPrintRecord );

Next, the Printing Style dialog box is displayed. The call to PrStlDialog() does all the work of monitoring the user's actions in this dialog box. In a full-featured program we'd make this call in response to the user choosing Page Setup from the File menu.

	PrStlDialog( gPrintRecord );

Once the Printing Style dialog box is dismissed, a call to PrJobDialog() displays the Printing Job dialog box. If the user clicks the Print button, PrJobDialog() returns a value of true, and the program continues on. If the user cancels printing, the program ends. In your own application you won't need to abruptly exit should the user cancel printing - you'll typically just carry on.

	doPrint = PrJobDialog( gPrintRecord );
	if ( doPrint == false )
		DoError( "\pUser canceled printing" );

If printing is to take place, the program calls PrOpenDoc() to initialize a printing graphics port. A pointer to the new port is returned and saved in the variable printerPort.

	printerPort = PrOpenDoc( gPrintRecord, nil, nil );

A call to PrOpenPage() begins the printing of a page. After this call all subsequent QuickDraw commands are routed to the printer. While the QuickDraw calls could have appeared here in main(), we'll group them in an application-defined function named DrawToPort().

	PrOpenPage( printerPort, nil );
	DrawToPort( kPICTResID );

We'll look at DrawToPort() just ahead. Regardless of the contents of that routine, once DrawToPort() returns, the printing of a page is complete - so we can wrap things up. A call to PrClosePage() balances the previous call to PrOpenPage(). Similarly, a call to PrCloseDoc() balances the prior call to PrOpenDoc(). Finally, a call to PrClose() pairs with the earlier call to PrOpen(), and closes the Printing Manager and the printing resource file.

	PrClosePage( printerPort );  
	PrCloseDoc( printerPort );
	PrClose();
}

As expected, ToolBoxInit() is identical to previous versions.

/******************** ToolBoxInit ********************/
void		ToolBoxInit( void )
{
	InitGraf( &qd.thePort );
	InitFonts();
	InitWindows();
	InitMenus();
	TEInit();
	InitDialogs( nil );
	InitCursor();
}

The DrawToPort() function holds the code that defines what is to be printed. PrintPict prints a picture, so the code in DrawToPort() loads a PICT resource to memory and then draws that picture. A call to GetPicture() moves the PICT code to memory.

void DrawToPort( void )
{
 	PicHandle	pict;
	Rect				rect;
	short			width;
	short			height;
	short			L, R, T, B;
	pict = GetPicture( kPICTResID );

Next, the size of the picture is determined. The picFrame field of the picture record referenced by the handle pict supplies that information. A little offsetting is done in case the picFrame rectangle boundaries aren't located at (0, 0).

	rect = (**pict).picFrame;
	width = rect.right - rect.left;
	height = rect.bottom - rect.top;

Now we determine where on the page we want the picture printed. The upper-left corner of the page is at coordinate (0, 0). By setting up a rectangle with a upper-left coordinate at (75, 50) we're telling the program to start the picture 75 pixels from the left of the page and 50 pixels from the top of the page.

	L = 75;
	R = L + width;
	T = 50;
	B = T + height;
	SetRect( &rect, L, T, R, B );

A call to DrawPicture() draws the picture. The current port has been set to the printer, so that's where "drawing" takes place. Finally, a call to ReleaseResource() frees the memory occupied by the picture.

	DrawPicture( pict, &rect ); 
	ReleaseResource( (Handle)pict );
} 

We've placed all the printing code in this one function for a good reason - it makes it easy to experiment. After successfully compiling and running the program you may want to replace the contents of DrawToPort() with other QuickDraw calls, such as a few calls to MoveTo() and Line(). Calls to DrawString() work too. DoError() is unchanged from prior versions. A call to this function results in the posting of an alert that holds an error message. After the alert is dismissed the program ends.

/********************** DoError **********************/
void		DoError( Str255 errorString )
{
	ParamText( errorString, "\p", "\p", "\p" );
	StopAlert( kALRTResID, nil );
	ExitToShell();
}

Running PrintPict

Run PrintPict by selecting Run from CodeWarrior's Project menu. After compiling the code and building a program, CodeWarrior runs the program. The Printing Style dialog box will automatically open. Look it over, make some changes if you'd like (including scaling the size of the picture), then click the OK button. After the style dialog box is dismissed, the Printing Job dialog box appears. Click the Print button and the dialog box is dismissed. The program quits, and a short time later your printer prints out a picture.

Till Next Month...

The PrintPict program provides a look at the very basics of sending information to a printer. Use your newfound knowledge of the Printing Manager to add Page Setup and Print commands to your program's File menu. In response to a print command you'll want to send the information from the frontmost window to the printer. Your program should already hold the code necessary to update a window, so your program already contains most of the code necessary to print! When a print command is issued, you'll specify that the port to "draw" to should be the printer - not the window. For the details on how to do this, browse through the Imaging With QuickDraw volume of Inside Macintosh. Or, wait until next month's issue of MacTech...

 
AAPL
$432.00
Apple Inc.
+1.95
MSFT
$35.00
Microsoft Corpora
+0.60
GOOG
$886.25
Google Inc.
+11.21

MacTech Search:
Community Search:

Software Updates via MacUpdate

Duplicate Annihilator 4.9.0 - Find and d...
Duplicate Annihilator takes on the time-consuming task of comparing the images in your iPhoto library using effective algorithms to make sure that no duplicate escapes. When found, the duplicate will... Read more
Bookends 12.0.0 - Reference management a...
Bookends is a full featured bibliography/reference and information management system for students and professionals. Access the power of Bookends directly from Mellel, Nisus Writer Pro, or MS Word... Read more
iTubeX 9.3 - Download videos, mp3, and s...
iTubeX allows you to download videos (Flash, HTML5 and others), .mp3 and .swf files from almost every website as easily as possible. You can also choose to save only the audio of a video as a .mp3... Read more
SlingPlayer Plugin 3.3.18.400 - Browser...
SlingPlayer is the screen interface software that works hand-in-hand with the hardware inside the Slingbox to make your TV viewing experience just like that at home. It features an array of... Read more
Cornerstone 2.7.10 - Feature-rich Subver...
Cornerstone allows you to take control of Subversion with a client application that was specifically designed for Mac users. Cornerstone integrates all of the features you need to interact with your... Read more
Xcode 4.6.3 - Integrated development env...
Apple Xcode is Apple Computer's integrated development environment (IDE) for OS X. The full Xcode package is free to ADC members and includes all the tools you need to create, debug, and optimize... Read more
Cobook Contacts 1.2.8 - Intelligent addr...
Cobook Contacts is an intuitive, engaging address book. Solve the problem of contact management with Cobook Contacts and its simple interface and powerful syncing and integration possibilities.... Read more
Tidy Up 3.0.7 - Find duplicate files and...
Tidy Up is a complete duplicate finder and disk-tidiness utility. With Tidy Up you can search for duplicate files and packages by the owner application, content, type, creator, extension, time... Read more
Microsoft Office 2011 14.3.5 - Popular p...
Microsoft Office 2011 helps you create professional documents and presentations. And since Office for Mac 2011 is compatible with Office for Windows, you can work on documents with virtually anyone... Read more
Adobe Flash Player 11.7.700.225 - Multim...
Adobe Flash Player is a cross-platform, browser-based application runtime that provides uncompromised viewing of expressive applications, content, and videos across browsers and operating systems.... Read more

Mail Ninja Review
Mail Ninja Review By Jennifer Allen on June 17th, 2013 Our Rating: :: SIMPLE MAIL SORTINGiPhone App - Designed for the iPhone, compatible with the iPad Favoring simplicity over complexity, Mail Ninja won’t be the email solution for... | Read more »
Beejumbled Review
Beejumbled Review By Jennifer Allen on June 17th, 2013 Our Rating: :: SIMPLE WORDPLAYUniversal App - Designed for iPhone and iPad A simple but cute word game, Beejumbled should keep word game fans bzzzzy for a time.   | Read more »
Angry Birds Update Flies Near As Rovio T...
Angry Birds Update Flies Near As Rovio Teases New Level Pack Posted by Andrew Stevens on June 17th, 2013 [ permalink ] A new Angry Birds update is on the way as Rovio posted an image on | Read more »
The Official Guide to Star Command HD Is...
The Official Guide to Star Command HD Is Out, Provides Tactical Strategies To Win Posted by Andrew Stevens on June 17th, 2013 [ permalink ] | Read more »
Bill Nye The Science Guy Promotes Scienc...
Bill Nye The Science Guy Promotes Science, Lets You Watch Favorite Clips Posted by Andrew Stevens on June 17th, 2013 [ permalink ] | Read more »
Clash of Clans Launches New Battle Spell...
Clash of Clans Launches New Battle Spells and Advanced Warfare In Latest Update Posted by Andrew Stevens on June 17th, 2013 [ permalink | Read more »
Perfection. Review
Perfection. Review By Carter Dotson on June 17th, 2013 Our Rating: :: REALLY GOODUniversal App - Designed for iPhone and iPad Perfection is a line-slicing puzzle game with no stars, no scores, just gameplay.   | Read more »
AT&T Update Will Provide Wireless Em...
AT&T Update Will Provide Wireless Emergency Alert System Posted by Andrew Stevens on June 17th, 2013 [ permalink ] | Read more »
Gangstar Vegas Review
Gangstar Vegas Review By Blake Grundman on June 17th, 2013 Our Rating: :: BUSTEDUniversal App - Designed for iPhone and iPad It is always unfortunate when bugs derail what could have been a great game.   | Read more »
How To: Listen to Lossless Music
Most digital music nowadays sounds slightly worse than it does on CD, thanks to audio compression. This is great for quickly downloading music, but not best for audio quality. If you want to listen to music on your iOS device without that pesky... | Read more »

Price Scanner via MacPrices.net

15-inch Retina MacBook Pros on sale for $200 off M...
 B&H Photo has 15″ Retina MacBook Pros on sale for $200 off MSRP including free shipping. B&H will also include free copies of Parallels Desktop, Bento Database, and LoJack for Laptops... Read more
Apple refurbished iMacs available for up to $330 o...
Apple has Apple Certified Refurbished 2012 iMacs in stock today for up to $330 off MSRP – 15% off. Each iMac comes with an Apple one-year warranty, and shipping is free: - 21″ 2.7GHz iMac: $1099 $100... Read more
Save up to $200 on MacBook Pros with Apple Educati...
Purchase a new MacBook Pro at The Apple Store for Education, and take up to $200 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free... Read more
Save up to $100 on iMacs with Apple Education disc...
Take up to $100 off the price of a new 21″ or 27″ iMac at The Apple Store for Education. All students, teachers, and staff at any educational institution qualify for the discount, and shipping is... Read more
Microsoft Makes Office Mobile Support For iPhone (...
Microsoft Office Division General Manager Julia White announced Friday that Microsoft is releasing Office Mobile for iPhone, which will be available at no extra charge from the Apple App Store for... Read more
Tablet Computers Supplementing — Not Displacing —...
The technological world moves incredibly fast, with cutting edge trends sometimes getting pushed to the edge of the information and entertainment superhighway almost before the digital ink of their... Read more
iOS 7 Beta Adoption Accelerates Rapidly Past Previ...
Chitika Insights notes: On June 10, 2013, as part of its Worldwide Developer Conference (WWDC), Apple unveiled its latest redesign for its iOS operating system (OS). Since that time, developers have... Read more
Shootout: 2013 MacBook Air versus 2012 MacBook Air
BareFeats’ rob-ART morgan says the ‘mid-2013′ MacBook Air has some key enhancements over the 2012 MacBook Air, with the new model’s flash storage dramatically faster than the flash storage in both... Read more
13″ MacBook Pro on sale for $100 off MSRP
Amazon.com has lowered their price on the 13″ 2.5GHz MacBook Pro to $1099.99 including free shipping. Their price is $100 off MSRP. Read more
27″ iMacs on sale for $150 off MSRP
B&H Photo has 27-inch iMacs on sale for $150 off MSRP: - 27″ 3.2GHz iMac: $1849.99 - 27″ 2.9GHz iMac: $1649.99 Shipping is free, and there is NY sales tax only. B&H will also include free... Read more

Jobs Board

*Apple* Retail - Manager - Apple (Unite...
Job SummaryKeeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, youre a master of them all. In the stores fast-paced, dynamic Read more
*Apple* - Solution Architect - CompuCom...
Job Location: US-TX-Dallas Posted Date: 4/18/2013 Overview: The Apple Solution Architect (SA) will be responsible for supporting pre-sales and post-sales solutions in Read more
*Apple* Support Technician; Mid-level -...
A Kforce client in Washington, DC area is seeking an Apple Support Technician. This contractor will have the following types of responsibilities including, but not Read more
Systems Engineer - *Apple* TV - Apple...
Job Summary The Apple TV team is looking for an experienced engineer with a passion for delivering first in class home entertainment solutions. The individual must be Read more
*Apple* Support Technician - Mid - URS...
…Business Operations/Admin/IT Interest Sub Category: Information Technology Job Title : Apple Support Technician - Mid Employment Category/Status: full-time Type of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.