iOS蓝牙
Posted 顺手给我new一个对象
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS蓝牙相关的知识,希望对你有一定的参考价值。
在ios中进行蓝牙传输应用开发常用的框架有如下几种:
GameKit.framework:iOS7之前的蓝牙通讯框架,从iOS7开始过期,但是目前多数应用还是基于此框架。
MultipeerConnectivity.framework:iOS7开始引入的新的蓝牙通讯开发框架,用于取代GameKit。
CoreBluetooth.framework:功能强大的蓝牙开发框架,要求设备必须支持蓝牙4.0。
前两个框架使用起来比较简单,但是缺点也比较明显:仅仅支持iOS设备,传输内容仅限于沙盒或者照片库中用户选择的文件,并且第一个框架只能在同一个应用之间进行传输(一个iOS设备安装应用A,另一个iOS设备上安装应用B是无法传输的)。当然CoreBluetooth就摆脱了这些束缚,它不再局限于iOS设备之间进行传输,你可以通过iOS设备向android、Windows Phone以及其他安装有蓝牙4.0芯片的智能设备传输,因此也是目前智能家居、无线支付等热门智能设备所推崇的技术。
GameKit
其实从名称来看这个框架并不是专门为了支持蓝牙传输而设计的,它是为游戏设计的。而很多游戏中会用到基于蓝牙的点对点信息传输,因此这个框架中集成了蓝牙传输模块。前面也说了这个框架本身有很多限制,但是在iOS7之前的很多蓝牙传输都是基于此框架的,所以有必要对它进行了解。GameKit中的蓝牙使用设计很简单,并没有给开发者留有太多的复杂接口,而多数连接细节开发者是不需要关注的。GameKit中提供了两个关键类来操作蓝牙连接:
GKPeerPickerController:蓝牙查找、连接用的视图控制器,通常情况下应用程序A打开后会调用此控制器的show方法来展示一个蓝牙查找的视图,一旦发现了另一个同样在查找蓝牙连接的客户客户端B就会出现在视图列表中,此时如果用户点击连接B,B客户端就会询问用户是否允许A连接B,如果允许后A和B之间建立一个蓝牙连接。
GKSession:连接会话,主要用于发送和接受传输数据。一旦A和B建立连接GKPeerPickerController的代理方法会将A、B两者建立的会话(GKSession)对象传递给开发人员,开发人员拿到此对象可以发送和接收数据。
其实理解了上面两个类之后,使用起来就比较简单了,下面就以一个图片发送程序来演示GameKit中蓝牙的使用。此程序一个客户端运行在模拟器上作为客户端A,另一个运行在iPhone真机上作为客户端B(注意A、B必须运行同一个程序,GameKit蓝牙开发是不支持两个不同的应用传输数据的)。两个程序运行之后均调用GKPeerPickerController来发现周围蓝牙设备,一旦A发现了B之后就开始连接B,然后iOS会询问用户是否接受连接,一旦接受之后就会调用GKPeerPickerController的-(void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session代理方法,在此方法中可以获得连接的设备id(peerID)和连接会话(session);此时可以设置会话的数据接收句柄(相当于一个代理)并保存会话以便发送数据时使用;一旦一端(假设是A)调用会话的sendDataToAllPeers: withDataMode: error:方法发送数据,此时另一端(假设是B)就会调用句柄的- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context方法,在此方法可以获得发送数据并处理。下面是程序代码:
详细代码:
1 #import "ViewController.h" 2 #import <GameKit/GameKit.h> 3 4 @interface ViewController ()<GKPeerPickerControllerDelegate,UIImagePickerControllerDelegate,UINavigationBarDelegate> 5 6 @property (weak, nonatomic) IBOutlet UIImageView *imageView; 7 8 @property (nonatomic,strong) GKSession * session;//蓝牙连接会话 9 10 @end 11 12 @implementation ViewController 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 17 GKPeerPickerController * pearPickerController = [[GKPeerPickerController alloc] init]; 18 pearPickerController.delegate = self; 19 20 [pearPickerController show]; 21 } 22 23 24 #pragma mark - UI事件 25 //选择相片 26 - (IBAction)selectClick:(id)sender { 27 28 UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init]; 29 imagePickerController.delegate = self; 30 31 [self presentViewController:imagePickerController animated:YES completion:nil]; 32 } 33 34 //发送相片 35 - (IBAction)sendClick:(id)sender { 36 37 NSData * data = UIImagePNGRepresentation(self.imageView.image); 38 NSError * error = nil; 39 [self.session sendDataToAllPeers:data withDataMode:GKSendDataReliable error:&error]; 40 41 if (error) { 42 NSLog(@"发送图片过程中发生错误,错误信息:%@",error.localizedDescription); 43 } 44 } 45 46 #pragma mark - GKPeerPickerController delegate 47 /** 48 *连接到某个设备 49 * 50 *@param picker 蓝牙点对点连接控制器 51 *@param peerID 连接设备蓝牙传输ID 52 *@param session 连接会话 53 */ 54 - (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session{ 55 56 NSLog(@"已连接客户端设备:%@.",peerID); 57 58 //设置数据接收处理句炳,相当于代理,一旦数据接收完成调用它的-receiveData:fromPeer:inSession:context:方法处理数据 59 [self.session setDataReceiveHandler:self withContext:nil]; 60 61 [picker dismiss];//一旦连接成功关闭窗口 62 } 63 64 #pragma mark - 蓝牙数据接收发放 65 - (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context{ 66 67 UIImage *image=[UIImage imageWithData:data]; 68 69 self.imageView.image=image; 70 71 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); 72 73 NSLog(@"数据发送成功!"); 74 } 75 76 #pragma mark - UIImagePickerController delegate 77 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{ 78 79 self.imageView.image = [info objectForKey:UIImagePickerControllerOriginalImage]; 80 81 [self dismissViewControllerAnimated:YES completion:nil]; 82 } 83 84 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ 85 [self dismissViewControllerAnimated:YES completion:nil]; 86 }
效果图
MultipeerConnectivity
前面已经说了GameKit相关的蓝牙操作类从iOS7已经全部过期,苹果官方推荐使用MultipeerConnectivity代替。但是应该了解,MultipeerConnectivity.framework并不仅仅支持蓝牙连接,准确的说它是一种支持Wi-Fi网络、P2P Wi-Fi以及蓝牙个人局域网的通信框架,它屏蔽了具体的连接技术,让开发人员有统一的接口编程方法。通过MultipeerConnectivity连接的节点之间可以安全的传递信息、流或者其他文件资源而不必通过网络服务。此外使用MultipeerConnectivity进行近场通信也不再局限于同一个应用之间传输,而是可以在不同的应用之间进行数据传输(当然如果有必要的话你仍然可以选择在一个应用程序之间传输)。
要了解MultipeerConnectivity的使用必须要清楚一个概念:广播(Advertisting)和发现(Disconvering),这很类似于一种Client-Server模式。假设有两台设备A、B,B作为广播去发送自身服务,A作为发现的客户端。一旦A发现了B就试图建立连接,经过B同意二者建立连接就可以相互发送数据。在使用GameKit框架时,A和B既作为广播又作为发现,当然这种情况在MultipeerConnectivity中也很常见。
明天再更......
以上是关于iOS蓝牙的主要内容,如果未能解决你的问题,请参考以下文章