TweetFollow Us on Twitter

GUI-up your Script

Volume Number: 22 (2006)
Issue Number: 8
Column Tag: Mac in the Shell

GUI-up your Script

OK - Perhaps the GUI is nice every now and then...

by Edward Marczak

Introduction

While I can extol the virtues of life in the shell, I do realize that sometimes, just sometimes, a GUI is more appropriate. Why would I say such a thing? Because there will be scripts that you write primarily to be used by other people. The kind of people that don't keep a terminal window open 100% of the time. On one hand, you've found a great solution to their issue. On the other, you don't want the cure to be more painful than the disease. The wonderful thing about Apple's XCode development environment is that you can take practically any shell solution and turn it into a GUI-based one without too much effort. That's where we'll be heading this month.

What's New in AppleScript

Did I just say AppleScript? Yes, yes I did. The history of AppleScript is outside the scope of this column; it is very lengthy. It is now, however, a mature technology. Even more exciting is the inclusion of "AppleScript Studio" into OS X and XCode.

Now, you won't find an application, or even a submenu that launches anything called "AppleScript Studio." AppleScript Studio refers to the ability of XCode to take an AppleScript app, tie it into all of the other XCode technologies and compile it into a native Cocoa app. This makes creating a basic application mind-blowingly simple. We're going to create a small sample app to prove this.

Fire Up XCode

If you've never launched XCode, now's your chance to dig in. If you're an XCoder already, you may have missed (or ignored) some of the AppleScript options. More importantly, if you've never installed XCode, you'll need to for the rest of this article. While the XCode environment ships with each copy of the OS, the retail disc is a little dated at this point. Bring yourself to <http://developer.apple.com>, sign up for a free account, and download the latest version of XCode (2.3, as of this writing, weighing in at 915MB).

With XCode installed, it's time to launch it. You'll find it at /Developer/Applications:



Figure 1: XCode icon

You may not notice that it's up and running. In its minimalist way, there's no splash screen or other trumpeting of its arrival. Choose New Project from the File menu:



Figure 2: New Project

When presented with the choice of the kind of project, choose "AppleScript Application" and click "Next". Name your project - the example this month is "Backup", if you're following along - and where you want it saved. XCode will create directories for you if necessary. Once you give it the go ahead, you'll be staring at a fresh new project.



Figure 3: Default Project

Lot of stuff - stay cool. In the "Groups & Files" pane, you'll see a 'Scripts' folder. Since we're going to be writing an AppleScript that will front-end a shell script, as you can imagine, this is where the bulk of the action will take place for us. Of course, we need to begin at the beginning. Let's write the shell script.

The Heart of the Matter

The real work will be done by a shell script, so we need to have that in place. This will be a 'lite' version of a solution I really have put in place. However, there were enough things that were specific to the environment in question, that I don't want to reproduce here. Additionally, I won't be getting into any heavy error checking or correction. Nor will I make the claim that this is a perfect fit for any other particular situation. That said, I'll offer this basic script as our base:

#!/bin/bash
ditto -rsrc /Files /Volumes/Backup_Drive/Files

This one-liner uses the OS X native ditto command to copy all files from /Files to /Volumes/Backup_Drive/Files. I'll stick the '-rsrc' switch in there as it only became the default behavior as of 10.4. What if we want to run this on a Panther machine? Use your favorite text editor to create this script, and then save it. Call it "backup.sh". Mark it executable with chmod 770 and test it. You may need to modify the path names, or, for testing purposes, simply copy between two folders on your local drive.

Have it working? Great. Now, we can drag-and-drop this script right into our XCode project. Locate this script in the Finder, and drag it into the Scripts folder. You'll be asked how to reference this file. Ensure that the "Copy items into destination group's folder" is checked, and click add.



Figure 4: Copying a script into XCode

You should see your backup.sh script listed alongside the preloaded AppleScript file. Like so:



Figure 5: Your script has been added

