蓝牙在GameKit框架中实现,可以实现文件传递和游戏通信等,蓝牙的缺点是不能得到文件传输的进度,因此不宜传输大文件。
使用蓝牙的一般步骤如下:
①创建蓝牙设备拾取器,类似于图片拾取器,通过代理方法获取拾取到的设备,调用show方法来显示拾取器。
GKPeerPickerController *peerC = [[GKPeerPickerController alloc] init]; peerC.delegate = self; [peerC show];要遵循UINavigationControllerDelegate,GKPeerPickerControllerDelegate协议。
②通过代理方法获取拾取到的设备,存储这个会话,然后dismiss拾取器视图,记得要存储会话,注意为了接收数据,应该调用会话的setDataReceiveHandler::方法:
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session{ _session = session; // 设置谁来处理数据 [session setDataReceiveHandler:self withContext:NULL]; [picker dismiss]; }
接收数据的方法既不是代理,也不是通知,因此必须和帮助文档中写的一样,方法如下:
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context{ // data就是接收到的二进制数据 }③要发送蓝牙数据,通过session的sendDataToAllPeers:::实现,其中withDataMode用于选择是可靠传输还是不可靠传输,类似TCP和UDP,下面的代码演示了发送一张图片的过程。
- (IBAction)send:(id)sender { NSData *data = UIImagePNGRepresentation(_imageView.image); NSError *err = nil; // 可靠连接可以保证一定送到,不可靠只负责发送 [_session sendDataToAllPeers:data withDataMode:GKSendDataUnreliable error:&err]; if (err) { NSLog(@"%@",err); } }
下面的例子演示了一个发送图片的例程,有一张图片imageView,三个按钮,分别是连接(connect方法)、选择(choosePic)、发送(send),点击选择从照片图库中选择一张图片,点击连接建立会话,点击发送将图片通过会话发送出去。
// // ViewController.m // 蓝牙基本使用 // // Created by 11 on 7/27/15. // Copyright (c) 2015 soulghost. All rights reserved. // #import "ViewController.h" #import <GameKit/GameKit.h> @interface ViewController () <UIImagePickerControllerDelegate,UINavigationControllerDelegate,GKPeerPickerControllerDelegate> @property (weak, nonatomic) IBOutlet UIImageView *imageView; @property (weak, nonatomic) GKSession *session; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)connect:(id)sender { // 创建蓝牙设备选择器View,设置代理并且显示、 GKPeerPickerController *peerC = [[GKPeerPickerController alloc] init]; peerC.delegate = self; [peerC show]; } - (IBAction)choosePic:(id)sender { if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]){ NSLog(@"图库不可用"); return; } UIImagePickerController *imgPickerC = [[UIImagePickerController alloc] init]; imgPickerC.delegate = self; imgPickerC.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; [self presentViewController:imgPickerC animated:YES completion:nil]; } - (IBAction)send:(id)sender { NSData *data = UIImagePNGRepresentation(_imageView.image); NSError *err = nil; // 可靠连接可以保证一定送到,不可靠只负责发送 [_session sendDataToAllPeers:data withDataMode:GKSendDataUnreliable error:&err]; if (err) { NSLog(@"%@",err); } } - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ //NSLog(@"%@",info); UIImage *image = info[UIImagePickerControllerOriginalImage]; _imageView.image = image; [self imagePickerControllerDidCancel:picker]; } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ [picker dismissViewControllerAnimated:YES completion:nil]; } - (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session{ _session = session; // 设置谁来处理数据 [session setDataReceiveHandler:self withContext:NULL]; [picker dismiss]; } // 通过看setDataReceiveHandler的帮助得到,只要实现了即可 // 接收到其他设备传来的数据时调用 - (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context{ UIImage *image = [UIImage imageWithData:data]; _imageView.image = image; } @end