TweetFollow Us on Twitter

Jun 99 Getting Started

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

Resource Templates

by Dan Parks Sydow

How a Mac programmer defines custom resources to hold program data

In last month's Getting Started article we looked at how a Mac program works with resources stored in resource files. This month we carry on with our look at resources. Rather than work with resources of the standard types such as WIND, MENU, and DLOG, though, we're now ready to work with custom resources of our own design.

By now you're very familiar with how a program works with standard resources. With a little extra effort your program can also work with resources that you define. While the predefined resource types suffice for use with program interface elements such as windows, menus, and dialog boxes, they won't due if your program wants to store application-specific data in a resource. Last month's Getting Started article demonstrated how a program can easily make use of resources stored in an external resource file. One good use of an external resource file is for the storing of application data - particularly program preferences.

Resource Templates

Graphical resource editors like Apple's ResEdit and Mathemaesthetics' Resorcerer depend on templates to make resource editing easy. A template displays the value, or values, that make up a single resource of a single resource type. For example, you use the MBAR template to edit the strings in an MBAR resource. When working with a resource editor such as ResEdit, this use of templates is invisible. You double-click on a resource, and ResEdit uses the template associated with that resource type as the means for formatting and displaying the data held in the resource. Figure 1 shows a menu bar resource being edited with the use of the MBAR template. The template, which is built into ResEdit, displays the IDs of the menus that the menu bar resource defines to be a part of one menu bar.


Figure 1. An MBAR resource as viewed with the MBAR template.

You don't have to use the built-in MBAR template when viewing an MBAR resource. If you click on an MBAR resource and then choose Open Using Hex Editor from the Resource menu, you'd see the resource values in a window like the one shown in Figure 2. After looking at this window, though, you'll see that the use of a template makes viewing a resource's data much clearer.


Figure 2. Viewing an MBAR resource without the use of the MBAR template.

ResEdit supplies templates for dozens of the commonly used resource types, including the ALRT, DITL, and DLOG, MBAR, and MENU resources. For most of your programming needs, these built-in templates are all that you'll ever need. If you want to store your own data structures in a resource file, however, you'll want to create your own template so that you can view and edit your data in a simple fashion. You'll also want to create your own data-holding resources - the resources that ResEdit will format with the new template. Fortunately, ResEdit makes it easy to add your own template and custom resources to a resource file. On the following pages we'll create both a template and a custom resource. And to save a little work, the template and resource we create will be the same ones we'll use in this month's example program.

Creating a Resource Template

Using ResEdit, a new resource of any type is created by choosing Create New Resource from the Resource menu. In the dialog that appears you see the standard resource types named in a list. A template is itself a resource - a resource of the type TMPL. Double-click on TMPL in the list and ResEdit creates a new, empty template - as shown in Figure 3.


Figure 3. A new, empty TMPL resource.

The template resource itself won't be used by your application. Instead, it serves as nothing more than a tool to tell ResEdit how to display data of a particular type in ResEdit. That means you need to specify which resource type the new template is to affect. Do this by clicking on the template's ID in the TMPL window of the resource file, and then choosing Get Resource Info from the Resource menu. In the dialog box that opens, type in the name of the resource type that the template should format. At this time you'll need to think of a name for the data-holding resources you'll soon be creating. That is, you're creating a format-defining template resource now, and you'll be creating the actual data-holding custom resource (or resources) later. In Figure 4 you see that for our example the new template is named TSTD, for "TeST Data." When you choose to define a new resource type, keep in mind that the name should be four characters, but that Apple reserves type names that appear in all lowercase. So make sure to include at least one uppercase character in your template's name.


Figure 4. Giving the new template a name.

After closing the Info window, it's time to edit the template. The template will have an item for each data element that will be in a (yet-to-be-created) TSTD resource. Of course if you choose to give your template a different name, then your template won't be used to format TSTD resources. Rather, it will be used to format resources of the type you specify.

A template item provides a label for the data element and specifies the type of data that the element is. Imagine that our TSTD resource will hold just a single data element, and that this data element will be a two-byte number. In C, such a number could be represented by a short variable. In the template, there should be a single item that corresponds to this one data element. Figure 5 shows what this item would look like.


