Post Pic

iPhone SDK 3.0 – Playing with Game Kit – Part 1

I finally got some time to play with GameKit today and it is pretty simple to establish connectivity between two devices over bluetooth.

All you need to understand are 2 classes.

GKPeerPickerController and GKSession

You could create your own interface for establishing connection between 2 devices, but Apple provides a nice interface via the GKPeerPickerController

As with the Map Kit and other frameworks supported by Apple, they use the powerful delegate pattern to accomplish communication between the devices.

As such there are two delegates you need to make yourself familiar with. They are

GKPeerPickerControllerDelegate and GKSessionDelegate

Just create a simple View based project, Add Game Kit framework to your project, then Just go to your controller and implement the 2 delegates from above. Here is my code, My project is named GameKitTest, thus the name of the file GameKitTestController

The data transfer between the clients happens using NSData objects. For purposes of this discussion you just need to know how to convert back and forth from NSData to NSString. Here is a quick snippet

From NSString to NSData:

1
2
NSString* aStr;
aStr = [[NSString alloc] initWithData:aData encoding:NSASCIIStringEncoding];

From NSData to NSString:

1
2
NSData* aData;
aData = [aStr dataUsingEncoding: NSASCIIStringEncoding];

OK, Now with our further adieu here is the code

Header File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
//
//  GameKitTestViewController.h
//  GameKitTest
//
//  Created by Gavi Narra on 6/16/09.
//  Copyright ObjectGraph LLC 2009. All rights reserved.
//
 
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
 
@interface GameKitTestViewController : UIViewController<GKPeerPickerControllerDelegate,GKSessionDelegate> {
	GKPeerPickerController *mPicker;
	GKSession *mSession;
	IBOutlet UITextField *mTextField;
	IBOutlet UITextView *mTextView;
	NSMutableArray *mPeers;
}
 
-(IBAction) connectClicked:(id)sender;
-(IBAction) sendData:(id)sender;
@property (retain) GKSession *mSession;
 
@end

Main File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//
//  GameKitTestViewController.m
//  GameKitTest
//
//  Created by Gavi Narra on 6/16/09.
//  Copyright ObjectGraph LLC 2009. All rights reserved.
//
 
#import "GameKitTestViewController.h"
 
@implementation GameKitTestViewController
 
@synthesize mSession;
 
 
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/
 
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
 
 
 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
 
	mPicker=[[GKPeerPickerController alloc] init];
	mPicker.delegate=self;
	mPicker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline;
	mPeers=[[NSMutableArray alloc] init];
}
 
 
 
 
 
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
 
- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
 
	// Release any cached data, images, etc that aren't in use.
}
 
- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}
 
 
- (void)dealloc {
	[mPeers release];
    [super dealloc];
}
 
#pragma mark Events
 
-(IBAction) connectClicked:(id)sender{
//Show the connector
	[mPicker show];
}
 
#pragma mark PeerPickerControllerDelegate stuff
 
/* Notifies delegate that a connection type was chosen by the user.
 */
- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type{
	if (type == GKPeerPickerConnectionTypeOnline) {
        picker.delegate = nil;
        [picker dismiss];
        [picker autorelease];
		// Implement your own internet user interface here.
    }
}
 
/* Notifies delegate that the connection type is requesting a GKSession object.
 
 You should return a valid GKSession object for use by the picker. If this method is not implemented or returns 'nil', a default GKSession is created on the delegate's behalf.
 */
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type{
 
	//UIApplication *app=[UIApplication sharedApplication];
	NSString *txt=mTextField.text;
 
	GKSession* session = [[GKSession alloc] initWithSessionID:@"gavi" displayName:txt sessionMode:GKSessionModePeer];
    [session autorelease];
    return session;
}
 
/* Notifies delegate that the peer was connected to a GKSession.
 */
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session{
 
	NSLog(@"Connected from %@",peerID);
 
	// Use a retaining property to take ownership of the session.
    self.mSession = session;
	// Assumes our object will also become the session's delegate.
    session.delegate = self;
    [session setDataReceiveHandler: self withContext:nil];
	// Remove the picker.
    picker.delegate = nil;
    [picker dismiss];
    [picker autorelease];
	// Start your game.
}
 
-(IBAction) sendData:(id)sender{
 
	NSString *str=@"Hello SaiBaba";
	[mSession sendData:[str dataUsingEncoding: NSASCIIStringEncoding] toPeers:mPeers withDataMode:GKSendDataReliable error:nil];
}
 
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
    // Read the bytes in data and perform an application-specific action.
 
	NSString* aStr;
	aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	NSLog(@"Received Data from %@",peer);
	mTextView.text=aStr;
 
 
}
 
