TweetFollow Us on Twitter

Networking REALbasic

Volume Number: 16 (2000)
Issue Number: 2
Column Tag: Emerging Technologies

Network with REALbasic

By Erick J. Tejkowski

Make your own network game in REALbasic

These days it seems everyone is jumping on the network bandwagon. From chat applications to games, from CD databases to meta-search engines like Sherlock, network functionality is an important addition to many types of software. Luckily, REALbasic affords us the ability to quickly and easily add TCP/IP functionality to any application. To explore this area of REALbasic programming, we will build a simple network version of the ever-popular game Tic-Tac-Toe. After building the game, you should know enough about the basic principles of socket applications that you will be able to begin exploring network programming for yourself.

Background

Besides an Address and Port, your application should also have a protocol. A protocol is a small "language" that your application will use to communicate with other computers. Many established protocols are already out there for you to use (http, SMTP, et al), but for this example we will construct our own simple tic-tac-toe protocol. Our protocol will use three commands: Opponent Moved, Opponent Quit, and I Win. These are the three commands that our application will send and receive. To speed things up, we will abbreviate the commands in a group of four letters followed by a number in two cases. Listing 1 details the commands in the protocol.

The heart of REALbasic TCP programming is the Socket control (see Figure 1). It is through the Socket control which your application will "talk" to the outside world. As such, a Socket control has two important properties. They include Address and Port.


Figure 1. The Socket Control.

The Address property is the IP address, which can be found in the TCP control panel or the Remote Access log if you are using dialup networking. The property is a string and can be set directly within the REALbasic IDE or later by code in your program during runtime. The Port property is an integer that tells a socket control where to focus its sending and receiving efforts. A TCP port is somewhat analogous to a television channel. Just as particular types of content appear on certain television channels, certain types of information appear on specific port numbers. Some port numbers are already reserved for use by protocols covering web, email, chat, telnet communication, and many more, while other port numbers are free for you to use as you see fit. A nice list of reserved port numbers can be found in the reference section of this article. For example, port 80 is used for http communication (i.e. web pages), while port 25 is used for Simple Mail Transfer. For our example, we will use port 815.

Listing 1. - A Simple Tic-Tac-Toe Protocol

Command		Function			Parameters
oppm#	Opponent Moved	Requires an integer indicating location of move
opqu			Opponent Quit		None
iwin#		I Win	Requires an integer indicating location of win

How this protocol is used will become more apparent as the project progresses, so be patient if it doesn't make sense to you yet.

One final point to note about our project is that it will really be built in two parts. One game board will be the server, while the other will act as the client. Although this functionality could be built into a single application, it will help you to see how a client differs from a server by separating the functionality. Despite this separation, however, you will quickly notice that the two applications share a lot of the same code. Both will respond to and send move "events". The difference lies in the initialization of the game. The server begins by opening a socket control and listening for a player wishing to join the game. The client then opens a socket and sends a message to the server, asking to join the game. Game play begins with both server and client responding similarly to normal game play actions. When the game is over, both the client and server close their respective sockets.

Building the Server

First, we will first construct the Tic-Tac-Toe server. Begin by starting up REALbasic. Version 1 or 2 will work here, though the source code included on the MacTech ftp site will only work with version 2.0 or higher. You are presented with a default project with one Window entitled Window1. Double-click Window1 and add two Editfields, two PushButtons, and a StaticText. Name each of the controls as shown in Listing 2. You can also change the Caption property of the PushButtons to read "Start Game" and "End Game".

Listing 2. Window 1 Controls.

Control Type		Name
PushButton			StartButton
PushButton			EndButton
Editfield			IPBox
Editfield			PortBox
StaticText			Status

Next, drag a Line onto the Window1. It can be of any length, because we will change it in code, but you might want to change its color to something that stands out. It will be used to indicate where a win occurs. Name the Line "WinLine".

To build the Tic-Tac-Toe game board, we will use an array of BevelButtons. If control arrays are new to you, begin by adding a BevelButton and changing its Name property to "gametiles" and its Index property to zero (i.e. "0"). Now, whenever you create a BevelButton that shares the same name, REALbasic will automatically add an Index number for you. Make a grid of nine BevelButtons.