If you've never used XCode before, please do this now: click on the build icon in the toolbar. This will help you understand how XCode lays out your project. Open up the folder where you saved this project. Inside, you'll find a folder named 'build'. Inside of that, you'll find one named 'Debug', and it will contain your Backup.app. See how easy that was? OK, not so fast, right? Although this app actually will run (go on, try it), it won't do anything of use. Right-click (control-click) on the app and select "Show Package Contents". Open the resulting 'Contents' folder, and the 'Resources' folder beneath that. You should see three objects: backup.sh, English.lproj and Scripts. Well, there's our 'backup.sh' file! Now we know where it lives and how to access it.

Get GUI

Back in XCode, toggle the disclosure triangle next to the 'Resources' group. Double-click on the 'MainMenu.nib' file. This will launch Interface Builder, and even more windows will now litter your screen. Click once on the window labeled 'Window'. Let's immediately name it something more relevant. Change the Window Title in the inspector pane, and title the window "Backup". Also, we need to give it an AppleScript name. Change the drop-down menu in the inspector to "AppleScript". Name the window "wMain". Now, look for a button in the 'Cocoa-Controls' pane. Drag it to the lower right-hand corner of our window. You'll see guidelines appear to help you position it. With the button still selected, let's make it say and do something appropriate. Back on the attributes screen, update the button title in the inspector pane. (Change the drop-down menu to get back to the attributes screen). Additionally, change the 'Key equiv.' to '\R' - type it in or use the drop down menu to select 'Return', and check the 'Selected' checkbox. Flip the inspector back to AppleScript, and give this button a name. How about "bBackup"?

Now to begin to tie it together: Making sure that you're still in the AppleScript portion of the inspector, place a check-mark in the 'Action' box, and select the 'Backup.applescript' in the list at the bottom of the Inspector. Save and quit. Not too terrible, right? Of course, now we have to make that AppleScript do something.