Figure 5. A template resource that defines one data field.

A template item can have any label, but the label should be somewhat descriptive of what the data element is or what it will be used for. The label write was selected because in the program code this value will be used as a flag to determine whether the program should write to a window. The item has to have a type, and it must be one of the types that ResEdit recognizes. ResEdit doesn't recognize C, or Pascal, or any other standard programming language. Instead, it has it's own simple set of data types. For a two-byte value, ResEdit defines the DWRD type. DWRD stands for decimal word. The most commonly used ResEdit types are:

DWRD
2-byte word decimal field (maximum value of 32,767)
DLNG
4-byte long word decimal field (maximum value of 2,147,483,647)
PSTR
Pascal string field (though no leading "\p" is required)
CHAR
1-byte character field
RECT
Rectangle field, displaying four coordinate holding edit boxes (T, L, B, R)

A template can of course hold more than one item - but for this introduction we'll stop at one item so that we can run a test that proves the template works. Then we'll go back and add a couple of more items to this same template.

Creating a Custom Resource

To create a custom resource - one of a type not defined by ResEdit - choose Create New Resource from the Resource menu. You're creating a resource of your own resource type, so don't look for the type in the list in the Select New Type dialog box. Instead, type in the edit box the four characters that make up the custom type. This resource type should match the template type you defined earlier. For our example, that would be TSTD. Click the OK button and a new TSTD resource appears. As shown in Figure 6, the resource will be formatted using the TSTD template (compare the TSTD resource in Figure 6 with the TSTD template resource shown back in Figure 5).


Figure 6. A custom TSTD resource displayed using the TSTD template.

Now that we're satisfied that we can create data-holding resources that will be easily viewable and editable with our own template, it's time to go back to the template resource and add a couple of more items to it. Open the resource file's one TMPL resource, click on the area where a second item is to be added (the "2) *****" string), and choose Insert New Field(s) from the Resource menu. Type in a label and a type. Repeat for each item that is to appear in the template. As shown in Figure 7, for our TSTD template we'll have three fields: a 2-byte number, a 4-byte number, and a string.


Figure 7. The TSTD template with three items.

Our example program will eventually use the data that's held in one TSTD resource. The program will look at the value of the write item to see if the other TSTD resource data should be written to a window. A write value of 0 means no, a write value of 1 means yes. The score item will hold a high score (we'll assume we're writing a game), and the name item will hold the name of the person who holds the high score. The details of how the program accesses this data become evident just ahead.