In addition to the interface controls, the window needs a Socket control. Drag the control onto the window (location is unimportant) and change the Port property to 815.

Finally, to spruce things up, you can also add some StaticText controls to label parts of your game. For instance, the server game player will be 'X' and the client will be 'O'. Make a note of that. Label the IP and Port Edifields with StaticText controls. By now, your application should look something like Figure 2.


Figure 2. The server interface layout.

Now the time has come to add some code to the server. Begin by double-clicking Window1. Select the menu Edit..New Property and create two Boolean variables called GameRunning and ServersTurn. These are two flags that will be used to track whose turn it is and whether or not there is a game in session. Next, return to Window1 and double-click the StartButton. The code editor will open in the Action event of the PushButton. Enter the code as shown in Listing 3.

Listing 3. StartButton Code.

Sub Action()
	//Fire up socket1
	//to begin listening
	//for commands from a client
	socket1.address=IPBox.text
	socket1.port=val(PortBox.text)
	socket1.listen

	//set up the game
	status.text="Game started...Waiting for a player."
	EnableAllTiles
	ClearBoard
	winline.visible=false
	me.enabled=false
	EndButton.enabled=true
End Sub

In this code, we set up the Socket control by assigning the values from the Edifields. Since the port property of a Socket control is an integer, convert the PortBox text to a number by using the val() method. Next, the Socket is told to start listening on the given address and port. The rest of the code sets up the interface, enabling and disabling controls. Notice the two new methods used here. EnableAllTiles and ClearBoard will be defined later in the article.

Once the Socket has begun listening, nothing will happen until it receives some data, presumably from a client. Once a connection is made the Connected event of the Socket fires. In the code editor, go to the Connected event of the Socket control and add the code from Listing 4.

Listing 4. The Connected event of the Socket control.

Sub Connected()
	//A client has requested to play 
	//a game with this server
	//set up game play
	status.text="Player joined"
	GameRunning=true
	ServersTurn=true
End Sub()

Now that the Socket has received a connection from a client, it sits and waits for data. To respond to incoming data from the client, enter the code in Listing 5 into the Data Available event of Socket1.

Listing 5. DataAvailable Event

\Sub DataAvailable()
	dim s as string
	dim cmd as string
	dim i as integer

	//read what was sent to the server's socket1
	s=me.readall
	cmd=left(s,4)
	Select Case cmd
	case "oppm"
	//The opponent has moved.
	//First find outwhich tile.
	i=val(mid(s,5,1))
	//then, make sure the tile is blank
	if gametile(i).caption="" then
	//the client has "o" 
	//server has "x"
	gametile(i).caption="O"
	gametile(i).enabled=false
	ServersTurn=true
	status.text="Your turn"
	CheckForAWin
	end if
	case "opqu"
	//the opponent quit the game
	me.close
	Status.text="Game Over."
	GameRunning=false
	DisableAllTiles
	case "iwin"
	//the opponent has won
	me.close
	startbutton.enabled=true
	endbutton.enabled=false
	Status.text="You Lose." + chr(13) + "Game Over"
	GameRunning=false
	DisableAllTiles
	ServersTurn=true
	i=val(mid(s,5,1))
	WeLose(i)
	End Select

End Sub()

This code is where Socket1 responds to incoming data. What type of data, you might ask? Here is where the protocol we discussed earlier comes into play. We will respond to the commands in Listing 1. First, we read all of the data in the socket's buffer. Next, we parse out the first four characters and do something based on which command was sent. Again, if you notice Methods listed here that are unfamiliar, that is because we have not made them yet.

So far, we have only dealt with receiving data from a client. How do we send data to the client? Double-click on one of the gametiles. The beauty of having a control array is that we only have to add code one time. The same code can apply to all of the BevelButtons. We distinguish which button is being pressed by examining the button's index property. Listing 6 shows the code that should be entered into the gametile. Some game variables are changed and the interface is updated, but the most important thing to notice is regarding the Socket. First, a string is constructed that includes the "oppm" command. Then, the socket sends the string to the client by using the Write method of Socket1. This data will be intercepted by the client in much the same way this server received data in the Data Available event in Listing 5.

Listing 6. Action Event of gametiles.

