iOS
|
Modified: |
Downloads
HelloWorld application
Note that testing requires:
- simulators on two machines,
- BlueTooth is simulated over a local network,
- both machines must be on the same local network (WiFi, Ethernet connection over a switch or hub, direct Ethernet connection between two machines.
Resources
Overview
BlueTooth is part of the GameKit framework, which provides a simple API. At present, there does not seem to be an API for lower-level BlueTooth protocols.
Service discovery is very simple through the use of Bonjour, which works on BlueTooth, EtherNet and WiFi networks.
Services are advertized by broadcasts over a local network. For our example, HelloWorld is the name of the service with service ID of HelloWorldID.
Below are two cases for advertizing a service:
- A server advertizes a service and waits for a client to discover and connect to the service.
- Several peers advertize the same service and wait for a peer to discover and connect to the service.
Peer-to-peer communication offers several advantages:
- Possibly only one copy of the application executes on multiple peers.
- More robust than client/server since any device can act as a client or a server.
HelloWorld
The basics of peer-to-peer communication are illustrated below. Remember another device is executing the same app.
|
Start by Connect which creates picker.
|
Picker searching for other devices.
|
|
List of nearby devices. User selects.
|
Other (client) device chose first,
|
|
Send/receive message on either device.
|
Code
The code is numbered to reflect the order executed.
- Creates a GKPeerPickerController picker which in turn creates a session.
The picker is a UI for picking devices to connect. The following restricts discovery to only nearby, peer devices.
mPicker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
- Creates a session.
The session object manages the connection with the device the user chooses in the picker; data can be sent and received through a session.
Three key elements in establishing a session are:
- Session or service ID used to identify the services available on a remote device, ours is HelloWorldID.
- Name seen by remote user, ours is HelloWorld; default is device name.
- Session mode:
- server, which advertizes services and wait for connections
- client, which searches for services but does not advertize
- peer, which does both, defined by GKSessionModePeer.
To create a peer session:
GKSession* session = [[GKSession alloc] initWithSessionID: @"HelloWorldID"
displayName: @"HelloWorld"
sessionMode: GKSessionModePeer];
- When remote peer chooses this device, need to:
- retain session object for this peer
- make self the session delegate to receive events
- dismiss the picker UI
- When peer connection made or broken, a state change event occurs.
It is displayed but otherwise ignored here.
- Send or receive "Hello World" message.
Message is sent to all peers that have connected. Note that a reliable transmission is made by:
[mSession sendDataToAllPeers: [@"Hello World"
dataUsingEncoding: NSASCIIStringEncoding]
withDataMode: GKSendDataReliable error:nil];
Receive event signals arrival of a message so blocking for reading data is not necessary.
|
#import <UIKit/UIKit.h> #import <GameKit/GameKit.h> @interface HelloWorldViewController : UIViewController<GKPeerPickerControllerDelegate,GKSessionDelegate> { GKSession *mSession; IBOutlet UITextView *mTextView; } -(IBAction) connectClicked:(id)sender; -(IBAction) sendClicked:(id)sender; @property (retain) GKSession *mSession; @end |
||
|
#import "HelloWorldViewController.h" @implementation HelloWorldViewController @synthesize mSession;
// 4. A remote peer caused a state change.
//
5. Receive data delegate method @end |
For two peers, only one (client peer) will connect to the other (server peer) depending upon the order in which the iPhone/iTouch picked.
The client peer executes on a connection:
- (void)peerPickerController:(GKPeerPickerController *) picker
didConnectPeer:(NSString *)peerID
toSession:(GKSession *)sessionThe server peer executes on a connection:
- (void) session: (GKSession *) session
peer: (NSString *) peerID
didChangeState: (GKPeerConnectionState)stateThis is useful when two peers must perform their function in some order.
For example, in TicTacToe one peer must play X and the other O. Assigning the client peer O and the server peer X in their respective connection delegate methods.