TweetFollow Us on Twitter

MACINTOSH C CARBON

Demonstration Program SysMemRes

Goto Contents

// *******************************************************************************************
// SysMemRes.c
// *******************************************************************************************
//
// This program:
//
// o  Loads a window template ('WIND') resource and creates a window.
//
// o  Allocates a relocatable block in the application's heap, gets its size in bytes, draws
//    the size in the window, and then disposes of the block.
//    
// o  Loads a purgeable 'PICT' resource and a non-purgeable 'STR ' resource and draws them in
//    the window.
//
// o  Checks if any error codes were generated as a result of calls to Memory Manager and
//    Resource Manager functions.
//
// o  Terminates when the mouse button is clicked.
//
// The program utilises the following resources:
//
// o  A 'plst' resource.
//
// o  A 'WIND' resource (purgeable).
//
// o  A 'PICT' resource (purgeable).
//
// o  A 'STR ' resource (non-purgeable).
//
// *******************************************************************************************

// .................................................................................. includes

#include <Carbon.h>

// ................................................................................... defines

#define rWindowResourceID  128
#define rStringResourceID  128
#define rPictureResourceID 128

// ....................................................................... function prototypes

void  main            (void);
void  doPreliminaries (void);
void  doNewWindow     (void);
void  doMemory        (void);
void  doResources     (void);

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

void  main(void)
{  
  doPreliminaries();
  doNewWindow();
  doMemory();
  doResources();

  QDFlushPortBuffer(GetWindowPort(FrontWindow()),NULL);

  while(!Button())
   ;
}

// *************************************************************************** doPreliminaries

void  doPreliminaries(void)
{
  MoreMasterPointers(32);
  InitCursor();
}

// ******************************************************************************* doNewWindow

void  doNewWindow(void)
{
  WindowRef windowRef;

  windowRef = GetNewCWindow(rWindowResourceID,NULL,(WindowRef) -1);
  if(windowRef == NULL)
  {
    SysBeep(10);
    ExitToShell();
  }

  SetPortWindowPort(windowRef);
  UseThemeFont(kThemeSystemFont,smSystemScript);
}

// ********************************************************************************** doMemory

void  doMemory(void)
{
  Handle theHdl;
  Size   blockSize;
  OSErr  memoryError;
  Str255 theString;
  
  theHdl = NewHandle(1024);
  if(theHdl != NULL)
    blockSize = GetHandleSize(theHdl);

  memoryError = MemError();
  if(memoryError == noErr)
  {
    MoveTo(170,35);
    DrawString("\pBlock Size (Bytes) = ");
    NumToString(blockSize,theString);
    DrawString(theString);

    MoveTo(165,55);
    DrawString("\pNo Memory Manager errors");
    
    DisposeHandle(theHdl);
  }
}

// ******************************************************************************* doResources

void  doResources(void)
{
  PicHandle    pictureHdl;
  StringHandle stringHdl;
  Rect         pictureRect;
  OSErr        resourceError;

  pictureHdl = GetPicture(rPictureResourceID);
  if(pictureHdl == NULL)
  {
    SysBeep(10);
    ExitToShell();
  }

  SetRect(&pictureRect,148,75,348,219);

  HNoPurge((Handle) pictureHdl);
  DrawPicture(pictureHdl,&pictureRect);
  HPurge((Handle) pictureHdl);

  stringHdl = GetString(rStringResourceID);
  if(stringHdl == NULL)
  {
    SysBeep(10);
    ExitToShell();
  }

  MoveTo(103,250);
  DrawString(*stringHdl);

  ReleaseResource((Handle) pictureHdl);
  ReleaseResource((Handle) stringHdl);

  resourceError = ResError();
  if(resourceError == noErr)
  {
    MoveTo(160,270);
    DrawString("\pNo Resource Manager errors");
  }  
}

// *******************************************************************************************

Demonstration Program SysMemRes Comments

The 'plst' (Property List) Resource