Sub Action (Index As Integer)
	dim s as string

	if GameRunning=true then
		if ServersTurn=true then
		me.enabled=false
		me.caption="X"
		//construct a 'move' string to send to
		//the client
		s="oppm"+str(Index)
		//switch players for next round
		ServersTurn=false
		status.text="Other Player's turn"
		CheckForAWin
		//let the client know about the move
		socket1.write s
		end if
	end if
End Sub

The final control needing code is the EndButton (Listing 7). This button is included in the event that a user wants to end a game prematurely or if the game is a draw. It merely resets the game board, variables, and sends out a quit command to the client.

Listing 7. The EndButton Action event.

Sub Action()
	//Socket1.close
	Status.text="Game Over."
	GameRunning=false
	DisableAllTiles

	ServersTurn=false
	me.enabled=false
	StartButton.enabled=true

	socket1.write "opqu"
End Sub

To wrap up this project, we need to add all of the methods that we have been calling in our code. To define a new method, select the menu Edit...New Method. Listing 8 details the code for the accessory methods.

Listing 8. The methods of Window1.

Window1.ClearBoard:
Sub ClearBoard()
	dim i as integer
	for i=0 to 8
	gametile(i).caption=""
	next
End Sub

Window1.EnableAllTiles:
Sub EnableAllTiles()
	dim i as integer
	for i=0 to 8
	gametile(i).enabled=true
	next
End Sub

Window1.DisableAllTiles:
Sub DisableAllTiles()
	dim i as integer
	for i=0 to 8
	gametile(i).enabled=false
	next
End Sub

Window1.CheckForAWin:
Sub CheckForAWin()
	//check the horizontal wins
	if (gametile(0).caption="X") and (gametile(1).caption="X") and (gametile(2).caption="X")
	WeHaveAWinner(1)
	end if
	if (gametile(3).caption="X") and (gametile(4).caption="X") and (gametile(5).caption="X")
	WeHaveAWinner(2)
	end if
	if (gametile(6).caption="X") and (gametile(7).caption="X") and (gametile(8).caption="X")
	WeHaveAWinner(3)
	end if
	//check the vertical wins
	if (gametile(0).caption="X") and (gametile(3).caption="X") and (gametile(6).caption="X")
	WeHaveAWinner(4)
	end if
	if (gametile(1).caption="X") and (gametile(4).caption="X") and (gametile(7).caption="X")
	WeHaveAWinner(5)
	end if
	if (gametile(2).caption="X") and (gametile(5).caption="X") and (gametile(8).caption="X")
	WeHaveAWinner(6)
	end if
	//check the diagonal wins
	if (gametile(0).caption="X") and (gametile(4).caption="X") and (gametile(8).caption="X")
	WeHaveAWinner(7)
	end if
	if (gametile(2).caption="X") and (gametile(4).caption="X") and (gametile(6).caption="X")
	WeHaveAWinner(8)
	end if
End Sub

Window1.WeHaveAWinner:
Sub WeHaveAWinner(w as integer)
	Select Case w
	//draw horizontal wins
	case 1
	WinLine.x1=14
	WinLine.x2=189
	WinLine.y1=90
	WinLine.y2=90
	case 2
	WinLine.x1=14
	WinLine.x2=189
	WinLine.y1=147
	WinLine.y2=147
	case 3
	WinLine.x1=14
	WinLine.x2=189
	WinLine.y1=205
	WinLine.y2=205
	//draw vertical wins
	case 4
	WinLine.x1=44
	WinLine.x2=44
	WinLine.y1=59
	WinLine.y2=230
	case 5
	WinLine.x1=104
	WinLine.x2=104
	WinLine.y1=59
	WinLine.y2=230
	case 6
	WinLine.x1=163
	WinLine.x2=163
	WinLine.y1=59
	WinLine.y2=230
	//draw diagonal wins
	case 7
	WinLine.x1=14
	WinLine.x2=191
	WinLine.y1=59
	WinLine.y2=233
	case 8
	WinLine.x1=191
	WinLine.x2=14
	WinLine.y1=59
	WinLine.y2=233
	End Select
	//display where the win is
	//with a red line
	WinLine.visible=true
	//tell the client that we won
	socket1.write "iwin"+str(w)
	//reset the game state
	startbutton.enabled=true
	endbutton.enabled=false
	Status.text="You Win." + chr(13)+"Game Over"
	GameRunning=false
	DisableAllTiles
	ServersTurn=true
