Thursday, March 26, 2009

Sample Source Code : iPhone OS 3.0 peer to peer bluetooth connectivity

Just saw a sample source code from the apple dev forum to sharing the testing the p2p bluetooth

What you need to do is to create a new project from OpenGL ES Application of iPhone OS 3.0 SDK template called it BluetoothSample
and past the codes as below and test, it should work on 2 iPhone 3G and iPod Touch 2nd gen only.

Then you need to add GameKit framework to build and go

The source is from Travis True

BluetoothSampleAppDelegate.h Select all

//
// BluetoothSampleAppDelegate.h
// BluetoothSample
//

#import "EAGLView.h"
#import <GameKit/GameKit.h>

@interface BluetoothSampleAppDelegate : NSObject {
UIWindow *window;
EAGLView *glView;

GKPeerPickerController *picker;
GKSession *session;

int myNumber;
NSData *myData;
UILabel *textView;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet EAGLView *glView;
@property (nonatomic, retain) GKPeerPickerController *picker;
@property (nonatomic, retain) GKSession *session;

- (void)mySendData;

@end



BluetoothSampleAppDelegate.m Select all

//
// BluetoothSampleAppDelegate.m
// BluetoothSample
//

#import "BluetoothSampleAppDelegate.h"

@implementation BluetoothSampleAppDelegate

@synthesize picker;
@synthesize session;
@synthesize window;
@synthesize glView;

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// setup the text view
myNumber = 0;
textView = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 640.0f, 12.0f)];
textView.text = [NSString stringWithFormat:@"myNumber: %i\n", myNumber];
[window addSubview:textView];
[window bringSubviewToFront:textView];

// start the EAGLView
glView.animationInterval = 1.0 / 60.0;
[glView startAnimation];

// allocate the NSData
myData = [[NSData alloc] initWithBytes:&myNumber length:sizeof(int)];


// allocate and setup the peer picker controller
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline;
[picker show];
}


- (void)applicationWillResignActive:(UIApplication *)application {
glView.animationInterval = 1.0 / 5.0;
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
glView.animationInterval = 1.0 / 60.0;
}


- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {
if(type == GKPeerPickerConnectionTypeOnline) {
[self.picker dismiss];
[self.picker release];
self.picker = nil;
// Display your own UI here.
}
}


- (GKSession *) peerPickerController:(GKPeerPickerController *)picker
sessionForConnectionType:(GKPeerPickerConnectionType)type {
session = [[GKSession alloc] initWithSessionID:@"FR" displayName:nil sessionMode:GKSessionModePeer];
session.delegate = self;

return session;
}


- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
switch (state) {
case GKPeerStateConnected:
[self.session setDataReceiveHandler :self withContext:nil];
[self mySendData]; // start off by sending data upon connection
break;

case GKPeerStateDisconnected:
break;
}
}


- (void)peerPickerController:(GKPeerPickerController *)picker didConnectToPeer:(NSString *)peerID {
printf("connection was successful! start the game.\n");
}


- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker {
printf("connection attempt was canceled\n");
}


- (void)mySendData {
// allocate the NSData
myNumber++;
myData = [[NSData alloc] initWithBytes:&myNumber length:sizeof(int)];
[session sendDataToAllPeers :myData withDataMode:GKSendDataReliable error:nil];
printf("send data: %i\n", myNumber);
textView.text = [NSString stringWithFormat:@"myNumber: %i\n", myNumber];
}


- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
// Read the bytes in data and perform an application-specific action, then free the NSData object
[data getBytes:&myNumber length:sizeof(int)];
printf("received data: %i from: %s\n", myNumber, [peer UTF8String]);
textView.text = [NSString stringWithFormat:@"myNumber: %i\n", myNumber];

[self mySendData];
}


- (void)dealloc
{
[picker release];
[session release];
[textView release];
[glView release];
[window release];
[super dealloc];
}


@end

22 comments:

Anonymous said...

Ok, so my question is, how do you actually test this? You can't deploy to a device yet. Does the SDK use the mac's bluetooth? Does it talk from one simulator to another?!

javacom said...

If you have two devices with OS 3.0 beta, you can test it.

Or you can test one iPhone device with the iPhone Simulator, SDK beta 2 Simulator and iPhone OS 3.0 beta 2 support this.

Jim Carter said...

Thanks for sharing the code. i was able to compile it just fine but I can't get the connection to work with an iPhone 3G with os3 and the newest SDK Simulator. is there any special trick to it or a special setting on the simulator I'm missing.

Gideon Kowadlo said...

For me, the GameKit framework did not exist in the default location, but in Developer/Platforms/iPhoneOS.platform/Developer/SKDs/iPhoneOS3.0.skd/System/Library/Frameworks.

Is this a problem? Does it conflict with the other framework's versions?