Next, open the one existing TSTD resource. Because the template this resource uses has been altered (we've added two items), you'll see an alert that warns you that items are being added to the TSTD resource. After dismissing the alert you'll see that the TSTD resource now has edit boxes for entering values for the three items. In Figure 8 you see values entered in each item.


Figure 8. A TSTD resource with three items.

Now let's see how our TSTD resource would be viewed in ResEdit if there wasn't a corresponding TSTD template. Figure 9 shows the TSTD resource pictured in Figure 8 - but here it's opened using ResEdit's hex editor. The same data is present, it's just not formatted in a manner that's easy to view and easy to edit.


Figure 9. A TSTD resource viewed without the aid of a template.

For any given resource type, you only need to create one template resource. Now that our TMPL resource of type TSTD is completed, any newly created TSTD resource will use it. To verify that, choose Create New Resource from the Resource menu, type in TSTD as the resource type, and click the OK button. Figure 10 shows that ResEdit creates a new empty resource and displays it with the help of the TSTD template.


Figure 10. A new TSTD resource automatically uses the TSTD template.

Using Custom Resource Data in an Application

When a Mac application makes a call to GetNewWindow(), information from a WIND resource is loaded into a WindowRecord data structure. The program is then provided with a pointer to this structure:

WindowPtr   wind;

wind = GetNewWindow( 128, nil, (WindowPtr)-1L );

Your program can use the WindowPtr variable to obtain information stored in the WindowRecord. That's possible because the WindowRecord data type is defined in the universal header files and is known to the Toolbox.

When you want an application that you're writing to access information from a resource type that you've defined, you'll have to supply the application with the format in which the data is stored. Just as a program needs to recognize a WindowRecord data structure before it can work with the data from a WIND resource, your application needs to have a data structure defined for any programmer-defined resource type.

Consider our own TSTD resource. Any resource of that type contains values that correspond to a C language short, long, and Str255 - in that order. That means an application that is to use a TSTD resource needs to define a data structure that matches this format. Here's that structure:

typedef  struct
{   
   short      write;
   long       score;
   Str255     name;
} TemplateRecord, *TemplatePtr, **TemplateHandle;

While we've given each field a name that corresponds exactly to the label of a TSTD resource item, that naming scheme isn't a requirement. As long as the data structure consists of fields that are of data types that match the resource item data types, the structure is valid.

Now, when the application needs to access information from a TSTD resource, it makes a call to the Toolbox routine Get1Resource() to load the resource data into memory and to return a handle to the data.

Handle      dataHandle;

dataHandle = Get1Resource( 'TSTD', 128 );

Get1Resource() can be used to load into memory one resource of any type. The first parameter is the resource type, and the second is the ID of the particular resource to load.

Once the TSTD resource data is loaded into memory, it can be accessed by the application - but not until the application is told the format of the data. Until then, the data appears as just a stream of information in memory. Typecasting the generic dataHandle variable to a TemplateHandle is the way to tell the application how the data is formatted. To gain access to one piece of data, the TemplateHandle is dereferenced twice. Here's how a short variable would be assigned the value of the first item in the TSTD resource.

Handle      dataHandle;
short      resValue;

dataHandle = Get1Resource( 'TSTD', 128 );

resValue = (**(TemplateHandle)dataHandle).write;

After the above code executes, the resValue variable can be used, and the first member of the TSTD data in memory can be ignored. This applies to each of the three TSTD data members: once variables are assigned the values held in the resource, you don't have to use the handle to the resource data. The following snippet loads the TSTD data into memory, then uses assignment statements to extract all of the data from that resource. After the snippet executes, the variables resValue1, resValue2, and resValue3 hold the data that is in the resource.

Handle         dataHandle;
short         resValue1; 
long            resValue2;
Str255         resValue3;
StringPtr   sourceStr;
Size            bytes;
   
dataHandle = Get1Resource( 'TSTD', 128 );
   
resValue1 = (**(TemplateHandle)dataHandle).write;
resValue2 = (**(TemplateHandle)dataHandle).score;
sourceStr = (**(TemplateHandle)dataHandle).name;
bytes = (**(TemplateHandle)dataHandle).name[0] + 1;
BlockMoveData( sourceStr, resValue3, bytes );

After obtaining a handle, each of the first two assignments are straightforward: cast the handle, then dereference it twice to access a struct member. Assigning a value to the Str255 variable requires a little extra work. A string variable is an array of characters, and in C a simple assignment statement can't be made in order to assign the value of one array to another array. Thus an assignment like this next one will result in an error during compilation:

resValue3 = (**(TemplateHandle)dataHandle).name;

Instead of a direct assignment to a Str255 variable, first make the assignment to a pointer:

StringPtr   sourceStr;

sourceStr = (**(TemplateHandle)dataHandle).name;

Next, get the length of the string - it can be found in the first element of the array that holds the string. Add one byte to account for this first length byte. Then use the Toolbox routine BlockMoveData() to copy the the values in the proper number of bytes of memory to the Str255 variable.

Str255      resValue3;
StringPtr   sourceStr;
Size        bytes;

sourceStr = (**(TemplateHandle)dataHandle).name;
bytes = (**(TemplateHandle)dataHandle).name[0] + 1;
BlockMoveData( sourceStr, resValue3, bytes );

Once a program has the resource data stored in a variable, the information can be used just as data in any variable is used. For instance, this next snippet adds the short and long values together and stores the result back into the long variable. The snippet also draws to a window the string held in resValue3.

resValue2 += resValue1;

MoveTo( 20, 60 );
DrawString( resValue3 );

RsrcTemplate

This month's program is named RsrcTemplate. Running RsrcTemplate results in the appearance of the window shown in Figure 11. The RsrcTemplate program doesn't have a menu bar - just click the mouse button to close the window and quit the program.


Figure 11. The RsrcTemplate window.

The RsrcTemplate program does nothing more than prove that the program is successfully accessing the information stored in a custom resource. The number 150800 and the string Dan P Sydow are both stored in the same custom resource. While the very simple RsrcTemplate program may not seem to be doing much, it is in fact doing just enough. By displaying a little information in a window, we know that the work that went into creating a custom resource was successful.

Creating the RsrcTemplate Resources

The project begins with the creation of a new folder named RsrcTemplate in your CodeWarrior development folder. Start ResEdit, then create a new resource file named RsrcTemplate.rsrc. Make sure to designate the RsrcTemplate folder as the resource file's destination. The resource file will hold just three resources: a WIND, a TMPL, and a resource of a custom type - a TSTD.

The one WIND resource is used for a window that displays some of the data from the custom TSTD resource. There will be only two lines of information written in the window (a number and a string), so the exact placement and size of the window isn't important.

If you've followed along with the preceding walkthough of the creation of TMPL and TSTD resources, you already have the template and custom resource created. If you have these resources saved in a file, copy and paste them into the RsrcTemplate.rsrc file. If you haven't created them, go back and read again the discussion on templates and custom resources. When you've finished, your TMPL and TSTD resources should look like the one's pictured in Figure 12.


Figure 12. The TMPL and TSTD resources.

Creating the RsrcTemplate Project

Launch 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. Uncheck the Create Folder check box before clicking the OK button. Name the project RsrcTemplate.mcp, and make sure the project's destination is the RsrcTemplate folder.

Add the RsrcTemplate.rsrc file to the new project, then remove the SillyBalls.rsrc file. The project doesn't make use of any standard ANSI libraries, so feel free to remove the ANSI Libraries folder from the project window.

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

If you want to save the work of typing in source code and creating resources, you can skip all the above steps and instead download the entire RsrcTemplate project folder from MacTech's ftp site at <ftp://ftp.mactech.com/src/mactech/volume15_1999/15.06.sit>.

Walking Through the Source Code

Because the RsrcTemplate program doesn't have menus, and doesn't include event handling (the program quits when the mouse button is clicked), we've got less code than usual to cover.

The program listing begins with a few constant definitions - all of which are resource-related. kWINDResID is the ID of the WIND resource, kTSTDResID is the ID of the custom TSTD resource, and kResTypeTSTD is the constant that defines the four characters that make up the type of our custom resource.

/********************* constants *********************/

#define      kWINDResID            128
#define      kTSTDResID            128
#define      kResTypeTSTD         'TSTD'

In order to let the program know the format of our custom TSTD resource, we need to define a data structure that includes fields that match the order and data type of each item in the TSTD resource. If you alter the TSTD resource (and the corresponding template), you'll need to also alter the struct such that its fields remain in correlation with the resource items.

/******************* data structures *****************/

typedef  struct
{   
   short      write;
   long       score;
   Str255     name;
} TemplateRecord, *TemplatePtr, **TemplateHandle;

RsrcTemplate declares three global variables. The Boolean flag gWriteScoreInfo tells the program whether it should write to a window the high score and name information that's stored in the TSTD resource. The gHighScore variable will hold the value from the score item in the TSTD resource, while the gName variable will hold the string from the name item in the same TSTD resource.

/****************** global variables *****************/

Boolean     gWriteScoreInfo = false;
long        gHighScore;
Str255      gName;

Next come the program's function prototypes.

/********************* functions *********************/

void      ToolBoxInit( void );
void      GetTemplateRsrcValues( void );
void      WriteValuesToWindow( void );

The main() function begins by initializing the Toolbox and opening a window. A call to the application-defined GetTemplateRsrcValues() extracts the data from a TSTD resource. That function stores the value of the first item in the TSTD resource (the write item) in the program's global variable gWriteScoreInfo. The main() function checks the value of gWriteScoreInfo to determine if the remaining TSTD data should be written to the window. If writing should take place, we delegate that work to the application-defined function WriteValuesToWindow(). After that the program simply waits for Button() to return a value of true, indicating that the user clicked the mouse button. At that time main(), and the program, ends.

/*********************** main ************************/

void   main( void )
{    
   WindowPtr   window;

   ToolBoxInit();
   
   window = GetNewWindow( kWINDResID, nil, (WindowPtr)-1L );
   SetPort( window );
   
   GetTemplateRsrcValues();

   if ( gWriteScoreInfo == true )
      WriteValuesToWindow();
   
   while ( !Button() )
      ;
}

ToolBoxInit() needs no discussion - it's the same as prior versions.

/******************** ToolBoxInit ********************/

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

GetTemplateRsrcValues() begins by calling Get1Resource() to load the data from the TSTD resource to memory and to provide the program with a handle to that block of memory.

/*************** GetTemplateRsrcValues ***************/

void  GetTemplateRsrcValues( void )
{
   short       write; 
   Handle      dataHandle;
   StringPtr   sourceStr;
   Size        bytes;
   dataHandle = Get1Resource( kResTypeTSTD, kTSTDResID );

GetTemplateRsrcValues() continues by extracting the individual values from the block of memory that holds all of the resource information. The generic handle that references the memory block is first typecast to a TemplateHandle, then the write field of the TemplateRecord structure is accessed. The value of this field is placed in the local variable write, and the global variable gWriteScoreInfo is then set according to the value of write.

   write = (**(TemplateHandle)dataHandle).write;
   if ( write == 0 )
      gWriteScoreInfo = false;
   else
      gWriteScoreInfo = true;

The second item in the TemplateRecord is now extracted, and the result is stored in the global variable gHighScore.

   gHighScore = (**(TemplateHandle)dataHandle).score;

Now the third and last item in the TemplateRecord is extracted. A local StringPtr variable is first set to point to the name field of the TemplateRecord. The number of bytes in the string are then determined. Finally, that number of bytes are moved into the global variable gName. Recall that a Str255 variable cannot be assigned a string directly (except upon initialization), so this roundabout copying of bytes is necessary.

   sourceStr = (**(TemplateHandle)dataHandle).name;
   bytes = (**(TemplateHandle)dataHandle).name[0] + 1;
   BlockMoveData( sourceStr, gName, bytes );
}

After GetTemplateRsrcValues() executes, the gHighScore variable holds the value that initially came from the score item in the TSTD resource, and the gName variable holds the string that initially came from the name item in that same resource. So at this point the program has stored in its own variables the data it needs - and the TSTD resource and the TemplateRecord are no longer of interest. The WriteValuesToWindow() function is called from main() to write the information from these variables to the program's window. NumToString() converts the value held in the long variable gHighScore to a string, and DrawString() writes the resulting string to the window. Variable gName already holds a string, so that variable is passed directly to DrawString() to write the name to the window.

/**************** WriteValuesToWindow ****************/

void   WriteValuesToWindow( void )
{
   Str255      tempStr;
   MoveTo( 20, 20 );
   NumToString( gHighScore, tempStr );
   DrawString( tempStr );
   MoveTo( 20, 40 );
   DrawString( gName );
}

Running RsrcTemplate

Run RsrcTemplate by selecting Run from CodeWarrior's Project menu. After compiling the code and building a program, CodeWarrior runs the program. No menu bar appears - just a window. If the TSTD resource was properly read into memory, and if the program accessed the values from memory, the program's one window will display two strings - as shown back in Figure 11. When you're satisfied that the displayed information is correct, click the mouse button to end the program.

You can have the window display different information by editing the TSTD resource. Run ResEdit and open the RsrcTemplate.rsrc file and open the file's one TSTD resource. Change the value of the score item and the string in the name item. Note that if you change the write item value to 0, the program won't display anything in the window, as expected. Now save and close the resource file. Open the RsrcTemplate.mcp project and build a new version of the RsrcTemplate program. Running the program will then result in the display of the new TSTD values.

Till Next Month...

The template item data types that were described in this article - DWRD, DLNG, PSTR, CHAR, RECT - may be all you'll need in order to create your own template. But there are several other types ResEdit defines. While Apple's own ResEdit Reference book is dated, it does hold more than a little information that's of use to programmers. For template creation, you'll be interested in the list of data types for template items - it's found in Chapter 5: ResEdit Templates. You can freely download a PDF version of the book at <http://developer.apple.com/techpubs/mac/resedit/resedit-2.html>.

From last month's article you know about resource files - including working with multiple resource files. Now, after reading this month's article, you know how to store program data in a custom resource. Next month we'll tie things together to develop a program that creates a new resource file, creates a new custom resource in that file, and then writes program information to that resource. The program will do all of these feats "on-the-fly" (that is, as it executes). The program will also be able to subsequently open the resource file, access the resource information, and make use of it. If you haven't already guessed, what we're talking about is the process of working with a preferences file.

 
AAPL
$98.38
Apple Inc.
-0.64
MSFT
$43.89
Microsoft Corpora
-0.09
GOOG
$585.61
Google Inc.
-4.99

MacTech Search:
Community Search:

Software Updates via MacUpdate

Drive Genius 3.2.4 - Powerful system uti...
Drive Genius is an OS X utility designed to provide unsurpassed storage management. Featuring an easy-to-use interface, Drive Genius is packed with powerful tools such as a drive optimizer, a... Read more
Vitamin-R 2.15 - Personal productivity t...
Vitamin-R creates the optimal conditions for your brain to work at its best by structuring your work into short bursts of distraction-free, highly focused activity alternating with opportunities for... Read more
Toast Titanium 12.0 - The ultimate media...
Toast Titanium goes way beyond the very basic burning in the Mac OS and iLife software, and sets the standard for burning CDs, DVDs, and now Blu-ray discs on the Mac. Create superior sounding audio... Read more
OS X Yosemite Wallpaper 1.0 - Desktop im...
OS X Yosemite Wallpaper is the gorgeous new background image for Apple's upcoming OS X 10.10 Yosemite. This wallpaper is available for all screen resolutions with a source file that measures 5,418... Read more
Acorn 4.4 - Bitmap image editor. (Demo)
Acorn is a new image editor built with one goal in mind - simplicity. Fast, easy, and fluid, Acorn provides the options you'll need without any overhead. Acorn feels right, and won't drain your bank... Read more
Bartender 1.2.20 - Organize your menu ba...
Bartender lets you organize your menu bar apps. Features: Lets you tidy your menu bar apps how you want. See your menu bar apps when you want. Hide the apps you need to run, but do not need to... Read more
TotalFinder 1.6.2 - Adds tabs, hotkeys,...
TotalFinder is a universally acclaimed navigational companion for your Mac. Enhance your Mac's Finder with features so smart and convenient, you won't believe you ever lived without them. Tab-based... Read more
Vienna 3.0.0 RC 2 :be5265e: - RSS and At...
Vienna is a freeware and Open-Source RSS/Atom newsreader with article storage and management via a SQLite database, written in Objective-C and Cocoa, for the OS X operating system. It provides... Read more
VLC Media Player 2.1.5 - Popular multime...
VLC Media Player is a highly portable multimedia player for various audio and video formats (MPEG-1, MPEG-2, MPEG-4, DivX, MP3, OGG, ...) as well as DVDs, VCDs, and various streaming protocols. It... Read more
Default Folder X 4.6.7 - Enhances Open a...
Default Folder X attaches a toolbar to the right side of the Open and Save dialogs in any OS X-native application. The toolbar gives you fast access to various folders and commands. You just click... Read more

Latest Forum Discussions

See All

Note Review
Note Review By Jennifer Allen on July 29th, 2014 Our Rating: :: TOO SIMPLEiPhone App - Designed for the iPhone, compatible with the iPad Note is a note taking app that’s a little too short on features to be worth its asking price... | Read more »
Chainsaw Warrior Goes on Sale & Ther...
Chainsaw Warrior Goes on Sale & There’s a Chance to Win a Copy of the Original Board Game Posted by Jennifer Allen on July 29th, 2014 [ permalink | Read more »
It Came From Canada: Tiny Tower Vegas
If you go to a casino, you might make a lot of money. If you run a casino, you’re guaranteed to make a lot of money. The choice seems pretty obvious. So while waiting for your shady real estate deals to move forward, get prepared with Tiny Tower... | Read more »
Z Hunter Review
Z Hunter Review By Lee Hamlet on July 29th, 2014 Our Rating: :: RIGHT ON TARGETUniversal App - Designed for iPhone and iPad While it might not necessarily break new ground, Z Hunter has enough tricks up its sleeve to ensure that... | Read more »
Huge Update Comes To Duet, Adding 48 New...
Huge Update Comes To Duet, Adding 48 New Stages Posted by Jennifer Allen on July 29th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Sharknado: The Video Game Available Now....
Sharknado: The Video Game Available Now. Seriously. Posted by Rob Rich on July 29th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Frog Orbs 2 Review
Frog Orbs 2 Review By Nadia Oxford on July 29th, 2014 Our Rating: :: THIS MAGIC IS A TAD MONOTONOUS Universal App - Designed for iPhone and iPad Frog Orbs 2 is repetitive, but younger players should enjoy it nonetheless.   | Read more »
Puzzix Review
Puzzix Review By Jennifer Allen on July 29th, 2014 Our Rating: :: NICE IDEAUniversal App - Designed for iPhone and iPad A little like Tetris, Puzzix is all about piecing together blocks and watching them vanish. It could do with... | Read more »
Cannonball eMail is Now Live – Works Wit...
Cannonball eMail is Now Live – Works With Gmail, Yahoo, Outlook, Hotmail, and AOL Posted by Jessica Fisher on July 29th, 2014 [ permalink ] | Read more »
To The End Review
To The End Review By Lee Hamlet on July 29th, 2014 Our Rating: :: A VICIOUS CYCLEUniversal App - Designed for iPhone and iPad To The End will test players’ patience, timing, and dedication as they try to navigate all 13 levels in... | Read more »

Price Scanner via MacPrices.net

The lowest prices on leftover Retina MacBook...
Best Buy has dropped prices on leftover 13″ and 15″ Retina MacBook Pros by up to $300 off original MSRP on their online store for a limited time. Choose free local store pickup (if available) or free... Read more
Apple Updates MacBook Pro with Retina Display...
Apple today updated its MacBook Pro with Retina display with faster processors and double the amount of memory in both entry-level configurations. MacBook Pro with Retina display features a Retina... Read more
Up to $250 price drop on leftover 15-inch Mac...
B&H Photo has dropped prices on 2013 15″ Retina MacBook Pros by as much as $250 off original MSRP. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.3GHz Retina MacBook Pro: $2349... Read more
Updated MacBook Pro Price Trackers
We’ve updated our MacBook Pro Price Trackers with the latest information on prices, bundles, and availability on the new 2014 models from Apple’s authorized internet/catalog resellers as well as... Read more
Apple updates MacBook Pros with slightly fast...
Apple updated 13″ and 15″ Retina MacBook Pros today with slightly faster Haswell processors. 13″ models now ship with 8GB of RAM standard, while 15″ MacBook Pros ship with 16GB across the board. Most... Read more
Apple drops price on 13″ 2.5GHz MacBook Pro b...
The Apple Store has dropped their price for the 13″ 2.5GHz MacBook Pro by $100 to $1099 including free shipping. Read more
Apple drops prices on refurbished 2013 MacBoo...
The Apple Store has dropped prices on Apple Certified Refurbished 13″ and 15″ 2013 MacBook Pros, with model now available starting at $929. Apple’s one-year warranty is standard, and shipping is free... Read more
iOS 8 and OS X 10.10 To Support DuckDuckGo As...
Writing for Quartz, Dan Frommer reports that Apple’s forthcoming iOS 8 and OS X 10.10 operating systems version updates will allow users to select DuckDuckGo as their default search engine. He notes... Read more
U.K. Hospital Using iPods and iPads To Record...
British news journal GazetteLive’s. Ian McNeal notes that the old “an apple a day keeps the doctor away” proverb is being turned on its head at http://southtees.nhs.uk/hospitals/james-cook/ James... Read more
13-inch 2.5GHz MacBook Pro on sale for $1099,...
Best Buy has the 13″ 2.5GHz MacBook Pro available for $1099.99 on their online store. Choose free shipping or free instant local store pickup (if available). Their price is $100 off MSRP. Price is... Read more

Jobs Board

Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Sr. Product Leader, *Apple* Store Apps - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.