End Sub

Window1.WeLose:
Sub WeLose(w as integer)
	//The client won, and this
	//shows where
	Select Case w
	//horizontals
	case 1
	WinLine.x1=14
	WinLine.x2=189
	WinLine.y1=90
	WinLine.y2=90
	case 2
	WinLine.x1=14
	WinLine.x2=189
	WinLine.y1=147
	WinLine.y2=147
	case 3
	WinLine.x1=14
	WinLine.x2=189
	WinLine.y1=205
	WinLine.y2=205
	//verticals
	case 4
	WinLine.x1=44
	WinLine.x2=44
	WinLine.y1=59
	WinLine.y2=230
	case 5
	WinLine.x1=104
	WinLine.x2=104
	WinLine.y1=59
	WinLine.y2=230
	case 6
	WinLine.x1=163
	WinLine.x2=163
	WinLine.y1=59
	WinLine.y2=230
	//diags
	case 7
	WinLine.x1=14
	WinLine.x2=191
	WinLine.y1=59
	WinLine.y2=233
	case 8
	WinLine.x1=191
	WinLine.x2=14
	WinLine.y1=59
	WinLine.y2=233
	End Select
	WinLine.visible=true
End Sub

Window1.Open:
Sub Open()
	//Some Initilization
	GameRunning=false
	EndButton.enabled=false
End Sub

Building the Client

Once all of the code has been entered, select the menu File...Build Application and build a copy of the application and don't forget to save the project. Close REALbasic and make a copy of the server project and open it. This will be the basis for our client version of the Tic-tac-toe game. Open the Action event for the gametile and replace the code with that in Listing 9.

Listing 9. The Client gametile Action Event.

Sub Action(Index As Integer)
	dim s as string
	if GameRunning=true then
	if ServersTurn=false then
	ServersTurn=true
	me.enabled=false
	me.caption="O"
	s="oppm"+str(Index)
	Status.text="Other Player's Turn"
	CheckForAWin
	Socket1.write s
	end if
	end if
End Sub()

Another difference in the client version is that the client tries to connect to the server instead of sitting around and listening like the server does. Listing 10 details the code.

Listing 10 The Client StartButton Action Event.

Window1.StartButton.Action:
Sub Action()
	socket1.address=IPBox.text
	socket1.port=val(PortBox.text)
	//Connects instead of Listens!!!
	socket1.connect
	WinLine.visible=false
	me.enabled=false
	EndButton.enabled=true
End Sub

Listing 11 shows the DataAvailable event for the client socket. You will notice that the code is nearly identical. Only a few changes have been made that are related to the server being X's and the client being O's. Hard coding the players designation is normally not a good idea. What if the client wants to be X? However, for this demonstration, we will simplify matters by assuming some parameters.

Listing 11.

Window1.Socket1.DataAvailable:
Sub DataAvailable()
	dim s as string
	dim cmd as string
	dim i as integer
	//the commands
	//oppm# - The opponent made a move on tile#
	//opqu - The opponent has quit the game.
	//
	s=me.readall
	cmd=left(s,4)
	Select Case cmd
	case "oppm"
	//The opponent has moved
	//to which tile?
	i=val(mid(s,5,1))
	//make sure the tile is blank first
	if gametile(i).caption="" then
	//the client has "o"
	//server has "x"
	gametile(i).caption="X"
	gametile(i).enabled=false
	ServersTurn=false
	status.text="Your Turn"
	CheckForAWin
	end if
	case "opqu"
	me.close
	Status.text="Game Over."
	GameRunning=false
	DisableAllTiles
	case "iwin"
	//WinLine.visible=true
	//socket1.write "iwin"
	me.close
	startbutton.enabled=true
	endbutton.enabled=false
	Status.text="You Lose." + chr(13)+"Game Over"
	GameRunning=false
	DisableAllTiles
	ServersTurn=true
	i=val(mid(s,5,1))
	WeLose(i)
	End Select