As stated in the listing, one of the resources utilised by the program is a 'plst' 
(property list) resource.  Carbon applications must contain a 'plst' resource 
with ID 0 in order for the Mac OS X Launch Services Manager to recognize them as Carbon 
applications.  If the 'plst' resource is not provided, the application will be launched as a 
Classic application.

The 'plst' resource used is actually an empty 'plst' resource.  As will be seen at Chapter 9,
 however, this resource, apart from causing Mac OS X to recognise applications as Carbon 
applications, also allows applications to provide information about themselves to the Mac 
OS X Finder.

includes

Carbon greatly simplifies the matter of determining which Universal Headers files need to 
be included in this section.  All that is required is to include the header file Carbon.h, 
which itself causes a great many header files to be included.  If Carbon.h is not specified, 
the following header files would need to be included, and for the reasons indicated:

Appearance.h  Constant:  kThemeSystemFont

              Appearance.h itself includes MacTypes.h, which contains:

              Data Types:  SInt16  Str255  Size  OSErr  Handle  Rect  StringHandle
              Constants:   noErr  NULL

              Appearance.h also includes MacWindows.h, which contains:

              Prototypes:  GetNewCWindow  GetWindowPort

              MacWindows.h itself includes Events.h, which contains:

              Prototype:  Button

              MacWindows.h also includes Menus.h, which itself includes Processes.h, which
              contains:

              Prototype:  ExitToShell

              Appearance.h also includes QuickDraw.h, which contains:

              Prototypes:  InitCursor  SetPortWindowPort  SetRect  DrawPicture  MoveTo
                           GetPicture
              Data Types:  WindowRef  PicHandle

              QuickDraw.h itself includes QuickDrawText.h, which contains:

              Prototypes:  TextFont  DrawString

MacMemory.h   Prototypes:  NewHandle  DisposeHandle  GetHandleSize  HNoPurge  HPurge  
                           MemError  MoreMasterPointers

Resources.h   Prototypes:  ReleaseResource  ResError

Sound.h       Prototype:  SysBeep

TextUtils.h   Prototype:  GetString

              TextUtils.h itself includes NumberFormatting.h, which contains:

              Prototypes:  NumToString

It would be a good idea to peruse the header files MacMemory.h and Resources.h at this stage. 
Another header file which should be perused early in the piece is MacTypes.h.

defines

Constants are established for the resource IDs of the 'WIND', 'PICT' and 'STR ' resources.

main

The main function calls the functions that perform certain preliminaries common to most
applications, create a window, allocate and dispose of a relocatable memory block, and draw a
picture and text in the window.  It then waits for a button click before terminating the
program

The call to the QuickDraw function QDFlushPortBuffer is ignored when the program is run on Mac
OS 8/9.  It is required on Mac OS X because Mac OS X windows are double-buffered.  (The picture
and text are drawn in a buffer and, in this program, the buffer has to be flushed to the screen
by calling QDFlushPortBuffer.)  This is explained in more detail at Chapter 4.

doPreliminaries

The call to MoreMasterPointers is ignored when the program is run on Mac OS X.  (Master
pointers do not need to be pre-allocated, or their number optimised, in the Mac OS X memory
model.)  

On Mac OS 8/9, the call to MoreMasterPointers to allocate additional master pointers is really
not required in this simple program because the system automatically allocates one block of
master pointers at application launch.  However, in larger applications where more than 64
master pointers are required, the call to MoreMasterPointers should be made here so that all
master pointer (nonrelocatable) blocks are located at the bottom of the heap.  This will assist
in preventing heap fragmentation.  Note that specifying a number less than 32 in the inCount
parameter will result in 32 master pointers in the allocated block.

The call to InitCursor sets the cursor shape to the standard arrow cursor and sets the cursor
level to 0, making it visible.

doNewWindow

doNewWindow creates a window.

The call to GetNewCWindow creates a window using the 'WIND' template resource specified in the
first parameter.  The type, size, location, title, and visibility of the window are all
established by the 'WIND' resource.  The third parameter tells the Window Manager to open the
window in front of all other windows.  