Thanks a lot to anyone who can help.

Anonymous said...

You also need to have your interface implement the GKSessionDelegate and GKPeerPickerControllerDelegate protocols in order to get this to compile. I am trying this on two iPod touches. I can get them to send and receive data, but the Peer Picker dialog never goes away. I am dismissing and releasing it in the didConnectToPeer method, but it seems to never get called. Stepping through the code I can see that the state does change to connected, but I can't dismiss the dialog in order to return to my original view. Frustrating that there aren't more examples than this. There must be thousands of developers working on this right now.

Unknown said...

Not only in opengl app,It aslo worked in viewcontroller.And it will also talk from simulator to simulator.I need to know that how we set a name for a particular bluetooth device(iphone/ipod)

mathew said...

Hey guys i am new to iphone programming. I tried to build this with iphone sdk 3.0 simulator and got these errors.


".objc_class_name_GKSession", referenced from:
literal-pointer@__OBJC@__cls_refs@GKSession in BluetoothSampleAppDelegate.o
".objc_class_name_GKPeerPickerController", referenced from:
literal-pointer@__OBJC@__cls_refs@GKPeerPickerController in BluetoothSampleAppDelegate.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


could some one help me on this

Anonymous said...

amm, nice tut... could you tell me, can i use it for connecting iphone with mac? not iphone2iphone

Unknown said...

Mathew,what you need to do is add a GameKit framework as well as import a header file
(#import GameKit/GameKit.h) in .h file

in order to add a framework,open the frameworks folder in Groups & files at the left of the screen.
Right click on any of the framework and choose
"open with finder"

Here you will see a list of frameworks,in that select
Gamekit framework,Drag and Drop it in your frameworks folder,you will get a pop up window with checkbox at top left corner,"DONT CLICK THE
CHECKBOX" .click Add,now build the code and it runs.

jgbradley1 said...

Does anyone else get a "error: 'expected specific-qualifier-list before 'GKPeerPickerController'" when they try and build this

JR said...

Hey Matthew... ever solve your issue? I get the same error, and the GameKit framework was already added and I also have the import GameKit.h line in my .h file.. otherwise does anyone else have any ideas?

Anonymous said...

I have 2 warnings

BluetoothSampleAppDelegate.m:35: warning: class 'BluetoothSampleAppDelegate' does not implement the 'GKPeerPickerControllerDelegate' protocol

BluetoothSampleAppDelegate.m:64: warning: class 'BluetoothSampleAppDelegate' does not implement the 'GKSessionDelegate' protocol

Anonymous said...

Those two warnings, I've noticed, happen when I compile for the SIMULATOR, but not for an actual device. I think adding the gamekit library from the simulator directory (search for gamekit, you'll see there are copies for both "platforms") will fix that.

Beyond that, this seems to be working for me -- on top of my original opengl, which I was worried about. Nice!

Unknown said...

Hi there,

I have different quetion. Is it possible with iPhone SDK somehow to just list (without connecting) MAC addresses of bluetooth devices in range?

James said...

I too get the warnings in the SDK, however it doesn't matter what you're running it on (device or sim) the build will always show the warnings unless you fix them.

Anonymous said...

Could i connect to iphone and other bluetooth device ?


hi...
i want to develop one iPhone application , it should be capable to connect and send data with other bluetooth device ( it may be iphone/ ipod touch,other mobile phone or any bluetooth device , such as PC, bluetooth sticker and so on..)

is it possible in iphone using iPhone programming code.. ?

is possible pls give the the way...

pls help me ..

Anonymous said...

How to sovle the "error: EAGLView.h: No such file or directory"?
In my code ,the "EAGLView *glView;" ,which about the forword thing(EAGLView) didn't change color. Who can tell me the reason?

Thanks a lot~~

Anonymous said...

How to sovle the "error: request for member 'animationInterval' in something not a structure or union"?

What's this sector meaning?

// start the EAGLView
glView.animationInterval = 1.0/60.0;
[glView startAnimation];


Thanks!

Anonymous said...

"How to sovle the "error: request for member 'animationInterval' in something not a structure or union"?"

Change every instance of "animationInterval" to "animationFrameInterval" and see if that works. (Apparently the implementation of EAGLView.h has changed since this code was originally written.)

Unknown said...

Hi,
just change it to glView.animationFrameInterval

It wil work (:

Masahiro said...

Picker Dialog dismisses as follows,


switch (state) {
case GKPeerStateConnected:
[self.picker dismiss];// addtional line

Anonymous said...

I am new to iphone programmaing.I am implementing a Quiz app between number of users via bluetooth.My question is that when i establish connection between two iphones then when the view changes will the bluetooth connection will be ended. Will the classes with new view will be able to get data through bluetooth without re-establishing connection.