I am not, nor will I pretend to be an AppleScript guru. I can deal with the basics well enough, and they are easy to pick up. However, once you start doing this, and you get hooked on it, do yourself a favor and hit some of the many fine AppleScript resources available. This includes Ben Waldie's AppleScript column right here in MacTech. He's also written some excellent books, available through SpiderWorks (http://www.spiderworks.com). There's also <http://www.macscripter.net>, another web-based resource. However, to simply front-end a shell script - no matter how complex - you'll find all you need in this one column. Just do realize that you can do some very complex scripting with AppleScript, and in an all Mac environment is well-worth learning.

With that out of the way, let's continue. Back in XCode proper, double-click on the 'Backup.applescript' in the 'Scripts' group. You'll see that XCode give you some pre-populated comments for you to tailor to this project. But comments don't cause any action! Place these lines into the script:

on clicked theObject
   -- setup
   set myPath to POSIX path of (path to me) as string
   
   -- Do it!
   do shell script quoted form of myPath & "Contents/Resources/backup.sh"
end clicked

As you type this in, all text will be set in a purple mono-spaced font (by default, anyway - you may have changed this preference). Once you save, the parser comes alive to check the validity of the script. Valid strings and recognized keywords get color-coded and set in a different font. What did we just tell our application to do? Actions performed on the button will be sent here since we used Interface Builder to tie an action to this particular script. In this case, we're interested to know when someone clicks on the button.

The first line (set myPath...) sets the "myPath" variable to the path of the application. This lets the user place this app wherever they want on their file system, and we can deal with it at runtime. Next, we call our shell script. AppleScript gained the ability to call scripts with the "do shell script" command. Currently, we know where our app lives and have stored that in a variable, myPath. Earlier, we verified where our script lives inside our application bundle. Now we know where to go relative to the app. We can launch our script from the "Contents/Resources" folder below "myPath".

Is it really this simple? Let's find out. First: go load up your /Files directory with some files and folders. Then, back in XCode, click on the "Build and Go" icon in the toolbar. A build window will appear and give you build status. Once complete, you'll see the window that we created earlier in Interface Builder with its one lonely button. As you can see, it is the default button, and has the Aqua default pulsing glow. Go ahead and click the "Backup" button. Our app will run our shell script buried in the application bundle. Depending on how much stuff you loaded into the /Files directory, this may take a minute. Do notice, though, that while the underlying script is running, the button stops pulsing. Once the script finishes up, the button will pulse again. Press Apple-Q or select "Quit NewApplication" from the "Backup" menu.

The answer, then, is "yes! It is that simple." Of course, not only did we not write a very friendly application, there are some other things we need to take into consideration. However, if all you ever want is a one-button method of running a shell-script, now you have the framework to do so. This isn't anything I'd hand a client, of course.

Version 1.1

Before I continue to spill letters onto the page, there's a much more important source before we continue. "do shell script" is addressed in detail in Apple's Technote TN2065. This is a must read. URL in the references at the end of this article.

Moving along, we need to create better feedback for the client when they run our application. Double-click on the MainMenu.nib file once again (in XCode). You should see our application's window displayed by default. If not, double-click the "Window" icon in the "MainMenu.nib (English)" window. Drag a progress indicator from the Cocoa-Controls window onto our main window - place it just above the backup button, and stretch it horizontally to the width of the window. Then, with it still selected, change the drop-down menu in the inspector to "AppleScript". Give this control a name...like, "pMainProgress". (I used to code in VB and RB and, yes, Hungarian notation is driven pretty deep into my brain). We need this name so we can refer to the control in code. Save and quit Interface Builder.

Once again, we're in the position of writing code that will actually make that progress bar do something. Fortunately, AppleScript makes it pretty trivial. You'll see why we need to name objects so AppleScript can reference them. Here's one of the lines we'll need to add:

set uses threaded animation of progress indicator "pMainProgress" of window "wMain" to true

(While this may wrap in print, you should type it as all one single line with no line break).

Since we can have multiple windows, each with multiple progress bars and other objects, we need to be specific. We need to set the "uses threaded animation" property of the progress bar. Ah, which progress bar? The one we called "pMainProgress". Well, on which window? "wMain"! AppleScript's goal of being English-like works in its favor most of the time. Other times, you can get some pretty bizarre sentences. We'll place all of our code right in the on clicked section, because we only want the progress bar to animate while the backup is running. The fully updated code follows (and look for the start and stop of the progress bar):

on clicked theObject
   -- setup
   set myPath to POSIX path of (path to me) as string
   -- Start progress bar
   set uses threaded animation of progress indicator "pMainProgress" of window "wMain" to true
   tell progress indicator "pMainProgress" of window "wMain" to start
   
   -- Do it!
   do shell script quoted form of myPath & "Contents/Resources/backup.sh"
   -- Stop progress bar
   tell progress indicator "pMainProgress" of window "wMain" to stop
   set uses threaded animation of progress indicator "pMainProgress" of window "wMain" to false
   
end clicked

(Again, these lines wrap in print, but they should not be artificially broken when you type them).

Our progress bar commands "wrap" the do shell script. Time for the test: Apple-S (save) and Apple-R (build and Run). Make sure that your source folder is populated, and click on "Backup". Progress bar moves while it's working, and stops once it's done. Fantastic.

What if there's a problem? We really want to trap for errors. Change the "Do it" section to read thusly:

   -- Do it!
   try
      do shell script quoted form of myPath & "Contents/Resources/backup.sh"
   on error number 255
      display dialog "Sorry, an error occurred.  I can't make the copy."
   end try

As you can surmise, this allows us to try a command that may fail, without bombing out - we get to control the process. Here, I show a basic try block. We try to run the script. If it runs properly, returning a zero, all's good and we continue on. If there's a problem, we show a dialog box that explains that there has been a problem. Try blocks can certainly get much more elaborate.

What might be a reason that we'd have an error in our script? Perhaps we're asking it to backup areas of the file system that we don't have access to? In that case, you can have your script run with administrator privileges. You do this with the....wait for it..."with administrator privileges" parameter. Alter the do shell script line to read like this:

do shell script quoted form of myPath & "Contents/Resources/backup.sh" 
with administrator privileges

By itself, with no additional parameters, this will present the user with the familiar dialog box asking for an admin password when the app is run.



Figure 6: Our app asking for authentication

You can preload your script with a username and password. However, I DO NOT RECOMMEND THIS. Clear? To tie this back into last month's column, it would be trivial for someone to run strings across the resulting binary and gather the admin level id and password you provided. If you're daring enough to risk it, find the instructions in the Apple 'do shell script' technote referenced earlier (but seriously: don't).

One little thing that TN2065 does not mention: there is a default timeout on all AppleScript commands, including do shell script, of two minutes. If you believe your script may run for longer - for whatever reason - use a with timeout block:

with timeout of 300 do
   do shell script ...
end timeout

Unfortunately, there is no setting that will just let it do its thing indefinitely (OK, perhaps not a terrible thing). If a command does timeout, a timeout error is thrown (-1712). So do make sure you use a value large enough to let your script run to completion. Even if that's "99999".

One for the road

We'll add one more object to our window: A text field with the current status. Double-click on MainMenu.nib, and once Interface Builder is running, click on the Cocoa-Text icon in the object palette:



Figure 7: Cocoa-Text icon

Drag two "System Font Text" fields to the main window. Place one in the upper left (use the guides), and the second right next to it. Double-click on the first, and type "Status:" into the text field. Double-click on the second and type "Idle" into its text field. With the second still selected, Apple-8 your way to the AppleScript attributes, and name this field "efStatus". We should also clean this window up a bit while we're here, no? Drag the progress bar straight up until the guides appear under the text fields we just created. Do the same for the single button, and stop when the guides appear under the progress bar. Size the window itself appropriately, again using the guides. Save and quit Interface Builder.

Again, we need to make that text field perform an appropriate action. Here's how we can do so. In the "setup" section, add this line:

set the contents of text field "efStatus" of window "wMain" to "Copying files..."
...and just after the try block, add this line:
set the contents of text field "efStatus" of window "wMain" to "Backup Complete."

Save (Apple-S), build and run (Apple-R) the project with the changes. Nice.

Finally

Last thing I'll mention: If you really want to make this professional, you'll probably want to fix up the app menus to show the app's real name (not "New Application") and add a custom icon. Let's tackle the icon first. For this, you'll need Icon Composer. You'll find that with the developer tools in /Developer/Applications/Utilities. You'll need to have your artwork complete before using this utility - Icon Composer is not a drawing program. It will, though, read in Photoshop files directly. Drag your artwork to the 128x128 pane, scale it if needed. From there, drag the 128x128 to the 48x48, scale it and let the program extract the mask. Rinse and repeat for the last two sizes. Apple-S to save. Make sure "Save into bundles" is checked, and save the file. You can then take this file and drag it into the "Resources" section of the XCode project. Choose the "Project" menu and click on the "Properties" tab. Type in the name of your icon file (I left mine "icons.icns" in the example below), and as soon as you press return, you'll see a thumbnail representation of your application icon.



Figure 8: Project properties and setting an application icon.

To update the menus, we need to double-click on the MainMenu.nib once again and launch Interface Builder. You should notice a small menubar floating just underneath the window we've been editing. If not, simply double-click on the "Main Menu" icon in the main window of Interface Builder. Editing the menu is as simple as double-clicking on each item you want to rename. You can alternatively accomplish this with the inspector pane, but this method will update the inspector as well.



Figure 9: Menu editing in action.

Quit and save. Let's build this thing into a 'real' app. In XCode, choose the "Project" menu, and then change the "Active Build Configuration" to "Release". Save and build (Apple-B) the app. The last line of the Build Results window will tell you where to pick up your Universal Binary application! Go get it and double-click to run. Exiting, huh? You can now distribute this application, and it contains everything that it needs to run - your shell script (the point of this entire exercise, remember) is bundled inside.



Figure 10: Our final application, running as a universal binary.

Keep it simple

The goal of this article was to introduce the oft-overlooked capability to easily create a GUI for a shell script using tools that Apple provides for free. While many are aware of this capability, I find it "oft-overlooked" by shell scripters, anyway. As mentioned earlier in the article, this is certainly not an exhaustive look at everything you can do, nor does it even begin to approach "best practices" (such as exhaustive error checking in a try-block, creating a proper info.plist, or even dealing with script output). If this introduction intrigues you, there are many, many places to increase your knowledge and further this path.

While I realize that this will run very much after the fact, this publication will appear during WWDC, which will be less lively without Michael Bartosh. Friend, fellow tech, fellow author and more, he will be sorely missed. Let's all remember to raise a glass - even a virtual one - in remembrance. Speaking of WWDC, I'm present to raise a real glass with anyone interested. See you at Dave's.

Media of the month: I've been too tied up in Citrix tech docs and Microsoft Group Policy to recommend anything appropriate here from a technical perspective. Actually...that may provide the perfect segue: OS X provides Windows interoperability by using the open source Samba project. By itself, Samba is an ambitious and deep project. Cleverly, Apple provides O'Reilly's entire "Using Samba, Second Edition" preloaded onto your Mac! Launch Safari and point your browser to <file:///usr/share/swat/using_samba/toc.html>. This tends to be another 'oft-overlooked' resource.

I was fortunate to meet many MacTech readers at MacWorld in January, and I hope to meet more at WWDC 2006. If you're unable to attend, look for our reports from the show. In any case, I'll see you in print next month!

References

Just about everything at http://developer.apple.com

Especially Tech Note 2065: http://developer.apple.com/technotes/tn2002/tn2065.html

The Tao of AppleScript, Derrick Schneider (yes, this came out in 1994 and shipped with a floppy of examples. AppleScript basics just haven't changed that much).

Resources

Mac Scripter: http://macscripter.net/


Ed Marczak owns and operates Radiotope, a technology consulting company. Radiotope helps separate technology issues from policy issues, cool-tech from needed-tech. Guide your decision at http://www.radiotope.com

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

LibreOffice 4.4.1.2 - Free, open-source...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
Freeway Pro 7.0.3 - Drag-and-drop Web de...
Freeway Pro lets you build websites with speed and precision... without writing a line of code! With its user-oriented drag-and-drop interface, Freeway Pro helps you piece together the website of... Read more
Cloud 3.3.0 - File sharing from your men...
Cloud is simple file sharing for the Mac. Drag a file from your Mac to the CloudApp icon in the menubar and we take care of the rest. A link to the file will automatically be copied to your clipboard... Read more
Cyberduck 4.6.5 - FTP and SFTP browser....
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Firefox 36.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals and... Read more
Thunderbird 31.5.0 - Email client from M...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more
VOX 2.4 - Music player that supports man...
VoxIt just sounds better! The beauty is in its simplicity, yet behind the minimal exterior lies a powerful music player with a ton of features & support for all audio formats you should ever need... Read more
A Better Finder Rename 9.46 - File, phot...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more
WALTR 1.0.9 - Drag-and-drop any media fi...
WALTR is designed to make it easy to upload and convert any music or video file to an iPad or iPhone format for native playback. It supports a huge variety of media file types, including MP3, MP4,... Read more
Default Folder X 4.6.14 - Enhances Open...
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

Check Out the Trailer for the Upcoming F...
Check Out the Trailer for the Upcoming FINAL FANTASY: Record Keeper Posted by Jessica Fisher on February 26th, 2015 [ permalink ] DeNA and Square Enix have announced that | Read more »
Legacy Quest is an Upcoming Rouge-like T...
Legacy Quest is an Upcoming Rouge-like That’ll Kill the Whole Family Posted by Jessica Fisher on February 26th, 2015 [ permalink ] Nexon Co. | Read more »
Grudgeball: Enter the Chaosphere Review
Grudgeball: Enter the Chaosphere Review By Jordan Minor on February 26th, 2015 Our Rating: :: MUSCLE MENUniversal App - Designed for iPhone and iPad Regular Show gets an above average game.   | Read more »
Action RPG League of Angels – Fire Raide...
Gaia is being invaded by the Devil Prince and the demonic Devil Army at his disposal, and it’s up to you and your avatar to defeat him in League of Angels – Fire Raiders. Raise a mighty army from hundreds of recruitable angel heroes and take the... | Read more »
Burn Rubber on the Ice With a New Cars:...
Burn Rubber on the Ice With a New Cars: Fast as Lightning Update Posted by Jessica Fisher on February 26th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
AdVenture Capitalist Review
AdVenture Capitalist Review By Jordan Minor on February 26th, 2015 Our Rating: :: DAS KAPITALUniversal App - Designed for iPhone and iPad An inadvertent Marxist manifesto.   | Read more »
Monster vs Sheep Review
Monster vs Sheep Review By Jennifer Allen on February 25th, 2015 Our Rating: :: SAMEY FUNUniversal App - Designed for iPhone and iPad What Monster vs Sheep lacks in variety it makes up for with stress relieving fun. At least, for a... | Read more »
Is Your Face Ready for the New Outwitter...
Is Your Face Ready for the New Outwitters 2.0 Trailer? Posted by Jessica Fisher on February 25th, 2015 [ permalink ] One Man Left Studios has announced that their turn-based strategy game, | Read more »
HowToFormat Review
HowToFormat Review By Jennifer Allen on February 25th, 2015 Our Rating: :: USEFUL TIPSiPhone App - Designed for the iPhone, compatible with the iPad Making a presentation and want to get it just right? HowToFormat teaches you how... | Read more »
Thermo Diem Review
Thermo Diem Review By Jennifer Allen on February 25th, 2015 Our Rating: :: GETS TO THE POINTUniversal App - Designed for iPhone and iPad Want to know whether it’s warmer or colder tomorrow? That’s precisely what Thermo Diem will... | Read more »

Price Scanner via MacPrices.net

Apple Takes 89 Percent Share of Global Smartp...
According to the latest research from Strategy Analytics, global smartphone operating profit reached US$21 billion in Q4 2014. The Android operating system captured a record-low 11 percent global... Read more
New Travel Health App “My Travel Health” iOS...
Rochester, Minnesota based Travel Health and Wellness LLC has announced that its new iOS app help safeguard the user’s health when traveling abroad — “My Travel Health” is now available on the Apple... Read more
Sale! MacBook Airs for up to $115 off MSRP
B&H Photo has MacBook Airs on sale for up to $100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 11″ 128GB MacBook Air: $799 100 off MSRP - 11″ 256GB MacBook Air: $999 $100... Read more
15-inch 2.0GHz Retina MacBook Pro (refurbishe...
The Apple Store has Apple Certified Refurbished previous-generation 15″ 2.0GHz Retina MacBook Pros available for $1489 including free shipping plus Apple’s standard one-year warranty. Their price is... Read more
Wither The iPad mini? End Of The Road Imminen...
AppleDailyReport’s Dennis Sellers predicts that the iPad mini is going to be left to wither on the vine, as it were, and then just allowed to fade away — a casualty of the IPhone 6 Plus and other... Read more
Android and iOS Duopoly Owns 96.3% of Smartph...
IDC reports that Android and iOS inched closer to total domination of the worldwide smartphone market in both the fourth quarter (4Q14) and the calendar year 2014 (CY14). According to data from the... Read more
13-inch 2.4GHz Retina MacBook Pro available f...
MacMall has the 2013 13″ 2.4GHz/128GB Retina MacBook Pro available for $999.99 for a limited time. Shipping is free. Their price is $300 off original MSRP, and it’s the only sub-$1000 new Retina... Read more
Save up to $300 on a new Mac, $30 on an iPad,...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Mac minis available for up to $75 off MSRP
MacMall has Mac minis on sale for up to $75 off MSRP including free shipping. Their prices are the lowest available for these models from any reseller: - 1.4GHz Mac mini: $459.99 $40 off - 2.6GHz Mac... Read more
WaterField Unveils Versatile Padded Gear Pouc...
San Francisco manufacturer WaterField Design’s new Padded Gear Pouch is a light and handy-sized, yet protective, organizer for every kind of take-along gear: technology, travel, toiletries,... Read more

Jobs Board

*Apple* Solutions Consultant - Retail Sales...
**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 - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
*Apple* Solutions Consultant (ASC)- Retail S...
**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 - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.