End Sub

The last change to make to the code involves the Socket Connected event. Whereas the server socket fires the Connected event when the client requests to play a game, the client's Connected event will fire after the server accepts a connection from the client. Listing 12 shows the necessary changes.

Window1.Socket1.Connected:

Sub Connected()
	GameRunning=true
	ServersTurn=true
	status.text="Game started." + chr(13) + "Other Players turn"
	EnableAllTiles
	ClearBoard
End Sub

Testing the Game

Having morphed the copy of the server project into a client by hanging a bit of code, select the menu File...Build Application and build a client version. To test the game, start up both the server and client applications. Enter your IP address into the appropriate boxes in both applications. Next, click on the StartButton in the server window. This initiates the game. The server sits and waits for a client to join. Click on the client window and press the StartButton. If everything goes right, you should see confirmation that the game has begun and information regarding which players turn it is. Go ahead and play yourself in Tic-Tac-Toe. Try quitting early and winning in different manners.

Improvements

You will probably notice some places where the game could be improved. Absolutely! These applications do not check for errors, which is always important, but was left out for the sake of simplicity. Further, the two applications could be easily merged into one. The user can then decide if he wishes to be the server or the client. Again, this was avoided for demonstration purposes. Besides, you may sometimes want to have separate server and client applications. In the multimedia realm, the game could be improved with fancy graphics and sound as well as a scoreboard and a host of other features. These are all areas for you to explore. REALbasic makes it easy to do so.

Conclusion

In this article we looked at a basic server/client Tic-Tac-Toe game and introduced the Socket control. Not all aspects of the control were covered. To learn more about the socket control you should consult some other references.

As usual, the web is a good place to start exploring more information about socket communication with REALbasic. Check the reference section for a list of sites that have something to offer. Furthermore, Matt Neuberg's book REALbasic: The Definitive Guide offers several excellent socket examples, including email, web servers, and an online dictionary application. Finally, a peek at the documentation provided by REALbasic will also give you a good background in REALbasic sockets.

The world of network applications is constantly evolving and there are still many opportunities for programmers to make new advances in network applications. REALbasic offers the beginner a great way to easily learn about the topic, while providing the advanced programmer a rich set of features for utilizing TCP communication. Have fun exploring and be sure to send me all Battleship[TM] games you concoct!

References


Erick J. Tejkowski is a web developer in for the Zipatoni Company in St. Louis, MO. In his spare time, he programs shareware and freeware for his own Purple E Software. You can reach him at ejt@norcom2000.com.

 
AAPL
$99.00
Apple Inc.
+1.33
MSFT
$44.07
Microsoft Corpora
-0.43
GOOG
$589.79
Google Inc.
+0.77

MacTech Search:
Community Search:

Software Updates via MacUpdate

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
TinkerTool 5.3 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Audio Hijack Pro 2.11.0 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Intermission 1.1.1 - Pause and rewind li...
Intermission allows you to pause and rewind live audio from any application on your Mac. Intermission will buffer up to 3 hours of audio, allowing users to skip through any assortment of audio... Read more
Autopano Giga 3.6 - Stitch multiple imag...
Autopano Giga allows you to stitch 2, 20, or 2,000 images. Version 3.0 integrates impressive new features that will definitely make you adopt Autopano Pro or Autopano Giga: Choose between 9... Read more

Latest Forum Discussions

See All