/* Notifies delegate that the user cancelled the picker.
 */
- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker{
 
}
 
#pragma mark GameSessionDelegate stuff
 
/* Indicates a state change for the given peer.
 */
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state{
 
	switch (state)
    {
        case GKPeerStateConnected:
		{
			NSString *str=[NSString stringWithFormat:@"%@\n%@%@",mTextView.text,@"Connected from pier ",peerID];
			mTextView.text= str;
			NSLog(str);
			[mPeers addObject:peerID];
			break;
		}
        case GKPeerStateDisconnected:
		{
			[mPeers removeObject:peerID];
 
			NSString *str=[NSString stringWithFormat:@"%@\n%@%@",mTextView.text,@"DisConnected from pier ",peerID];
			mTextView.text= str;
			NSLog(str);
			break;
		}
    }
}
 
@end

Related posts:

  1. iPhone SDK 3.0 – Playing with Map Kit – Part 2 This is the second part of "Playing with Map Kit"...
  2. iPhone SDK 3.0 – Playing with Map Kit – Part 3 This is the 3 part of me Playing with Map...
  3. Twitter + iPhone = MyTweet A simple twitter client using Objective C API provided by...
  4. iPhone SDK 3.0 – Playing with Map Kit I started looking at the Map Kit API for developing...
  5. iPhone Development and a sample Objective C Program Kiichi and myself are learning how to program in Objective...

Related posts brought to you by Yet Another Related Posts Plugin.

18 Responses

07.01.09

Horrible code formatting and indentation!

But good effort and information! :)

I hope you won’t delete my comment! How lame to not recognize your shortcomings!

07.01.09

Actually I did not do any custom code formatting. Just copied and pasted directly from XCode

07.01.09

I’m with the iphone programming, and i am trying to learn how to use the iphone’s bluetooth….I understand most of the code, but i don’t get where and how do you send the string to the other device, i copy the code and ran it, but nothing happends, can you help me please?

thanks in advance

07.01.09

@Macs
You need 2 devices to make this work. It could be an iPhone or iPod Touch, both should be running iPhone 3.0

There is a way to make it work with Simulator + iPhone device, but i havent had luck with that model yet.

07.01.09

Your Comments

07.01.09

Hi, thank you for your fast answer. I installed the app in 2 iphones, both have os 3.0, but nothing happends

07.01.09

I hope Gurpartap Singh recognizes his shortcomings of being an ass. Apparently he oblivious to how XCode formats text.

07.01.09

Hey can someone tell me how to identify iphone 1st generation or ipod touch 1st generation, as I dont have both device and wish to know how to identy them before calling GKSession. So is there a way to identify the generations of the devices

07.01.09

it’s good .

but can i make a iphone program with bluetooth connect to other mobile’s bluetooth ?

it’s only can work at iphone to iphone ?

07.01.09

@BinLi

You can have only iPhone to iPhone (or iPod Touch) connectivity using GameKit. It does not work with other mobile devices

07.01.09

Nice blog. Just to keep things nice and tidy you should be releasing your dynamically allocated strings at the end of your receive data method.
e.g. [aStr release] should be added at line 140

07.01.09

also bluetooth communication between devices (peer to peer) wont work on the 1st gen iphone, or thats what it says in the sdk info at least

07.01.09

nice job thanks

07.01.09

Nice.. hey do you have more example on the data transfer by making use of this bluetooth pairing :(

07.01.09

Could you please upload full xcode workspace, so that i can take gamekit framwork :( , please do share some moreexamples of luetooth transfer

07.01.09

Hey,

So I am trying to figure out a way to connect an iPhone or an iPod to another device via bluetooth and then obtain some text data similar to the way you did it. I am aware of the fact that I cannot use GameKit to do this, but would you know any other way of doing this?

Any and all help is appreciated! Thanks in advance!

07.01.09

Hey gavi,

acutally i try to develope an app which connects to other devices (none apple-devices) via Bluetooth. I’m pretty new with XCode and I would be happy if you can just tell me IF it is possible and which direction (frameworks or even classes) i have to watch out!
Hoping for any help ;]
Thanks

[...] Playing with the GameKit – Introduction to the GameKit framework allowing connection between two devices using Bluetooth. [...]

Leave Your Response

* Name, Email, Comment are Required