Recall that, as soon as the data from the 'WIND' template resource is copied to the opaque data
structure known as a window object during the creation of the window, the relocatable block
occupied by the template will automatically be marked as purgeable.

The call to SetPortWindowPort makes the new window's graphics port the current port for drawing
operations.  The call to the Appearance Manager function UseThemeFont sets the font for that
port to the system font.

doMemory

doMemory allocates a relocatable block of memory, gets the size of that block and draws it
in the window (or, more accurately, in the window's graphics port), and checks for memory
errors.

The call to NewHandle allocates a relocatable block of 1024 bytes.  The call to GetHandleSize
returns the size of the allocated area available for data storage (1024 bytes).  (The actual
memory used by a relocatable block includes a block header and up to 12 bytes of filler.)

The call to MemError returns the error code of the most recent call to the Memory Manager.  If
no error occurred, the size returned by GetHandleSize is drawn in the window, together with a
message to the effect that MemError returned no error.  DisposeHandle is then called to free up
the memory occupied by the relocatable block.

MoveTo moves a "graphics pen" to the specified horizontal and vertical coordinates.  DrawString
draws the specified string at that location.  NumToString creates a string of decimal digits
representing the value of a 32-bit signed integer.  These calls are incidental to the
demonstration.

doResources

doResources draws a picture and some text strings in the window.

GetPicture reads in the 'PICT' resource corresponding to the ID specified in the GetPicture
call.  If the call is not successful, the system alert sound is played and the program
terminates.

The SetRect call assigns values to the left, top, right and bottom fields of a Rect variable. 
This Rect is required for a later call to DrawPicture.

The basic rules applying to the use of purgeable resources are to load it, immediately make it
unpurgeable, use it immediately, and immediately make it purgeable.  Accordingly, the HNoPurge
call makes the relocatable block occupied by the resource unpurgeable, the DrawPicture call
draws the picture in the window's graphics port, and the HPurge call makes the relocatable
block purgeable again.  Note that, because HNoPurge and HPurge expect a parameter of type
Handle, pictureHdl (a variable of type PicHandle) must be cast to a variable of type Handle.

GetString then reads in the specified 'STR ' resource.  Once again, if the call is not
successful, the system alert sound is played and the program terminates.  MoveTo moves the
graphics "pen" to an appropriate position before DrawString draws the string in the window's
graphics port.  (Since the 'STR ' resource, unlike the 'PICT' resource, does not have the
purgeable bit set, there is no requirement to take the precaution of a call to HNoPurge in this
case.)

Note the parameter in the call to DrawString.  stringHdl, like any handle, is a pointer to a
pointer.  It contains the address of a master pointer which, in turn, contains the address of
the data.  Dereferencing the handle once, therefore, get the required parameter for DrawString,
which is a pointer to a string.

The calls to ReleaseResource release the 'PICT' and 'STR ' resources.  These calls release the
memory occupied by the resources and set the associated handles in the resource map in memory
to NULL.

The ResError call returns the error code of the most recent resource-related operation.  If the
call returns noErr (indicating that no error occurred as a result of the most recent call by a
Resource Manager function), some advisory text is drawn in the window.

The next six lines examine the result of the most recent call to a memory manager function and
draw some advisory text if no error occurred as a result of that call.

Note that the last two calls to DrawString utilise "hard-coded" strings.  This sort of thing is
discouraged in the Macintosh programming environment.  Such strings should ordinarily be stored
in a 'STR#' (string list) resource rather than hard-coded into the source code.  The \p token
causes the compiler to compile these strings as Pascal strings.

PASCAL STRINGS

As stated in the Preface, when it comes to the system software, the ghost of
the Pascal language forever haunts the C programmer.  For example, a great many system 
software functions take Pascal strings as a required parameter, and some functions 
return Pascal strings.

Pascal and C strings differ in their formats.  A C string comprises the characters 
followed by a terminating 0 (or NULL byte):

+---+---+---+---+---+---+---+---+---+---+
| M | Y |   | S | T | R | I | N | G | 0 |
+---+---+---+---+---+---+---+---+---+---+

A C string is thus said to be "null-terminated".

In a Pascal string, the first byte contains the length of the string, and the 
characters follow that byte:

+---+---+---+---+---+---+---+---+---+---+
| 9 | M | Y |   | S | T | R | I | N | G |
+---+---+---+---+---+---+---+---+---+---+

Not surprisingly, then, Pascal strings are often referred to as "length-prefixed" 
strings.

In Chapter 3, you will encounter the data type Str255.  Str255 is the C name for a 
Pascal-style string capable of holding up to 255 characters.  As you would expect, 
the first byte of a Str255 holds the length of the string and the following bytes hold 
the characters of the string.

Utilizing 256 bytes for a string will simply waste memory in many cases.  Accordingly, 
the header file Types.h defines the additional types Str63, Str32, Str31, Str27, 
and Str15, as well as the Str255 type:-

    typedef unsigned char Str255[256];
    typedef unsigned char Str63[64];
    typedef unsigned char Str32[33];
    typedef unsigned char Str31[32];
    typedef unsigned char Str27[28];
    typedef unsigned char Str15[16];
    
Note, then, that a variable of type Str255 holds the address of an array of 256 elements,
each element being one byte long.

As an aside, in some cases you may want to use C strings, and use standard C library 
functions such as strlen, strcpy, etc., to manipulate them.  Accordingly, be aware that 
functions exist (C2PStr, P2CStr) to convert a string from one format to the other.

You may wish to make a "working" copy of the SysMemRes demonstration program file 
package and, using the working copy of the source code file SysMemRes.c, replace the
function doResources with the following, compile-link-run, and note the way the
second and third strings appear in the window.

    void  doResources(void)
    {
      Str255  string1 = "\pIs this a Pascal string I see before me?";
      Str255  string2 = "Is this a Pascal string I see before me?";
      Str255  string3 = "%s this a Pascal string I see before me?";
      Str255  string4;
      SInt16  a;

      // Draw string1    

      MoveTo(30,100);
      DrawString(string1);

      // Change the length byte of string1 and redraw

      string1[0] = (char) 23;
      MoveTo(30,120);
      DrawString(string1);

      // Leave the \p token out at your peril
      // I (ASCII code 73) is now interpreted as the length byte

      MoveTo(30,140);
      DrawString(string2);

      // More peril:-  % (ASCII code 37) is now the length byte

      MoveTo(30,160);
      DrawString(string3);

      // A hand-built Pascal string

      for(a=1;a<27;a++)
        string4[a] = (char) a + 64;

      string4[0] = (char) 26;

      MoveTo(30,180);
      DrawString(string4);

      // But is there a Mac OS function to draw the C strings correctly?

      MoveTo(30,200);
      DrawText(string2,0,40);  // Look it up in your on-line reference
    }
    

MORE ON STRINGS - UNICODE AND CFString OBJECTS

In the Carbon era, no discussion of strings would be complete without reference to
Unicode and CFString objects.

Preamble - Writing Systems, Character Sets, and Character Encoding A writing system (eg., Roman, Hebrew, Arabic) comprises a set of characters and the basic rules for using those characters in creating a visual depiction of a language. An individual character is a symbolic representation of an element of a writing system. In memory, an individual character is stored as a character code, a numeric value that defines that particular character. One byte is commonly used to store a single character code, which allows for a character set of 256 characters maximum. A total of 256 numeric values is, of course, quite inadequate to provide for all the characters in all the world's writing systems, meaning that different character sets must be used for different writing systems. In one-byte encoding systems, therefore, these different character sets are said to "overlap". As an aside, the Apple Standard Roman character set (an extended version of the 128-character ASCII character set) is the fundamental character set for the Macintosh computer. To view the printable characters in this set, replace the main function in the SysMemRes demonstration program with the following: void main(void) { WindowRef windowRef; SInt16 fontNum, a,b; UInt8 characterCode = 0; doPreliminaries(); windowRef = GetNewCWindow(rWindowResourceID,NULL,(WindowPtr) -1); SetPortWindowPort(windowRef); GetFNum("\pGeneva",&fontNum); TextFont(fontNum); for(a = 0;a < 256;a += 16) { for(b=0;b<16;b++) { MoveTo((a * 1.5) + 60,(b * 15) + 40); DrawText((Ptr) &characterCode,0,1); characterCode++; } } while(!Button()) ; } In addition to the overlapping of character sets between writing systems, a further problem is conflicting character encodings within a single writing system. For an example of this in the Roman writing system, change "\pGeneva" to "\pSymbol" in the above substitute main function.

Unicode Unicode is an international standard that combines all the characters for all commonly used writing systems into a single character set. It uses 16 bits per character, allowing for a character set of up to 65,535 characters. With Unicode, therefore, the character sets of separate writing systems do not overlap. In addition, Unicode eliminates the problem of conflicting character encodings within a single writing system, such as that between the Roman character codes and the codes of the symbols in the Symbol font (see above). Unicode makes it possible to develop and localize a single version of an application for users who speak most of the world's written languages, including Cyrillic, Arabic, Chinese, and Japanese.

Core Foundation's String Services Core Foundation is a component of the system software. Through its String Services, Core Foundation facilitates easy and consistent internationalization of applications. The essential part of this support is an opaque data type (CFString). A CFString "object" represents a string as an array of 16bit Unicode characters. Several Control Manager, Dialog Manager, Window Manager, Menu Manager, and Carbon Printing Manager functions utilize CFStrings. CFString objects come in immutable and mutable variants. Mutable strings may be manipulated by appending string data to them, inserting and deleting characters, and padding and trimming characters. CFStrings have many associated functions that do expected things with strings such as comparing, inserting, and appending. Functions are also available to convert Unicode strings (that is, CFStrings) to and from other encodings, particularly 8bit encodings (such as the Apple Standard Roman character encoding) stored as Pascal and C strings.

Example For a basic example of the use of CFStrings, remove the calls to doMemory and doResources, and the functions themselves, from the main function in the original version of the demonstration program SysMemRes and replace the function doNewWindow with the following: void doNewWindow(void) { WindowRef windowRef; Str255 pascalString = "\pThis window title was set using a CFString object"; CFStringRef titleStringRef; CFStringRef textStringRef = CFSTR("A CFString object converted to a Str255"); Boolean result; Str255 textString; windowRef = GetNewCWindow(rWindowResourceID,NULL,(WindowPtr) -1); SetPortWindowPort(windowRef); UseThemeFont(kThemeSystemFont,smSystemScript); titleStringRef = CFStringCreateWithPascalString(NULL,pascalString, CFStringGetSystemEncoding()); SetWindowTitleWithCFString(windowRef,titleStringRef); result = CFStringGetPascalString(textStringRef,textString,256, CFStringGetSystemEncoding()); if(result) { MoveTo(135,130); DrawString(textString); } if(titleStringRef != NULL) CFRelease(titleStringRef); } At the sixth line, an immutable CFString object is created. The easiest way to do this is to use the CFSTR macro. The argument of the macro must be a constant compile-time string (that is, text enclosed in quotation marks) that contains only ASCII characters. CFSTR returns a reference (textStringRef) to a CFString object. This will be used later. The call to the String Services function CFStringCreateWithPascalString converts a Pascal string (pascalString, of type Str255) to a CFString object. The reference to the CFString object is then passed in a call to the Window Manager function SetWindowTitleWithCFString to set the window's title. The call to the String Services function CFStringGetPascalString converts the CFString object (textStringRef) previously created by the CFSTR macro to a Pascal string (textString, of type Str255). 256, rather than 255, is passed in the bufferSize parameter to accommodate the length byte. textString is then passed in a call to the QuickDraw function DrawString, which draws the string in the window. The golden rules for releasing CFString objects are: if a "Create" or "Copy" function is used, CFString should be called to release the string when no longer required; if a "Get" function is used, CFString should not be called. Accordingly, CFRelease is called only in the case of titleStringRef. Note that CFRelease is not NULL-safe, so you must check for a non-NULL value before passing something to CFRelease.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Adobe Creative Cloud 4.0.0.185 - Access...
Adobe Creative Cloud costs $19.99/month for a single app, or $49.99/month for the entire suite. Introducing Adobe Creative Cloud desktop applications, including Adobe Photoshop CC and Illustrator CC... Read more
Default Folder X 5.1.4 - 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 on... Read more
Amazon Chime 4.1.5587 - Amazon-based com...
Amazon Chime is a communications service that transforms online meetings with a secure, easy-to-use application that you can trust. Amazon Chime works seamlessly across your devices so that you can... Read more
Persecond 1.0.9 - Timelapse video made e...
Persecond is the easy, fun way to create a beautiful timelapse video. Import an image sequence from any camera, trim the length of your video, adjust the speed and playback direction, and you’re done... Read more
CrossOver 16.2 - Run Windows apps on you...
CrossOver can get your Windows productivity applications and PC games up and running on your Mac quickly and easily. CrossOver runs the Windows software that you need on Mac at home, in the office,... Read more
MegaSeg 6.0.2 - Professional DJ and radi...
MegaSeg is a complete solution for pro audio/video DJ mixing, radio automation, and music scheduling with rock-solid performance and an easy-to-use design. Mix with visual waveforms and Magic... Read more
Apple iTunes 12.6 - Play Apple Music and...
Apple iTunes lets you organize and stream Apple Music, download and watch video and listen to Podcasts. It can automatically download new music, app, and book purchases across all your devices and... Read more
GraphicConverter 10.4 - $39.95
GraphicConverter is an all-purpose image-editing program that can import 200 different graphic-based formats, edit the image, and export it to any of 80 available file formats. The high-end editing... Read more
OpenEmu 2.0.5 - Open Source game-emulati...
OpenEmu is about to change the world of video game emulation, one console at a time... For the first time, the 'It just works' philosophy now extends to open source video game emulation on the Mac.... Read more
beaTunes 4.6.13 - Organize your music co...
beaTunes is a full-featured music player and organizational tool for music collections. How well organized is your music library? Are your artists always spelled the same way? Any R.E.M. vs REM?... Read more

The Elder Scrolls: Legends is now availa...
| Read more »
Ticket to Earth beginner's guide: H...
Robot Circus launched Ticket to Earth as part of the App Store's indie games event last week. If you're not quite digging the space operatics Mass Effect: Andromeda is serving up, you'll be pleased to know that there's a surprising alternative on... | Read more »
Leap to victory in Nexx Studios new plat...
You’re always a hop, skip, and a jump away from a fiery death in Temple Jump, a new platformer-cum-endless runner from Nexx Studio. It’s out now on both iOS and Android if you’re an adventurer seeking treasure in a crumbling, pixel-laden temple. | Read more »
Failbetter Games details changes coming...
Sunless Sea, Failbetter Games' dark and gloomy sea explorer, sets sail for the iPad tomorrow. Ahead of the game's launch, Failbetter took to Twitter to discuss what will be different in the mobile version of the game. Many of the changes make... | Read more »
Splish, splash! The Pokémon GO Water Fes...
Niantic is back with a new festival for dedicated Pokémon GO collectors. The Water Festival officially kicks off today at 1 P.M. PDT and runs through March 29. Magikarp, Squirtle, Totodile, and their assorted evolved forms will be appearing at... | Read more »
Death Road to Canada (Games)
Death Road to Canada 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: Get it now at the low launch price! Price will go up a dollar every major update. Update news at the bottom of this... | Read more »
Bean's Quest Beginner's Guide:...
Bean's Quest is a new take on both the classic platformer and the endless runner, and it's free on the App Store for the time being. Instead of running constantly, you can't stop jumping. That adds a surprising new level of challenge to the game... | Read more »
How to rake in the cash in Bit City
Our last Bit City guide covered the basics. Now it's time to get into some of the more advanced techniques. In the later cities, cash flow becomes much more difficult, so you'll want to develop some strategies if you want to complete each level.... | Read more »
PixelTerra (Games)
PixelTerra 1.1.1 Device: iOS Universal Category: Games Price: $.99, Version: 1.1.1 (iTunes) Description: The world of PixelTerra is quite dangerous so you need to build a shelter, find some food supply and get ready to protect... | Read more »
Tokaido™ (Games)
Tokaido™ 1.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.0 (iTunes) Description: Discover the digital adaptation of Tokaido, the boardgame phenomenon that has already sold more than 250,000 copies worldwide, and... | Read more »

Price Scanner via MacPrices.net

SSD Speeder RAM Disk SSD Life Extender App Fo...
Fehraltorf, Switzerland based B-Eng has announced they are making their SSD Speeder app for macOS publicly available for purchase on their website. SSD Speeder is a RAM disk utility that prevents... Read more
iPhone Scores Highest Overall in Smartphone D...
Customer satisfaction is much higher among smartphone owners who use their device to operate other connected home services such as smart thermostats and smart appliances, according to the J.D. Power... Read more
Swipe CRM Free Photo-Centric CRM Sales DEal C...
Swipe CRM LLC has introduced Swipe CRM: Visual Sales 1.0 for iPad, an app for creating, managing, and sharing visually stunning sales deals. Swipe CRM is targeted to small-and-medium creative... Read more
13-inch 2.0GHz Apple MacBook Pros on sale for...
B&H has the non-Touch Bar 13″ 2.0GHz MacBook Pros in stock today and on sale for $150 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.0GHz MacBook Pro Space Gray (... Read more
15-inch Touch Bar MacBook Pros on sale for up...
B&H Photo has the new 2016 15″ Apple Touch Bar MacBook Pros in stock today and on sale for up to $150 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.7GHz Touch Bar... Read more
Apple’s iPhone 6s Tops Best-Selling Smartphon...
In terms of shipments, the iPhone 6s from Apple bested all competitors for sales in 2016, according to new analysis from IHS Markit, a world leader in critical information, analytics and solutions.... Read more
Logitech Rugged Combo Protective iPad Case an...
Logitech has announced its Logitech Rugged Combo, Logitech Rugged Case, and Logitech Add-on Keyboard for Rugged Case for Apple’s new, more affordable $329 9.7-inch iPad, a complete solution designed... Read more
T-Mobile To Offer iPhone 7 and iPhone 7 Plus...
T-Mobile has announced it will offer iPhone 7 and iPhone 7 Plus (PRODUCT)RED Special Edition in a vibrant red aluminum finish. The introduction of this special edition iPhone celebrates Apple’s 10... Read more
9-inch 128GB iPad Pros on sale for $50-$70 of...
B&H Photo has 9.7″ 128GB Apple WiFi iPad Pros on sale for up to $70 off MSRP, each including free shipping. B&H charges sales tax in NY only: - 9″ Space Gray 128GB WiFi iPad Pro: $649 $50... Read more
27-inch iMacs on sale for up to $200 off MSRP...
B&H Photo has 27″ Apple iMacs on sale for up to $200 off MSRP, each including free shipping plus NY sales tax only: - 27″ 3.3GHz iMac 5K: $2099 $200 off MSRP - 27″ 3.2GHz/1TB Fusion iMac 5K: $... Read more

Jobs Board

*Apple* macOS Systems Integration Administra...
…most exceptional support available in the industry. SCI is seeking an Junior Apple macOS systems integration administrator that will be responsible for providing Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Director, *Apple* Program - ERP & Cloud...
Leading Pharmaceutical / Biotech Company is announcing a Director, Apple Program - ERP & Cloud Platform Architecture Lead opportunity in Northbrook, IL. Purpose & Read more
Fulltime aan de slag als shopmanager in een h...
Ben jij helemaal gek van Apple -producten en vind je het helemaal super om fulltime shopmanager te zijn in een jonge en hippe elektronicazaak? Wil jij werken in Read more
Starte Dein Karriere-Abenteuer in den Hauptst...
…mehrsprachigen Teams betreust Du Kunden von bekannten globale Marken wie Apple , Mercedes, Facebook, Expedia, und vielen anderen! Funktion Du wolltest schon Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.