注意:如果要测试本文所介绍的内容,需要两部iPhone(3G或3GS),或使用iPhone OS3.0或更高版本的iPod设备(二代或更新版本)。
创建一个项目
使用Xcode,创建一个新的基于视图的应用程序项目,取名为Bluetooth。访问蓝牙的各种API位于GameKit框架中,因此,你需要将这个框架添加到刚刚创建的项目中,在Xcode的框架组上点右键,选择“添加”*“现有框架”,选择GameKit框架,如图1所示。

图 1 添加GameKit框架
在BluetoothViewController.h文件中,声明下面的对象,outlet和行为:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1 #import
2
3 #import
4
5 @interface BluetoothViewController :UIViewController {
6
7 GKSession
* currentSession;
8
9 IBOutlet UITextField
* txtMessage;
10
11 IBOutlet UIButton
* connect;
12
13 IBOutlet UIButton
* disconnect;
14
15 }
16
17 @
property (nonatomic, retain) GKSession
* currentSession;
18
19 @
property (nonatomic, retain) UITextField*
txtMessage;
20
21 @
property (nonatomic, retain) UIButton
* connect;
22
23 @
property (nonatomic, retain) UIButton
* disconnect;
24
25
-(IBAction) btnSend:(id)sender;
26
27 -
(IBAction) btnConnect:(id) sender;
28
29 -
(IBAction) btnDisconnect:(id)sender;
30
31 @
end
32
33
GKSession对象用于表现两个蓝牙设备之间连接的一个会话,你也可以使用它在两个设备之间发送和接收数据。
在BluetoothViewController.m文件中,添加下面的代码:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1 #import
" BluetoothViewController.h
"
2
3 #import
4
5 @implementationBluetoothViewController
6
7 @synthesize currentSession;
8
9 @synthesize txtMessage;
10
11 @synthesize connect;
12
13 @synthesize disconnect;
14
15
双击BluetoothViewController.xib在InterfaceBuilder中编辑它,在视图窗口中添加以下视图,如图2所示。
文本区域(Text Field)
圆形按钮(Round Rect Button)

图 2在视图窗口中填充文本区域和圆形按钮视图
执行以下行为:
按住CTRL键,在文件所有者项目上点击,将其拖放到文本区域视图上,选择txtMessage;
按住CTRL键,在文件所有者项目上点击,将其拖放到连接按钮上,选择connect;
按住CTRL键,在文件所有者项目上点击,将其拖放到断开连接按钮上,选择disconnect;
按住CTRL键,在发送按钮上点击,将其拖放到文件所有者项目上,选择btnSend;
按住CTRL键,在连接按钮上点击,将其拖放到文件所有者项目上,选择btnConnect;
按住CTRL键,在断开连接按钮上点击,将其拖放到文件所有者项目上,选择btnDisconnect;
在文件所有者项目上点击右键,验证所有连接是否正常,如图3所示。