Traps n’ Gemstones Review
Traps n’ Gemstones Review By Campbell Bird on July 28th, 2014 Our Rating: :: CASTLEVANIA JONESUniversal App - Designed for iPhone and iPad Fight mummies, dig tunnels, and ride a runaway minecart to discover ancient secrets in this... | Read more »
The Phantom PI Mission Apparition Review
The Phantom PI Mission Apparition Review By Jordan Minor on July 28th, 2014 Our Rating: :: GHOSTS BUSTEDUniversal App - Designed for iPhone and iPad The Phantom PI is an exceedingly clever and well-crafted adventure game.   | Read more »
More Stubies Are Coming Your Way in a Ne...
More Stubies Are Coming Your Way in a New Update Posted by Jessica Fisher on July 28th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
The Great Prank War Review
The Great Prank War Review By Nadia Oxford on July 28th, 2014 Our Rating: :: PRANKING IS SERIOUS BUSINESSUniversal App - Designed for iPhone and iPad Though short, The Great Prank War offers an interesting and fun mix of action and... | Read more »
Marvel Contest of Champions Announced at...
Marvel Contest of Champions Announced at Comic-Con Posted by Jennifer Allen on July 28th, 2014 [ permalink ] Announced over the weekend at San Diego Comic-Con was the fairly exciting looking Marvel Contest of Champions. | Read more »
Teenage Mutant Ninja Turtles Review
Teenage Mutant Ninja Turtles Review By Jennifer Allen on July 28th, 2014 Our Rating: :: DULL SWIPINGUniversal App - Designed for iPhone and iPad The pizza power is weak when it comes to this Teenage Mutant Ninja Turtles game.   | Read more »
Exploration Focused Puzzle Game Beatbudd...
Exploration Focused Puzzle Game Beatbuddy Set to Make Transition from PC to iOS this September Posted by Jennifer Allen on July 28th, 2014 [ permalink ] | Read more »
PlanetHD
PlanetHD By Nadia Oxford on July 28th, 2014 Our Rating: :: SPACE MADNESSUniversal App - Designed for iPhone and iPad PlanetHD will keep players busy for a while, though its unpredictable physics are a handful to deal with.   | Read more »
This Week at 148Apps: July 21-25, 2014
Another Week of Expert App Reviews   At 148Apps, we help you sort through the great ocean of apps to find the ones we think you’ll like and the ones you’ll need. Our top picks become Editor’s Choice, our stamp of approval for apps with that little... | Read more »
Reddme for iPhone - The Reddit Client (...
Reddme for iPhone - The Reddit Client 1.0 Device: iOS iPhone Category: News Price: $.99, Version: 1.0 (iTunes) Description: Reddme for iPhone is an iOS 7-optimized Reddit client that offers a refreshing new way to experience Reddit... | Read more »

Price Scanner via MacPrices.net

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
Roundup of Apple refurbished MacBook Pros, th...
The Apple Store has Apple Certified Refurbished 13″ and 15″ MacBook Pros available for up to $400 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. Their prices... Read more
Record Mac Shipments In Q2/14 Confound Analys...
A Seeking Alpha Trefis commentary notes that Apple’s fiscal Q3 2014 results released July 22, beat market predictions on earnings, although revenues were slightly lower than anticipated. Apple’s Mac’... Read more
Intel To Launch Core M Silicon For Use In Not...
Digitimes’ Monica Chen and Joseph Tsai, report that Intel will launch 14nm-based Core M series processors specifically for use in fanless notebook/tablet 2-in-1 models in Q4 2014, with many models to... Read more
Apple’s 2014 Back to School promotion: $100 g...
 Apple’s 2014 Back to School promotion includes a free $100 App Store Gift Card with the purchase of any new Mac (Mac mini excluded), or a $50 Gift Card with the purchase of an iPad or iPhone,... Read more
iMacs on sale for $150 off MSRP, $250 off for...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
Mac minis on sale for $100 off MSRP, starting...
Best Buy has Mac minis on sale for $100 off MSRP. Choose free shipping or free instant local store pickup. Prices are for online orders only, in-store prices may vary: 2.5GHz Mac mini: $499.99 2.3GHz... Read more
Global Tablet Market Grows 11% in Q2/14 Notwi...
Worldwide tablet sales grew 11.0 percent year over year in the second quarter of 2014, with shipments reaching 49.3 million units according to preliminary data from the International Data Corporation... Read more
New iPhone 6 Models to Have Staggered Release...
Digitimes’ Cage Chao and Steve Shen report that according to unnamed sources in Apple’s upstream iPhone supply chain, the new 5.5-inch iPhone will be released several months later than the new 4.7-... Read more
New iOS App Helps People Feel Good About thei...
Mobile shoppers looking for big savings at their favorite stores can turn to the Goodshop app, a new iOS app with the latest coupons and deals at more than 5,000 online stores. In addition to being a... Read more

Jobs Board

*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
WW Sales Program Manager, *Apple* Online St...
**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
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.