图 3 验证所有连接是否正常
返回Xcode,在BluetoothViewController.m文件中,添加以下代码:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1
-(void)viewDidLoad {
2
3 [connectsetHidden:NO];
4
5 [disconnect setHidden:YES];
6
7 [superviewDidLoad];
8
9 }
10
11
-(void)dealloc {
12
13 [txtMessage release];
14
15 [currentSession release];
16
17 [superdealloc];
18
19 }
20
21
搜索对等设备
现在所有准备工作已经就绪,接下来介绍一下访问其它蓝牙设备的API。
在BluetoothViewController.h文件中,声明一个GKPeerPickerController对象:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1 #import
" BluetoothViewController.h
"
2
3 #import
4
5 @implementationBluetoothViewController
6
7 @synthesize currentSession;
8
9 @synthesize txtMessage;
10
11 @synthesize connect;
12
13 @synthesize disconnect;
14
15 GKPeerPickerController
* picker;
16
17
GKPeerPickerController类提供了一个标准的UI让你的应用程序发现并连接到其它蓝牙设备,连接方法并不难,首先实现一个btnConnect:类:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1
-(IBAction) btnConnect:(id) sender{
2
3 picker
= [[GKPeerPickerController alloc]init];
4
5 picker.delegate
= self;
6
7 picker.connectionTypesMask
= GKPeerPickerConnectionTy
8
9 [connectsetHidden:YES];
10
11 [disconnect setHidden:NO];
12
13 [pickershow];
14
15 }
16
17
connectionTypesMask属性指出用户可以选择的连接类型,包括两种类型:GKPeerPickerConnectionTy
检测到远程蓝牙设备,用户选择并连接到其中一个蓝牙设备时,调用peerPickerController:didConnectPeer:toSession:方法,这个方法的实现如下:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1 -
(void)peerPickerController:(GKPeerPickerController*
)picker
2
3 didConnectPeer:(NSString
* )peerID
4
5 toSession:(GKSession
* ) session{
6
7 self.currentSession
= session;
8
9 session.delegate
= self;
10
11 [session setDataReceiveHandler:selfwithContext:nil];
12
13 picker.delegate
= nil;
14
15 [picker dismiss];
16
17 [picker autorelease];
18
19 }
20
21
当用户已经连接到对等蓝牙设备后,可以将GKSession对象保存到currentSession属性中,这样你可以使用GKSession对象与远程设备通信。
如果用户取消了蓝牙选择器,调用peerPickerControllerDidC
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1
-(void)peerPickerControllerDidC
2
3 {
4
5 picker.delegate
= nil;
6
7 [picker autorelease];
8
9 [connect setHidden:NO];
10
11 [disconnect setHidden:YES];
12
13 }
14
15
如果要从一个设备断开连接,使用来自GKSession对象的disconnectFromAllPeers方法,btnDisconnect:方法的实现如下:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1
-(IBAction) btnDisconnect:(id) sender{
2
3 [self.currentSessiondisconnectFromAllPeers];
4
5 [self.currentSession release];
6
7 currentSession
= nil;
8
9 [connect setHidden:NO];
10
11 [disconnect setHidden:YES];
12
13 }
14
15
连接设备或断开连接时,调用session:peer:didChangeState:方法,其实现如下:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1 -
(void)session:(GKSession *
)session
2
3 peer:(NSString
* )peerID
4
5 didChangeState:(GKPeerConnectionState)state{
6
7 switch(state)
8
9 {
10
11
case GKPeerStateConnected:
12
13 NSLog(@
" connected
" );
14
15 break;
16
17
case GKPeerStateDisconnected:
18
19 NSLog(@
" disconnected
" );
20
21 [self.currentSession release];
22
23 currentSession
= nil;
24
25 [connect setHidden:NO];
26
27 [disconnect setHidden:YES];
28
29 break;
30
31 }
32
33 }
34
35
处理这个事件你将知道连接是什么时候建立的,或断开是什么时候发生的。例如,当建立一个连接时,你可能想要立即向对方发送数据。
发送数据
为了向连接的蓝牙设备发送数据,需要使用到GKSession对象的sendDataToAllPeers:方法,你发送的数据是通过NSData对象传输的,因此你可以自定义你的应用程序协议和发送的数据类型(如二进制数据),mySendDataToPeers:方法的定义如下:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1
-(void)mySendDataToPeers:(NSData
* )data
2
3 {
4
5
if(currentSession)
6
7 [self.currentSessionsendDataToAllPeers:data
8
9 withDataMode:GKSendDataReliable
10
11 error
:nil];
12
13 }
14
15 再定义btnSend:方法,以便用户输入的数据能够发送到远程设备:
16
17 -
(IBAction) btnSend:(id) sender
18
19 {
20
21
//--- convert an NSString
object to
NSData ---
22
23 NSData
* data;
24
25 NSString
* str=
[NSStringstringWithString:txtMessage.text];
26
27 data
= [strdataUsingEncoding: NSASCIIStringEncoding];
28
29 [selfmySendDataToPeers:data];
30
31 }
32
33
接收数据
当设备接收到数据时,调用receiveData:fromPeer:inSession:context:方法,其实现如下:
Code highlighting produced by Actipro CodeHighlighter(freeware)
http://www.CodeHighlighter.com/
1 -
(void)receiveData:(NSData *)data
2
3 fromPeer:(NSString
* )peer
4
5 inSession:(GKSession
* )session
6
7 context:(void
* )context{
8
9 //---
convert the NSData
to NSString
---
10
11 NSString
* str;
12
13 str
= [[NSStringalloc] initWithData:dataencoding:NSASCIIStringEncoding];
14
15 UIAlertView
* alert
= [[UIAlertView alloc] initWithTitle:@"
Data received "
16
17 message:str
18
19 delegate:self
20
21 cancelButtonTitle:@
" OK"
22
23 otherButtonTitles:nil];
24
25 [alertshow];
26
27 [alertrelease];
28
29 }
30
31
这里接收到的数据是NSData格式,为了使用UIAlertView类显示它,你需要将其转换为NSString对象。
测试应用程序
就是这么简单!现在可以开始测试了,在Xcode中按下Command-R,将程序部署到iPhone/iPod上,本文假设你有两部iPhone或两部iPod,为了运行刚刚创建的程序,这两台设备上都需要运行iPhoneOS 3.0。
部署好程序后,在两台设备上启动好程序,在任一设备上点击连接按钮,GKPeerPickerController将会显示标准的UI发现其它设备,如图4所示。

图 4GKPeerPickerController查找其它设备
等待一会儿后,两边的程序应该都能够发现对方,如图5所示,当你在发现的设备名称上轻轻点击,程序就会开始连接。

图 5 显示发现的设备名称
注意:如果你在iPhone模拟器上测试这个程序,应该会检测到两个设备,但却无法连接到任何设备。
当其它设备试图连接到你的设备时,你将会看到如图6所示的弹出提示,点击“接受”允许其连接,点击“拒绝”拒绝其连接。

图 6 其它设备试图连接到你时的提示
如果成功与你建立了连接,你就可以输入一些文本信息发给对方了,从其它设备接收到数据将会以一个警告视图显示,如图7所示。

图 7 接收到其它设备发来的数据
本文详细介绍如何利用iOS3.0的GameKit框架实现蓝牙通信,包括创建项目、添加框架、构建基本应用流程及测试方法,旨在帮助开发者轻松实现iPhone与iPod之间的数据交换。
3307

被折叠的 条评论
为什么被折叠?



