我是靠谱客的博主 舒适黑夜,最近开发中收集的这篇文章主要介绍iOS之蓝牙(Bluetooth),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

iOS中蓝牙的实现方案

1.GameKit.framework (用法简单)
只能用于iOS设备之间的连接,多用于游戏,从iOS7被弃用。
(1)GameKit框架简介
使用GameKit框架,可以在游戏中增加对等连接,又称对端连接或点对点连接,Peer To Peer。
使用GameKit框架中的对等网络连接API,可以在游戏玩家之间建立一个对等网络,并在游戏/应用实例之间交换数据。
GameKit框架可以使用蓝牙在玩家之间创建网络,玩家甚至不需要连接到互联网,就可以彼此对战
(2)通过蓝牙实现对等网络连接
为玩家双方呈现一个GKPeerPickerController,提供了一个标准的用户界面连接两台设备
ViewControoler遵循GKPeerPickerControllerDelegate协议,处理来自GKPeerPickerController(对端选择器)的信息
建立连接后,使用GKSession类可以向对端设备发送数据
在receiveData:fromPeer:inSession:context代理方法中编写代码来处理接收到的数据
(3)---1 蓝牙对等网络联系--发送图片
演练目标:通过蓝牙彼此发送照片
演练步骤:
  1.  基于照片选择项目进行扩展,仅从照片库选择照片
  2. 添加GameKit框架
  3. 创建对等连接
    3.1 实例化对端选择器
    3.2 设置代理,并遵循协议
    3.3 显示对端选择器
 4. 连接建立代理方法
    peerPickerController:didConnectPeer:toSession:
    4.1记录对端连接会话
    4.2 设置数据接收处理
    4.3 关闭对端选择器
(3)---2开发步骤
   1.显示可以连接的蓝牙设备列表

//  ViewController.m

#import "ViewController.h"
#import <GameKit/GameKit.h>
 
@interfaceViewController()<UINavigationControllerDelegate,UIImagePickerControllerDelegate,GKPeerPickerControllerDelegate>
 
// 显示照片的View
@property(weak, nonatomic)IBOutletUIImageView*imageView;
 
// 保留会话用户发送数据
@property(nonatomic,strong)GKSession*session;
 
@end

//实例化查找设备的控制器对象
GKPeerPickerController*ppc =[[GKPeerPickerController alloc] init];
//遵循代理
ppc.delegate= self;
//推出蓝牙设备列表
[ppc show];
   2.在代理方法中监控蓝牙的连接(设备连接成功后)
#prama mark---实现蓝牙的监控代理方法

/**

 *  设备连接成功后会调用该方法

 *

 *  @param peerID  设备节点ID

 *  @param session 会话(使用该会话对象来相互传递数据)

 */

-(void)peerPickerController:(GKPeerPickerController*)picker didConnectPeer:(NSString*)peerID toSession:(GKSession*)session {
NSLog(@"连接到设备:%@", peerID);
// 设置接收到蓝牙数据后的监听器
[session setDataReceiveHandler:self withContext:nil];
// 保存session(保留会话)
self.session = session;
//关闭蓝牙设备显示界面
[picker dismiss];
}
   3.处理接收到的蓝牙数据
#pragma mark -接受数据
/**
* 当接受收到数据的时候会调用该方法
*
* @param data 接受到的数据
* @param peer 从哪一个节点接受到的数据
* @param session 会话
*/
-(void) receiveData:(NSData*)data fromPeer:(NSString*)peer inSession:(GKSession*)session context:(void*)context {
// 将NSData转化成UIImage对象
UIImage*receiveImage =[UIImage imageWithData:data];
// 设置到imageView上
self.imageView.image = receiveImage;
// 将图片保存到相册当中
UIImageWriteToSavedPhotosAlbum(receiveImage, nil, nil, nil);
}

   4.利用GKSession给其他设备发送数据
#pragma mark -选择照片
-(IBAction)pickImage {
// 1.判断照片源是否可用
/*
UIImagePickerControllerSourceTypePhotoLibrary 图片库
UIImagePickerControllerSourceTypeCamera 相机
UIImagePickerControllerSourceTypeSavedPhotosAlbum 相册
*/
if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])return;
// 2.创建照片选择控制器
UIImagePickerController*ipc =[[UIImagePickerController alloc] init];
// 3.设置照片源
ipc.sourceType =UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// 4.设置代理
ipc.delegate= self;
// 5.弹出控制器
[self presentViewController:ipc animated:YES completion:nil];
}
 
/**
* 当选中某一个照片的时候会调用该方法
*
* @param info 存放着照片信息
*/
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
// 1.取出照片
self.imageView.image = info[UIImagePickerControllerOriginalImage];
// 2.退出控制器
[picker dismissViewControllerAnimated:YES completion:nil];
}

//给指定的连接设备发送数据
-(BOOL)sendData:(NSData*) data toPeers:(NSArray*)peers withDataMode:(GKSendDataMode)mode error:(NSError**)error;
//给所有连接的设备发送数据
-(BOOL)sendDataToAllPeers:(NSData*) data withDataMode:(GKSendDataMode)mode error:(NSError**)error;
#pragma mark -发送照片
-(IBAction)sendImage {
// 判断image如果为空直接返回
if(!self.imageView.image)return;
// 将UIImage转化成NSData
// UIImagePNGRepresentation(UIImage *image) 压缩图片
NSData*imageData =UIImageJPEGRepresentation(self.imageView.image,0.5);
 //发送照片
// self.session sendData:(NSData *) toPeers:(NSArray *) withDataMode:(GKSendDataMode) error:(NSError *__autoreleasing *)
/*
GKSendDataReliable, 可靠传输(数据一定会被传达,如果中间网络发生状况,重新连接,再次传输)-->TCP
GKSendDataUnreliable, 不可靠传输(数据只会发送一次,没有收到就算了)-->UDP
*/
[self.session sendDataToAllPeers:imageData withDataMode:GKSendDataReliable error:nil];
}

 (4)GameKit的蓝牙开发注意事项
       只能用户iOS设备之间的连接。
       只能用于同一个应用程序之间的连接。
       最好不要发送较大的数据,容易是设备卡死。

2.MultipeerConnectivity.framework
只能用于iOS设备之间的连接,从iOS7开始引入,主要用于文件共享(仅限于沙盒的文件)。

3.ExternalAccessory.framework
可用于第三方蓝牙与设备交互,但是蓝牙设备必须经过苹果MFI认证(国内较少)。

4.CoreBluetooth.framework(时下热门)
可用于第三方蓝牙设备交互,必须支持蓝牙4.0.
硬件至少iOS4s,系统最低iOS6.0.
蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy)。
Core Bluetooth测试比较麻烦,正常情况下,得至少有2台真实的蓝牙4.0设备
如何让iOS模拟器也能测试蓝牙4.0程序?
买一个CSR蓝牙4.0 USB适配器,插在Mac上
在终端输入sudo nvram bluetoothHostControllerSwitchBehavior="never"
重启Mac
用Xcode 4.6调试代码,将程序跑在iOS 6.1的模拟器上
(苹果把iOS 7.0模拟器对BLE的支持移除掉了)
Core Bluetooth的使用场景
运动手环、智能家居、嵌入式设备等等(金融刷卡器、心电测量器)
(1)Core Bluetooth的核心结构图


(2)Core Bluetooth的基本常识
每个蓝牙4.0设备都是通过服务(Service)和特征(Characteristic)来展示自己的
一个设备必然包含一个或多个服务,每个服务下面又包含若干个特征

特征是与外界交互的最小单位
比如说,一台蓝牙4.0设备,用特征A来描述自己的出厂信息,用特征B来收发数据

服务和特征都是用UUID来唯一标识的,通过UUID就能区别不同的服务和特征

设备里面各个服务(service)和特征(characteristic)的功能,均由蓝牙设备硬件厂商提供,比如哪些是用来交互(读写),哪些可获取模块信息(只读)等
(3)Core Bluetooth的开发步骤
建立中心设备

扫描外设(Discover Peripheral)

连接外设(Connect Peripheral)

扫描外设中的服务和特征(Discover Services And Characteristics)

利用特征与外设做数据交互(Explore And Interact)

断开连接(Disconnect)
(4)蓝牙的现状
绝大多数智能手机支持蓝牙 4.0(BLE)

蓝牙芯片发展迅速,在性能和效率方面都有很大提高,且不断变得更小更便宜

iBeacon + 蓝牙,前景一片光明
应用之一:室内导航
Estimote公司为iBeacon提供基站
3个iBeacon基站的预购价格为99美元(约合人民币610元)
Estimote公司推出的iBeacon基站的最远传输距离为50m,但是他们推荐在10m范围内的使用效果最好

一块纽扣电池就能为一个iBeacon基站提供长达 2 年的使用寿命,而且是在设备不断对外发射信号的情况下

 
// ViewController.m
// 07-蓝牙(CoreBlooth)
//
//
 
#import "ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
 
@interfaceViewController()<CBCentralManagerDelegate,CBPeripheralDelegate>
 
// 中央管理者
@property(nonatomic,strong)CBCentralManager*mgr;
 
@property(nonatomic,strong)NSMutableArray*peripherals;
 
@end
 
@implementationViewController
 
-(void)viewDidLoad {
[super viewDidLoad];
// 1.扫描所有的外围设备
// serviceUUIDs:可以将你想要扫描的服务的外围设备传入(传nil,扫描所有的外围设备)
[self.mgr scanForPeripheralsWithServices:nil options:nil];
}
 
#pragma mark -CBCentralManager的代理方法
/**
* 状态发生改变的时候会执行该方法(蓝牙4.0没有打开变成打开状态就会调用该方法)
*/
-(void)centralManagerDidUpdateState:(CBCentralManager*)central
{
}
 
/**
* 当发现外围设备的时候会调用该方法
*
* @param peripheral 发现的外围设备
* @param advertisementData 外围设备发出信号
* @param RSSI 信号强度
*/
-(void)centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI
{
if(![self.peripherals containsObject:peripheral]){
[self.peripherals addObject:peripheral];
}
}
 
/**
* 连接上外围设备的时候会调用该方法
*
* @param peripheral 连接上的外围设备
*/
-(void)centralManager:(CBCentralManager*)central didConnectPeripheral:(CBPeripheral*)peripheral
{
// 1.扫描所有的服务
// serviceUUIDs:指定要扫描该外围设备的哪些服务(传nil,扫描所有的服务)
[peripheral discoverServices:nil];
// 2.设置代理
peripheral.delegate= self;
}
 
#pragma mark -CBPeripheral的代理方法
/**
* 发现外围设备的服务会来到该方法(扫描到服务之后直接添加peripheral的services)
*/
-(void)peripheral:(CBPeripheral*)peripheral didDiscoverServices:(NSError*)error
{
for(CBService*serivce in peripheral.services){
if([serivce.UUID.UUIDString isEqualToString:@"123"]){
// characteristicUUIDs : 可以指定想要扫描的特征(传nil,扫描所有的特征)
[peripheral discoverCharacteristics:nil forService:serivce];
}
}
}
 
/**
* 当扫描到某一个服务的特征的时候会调用该方法
*
* @param service 在哪一个服务里面的特征
*/
-(void)peripheral:(CBPeripheral*)peripheral didDiscoverCharacteristicsForService:(CBService*)service error:(NSError*)error
{
for(CBCharacteristic*characteristic in service.characteristics){
if([characteristic.UUID.UUIDString isEqualToString:@"456"]){
// 拿到特征,和外围设备进行交互
}
}
}
 
#pragma mark -连接设备
-(void)connect:(CBPeripheral*)peripheral
{
// 连接外围设备
[self.mgr connectPeripheral:peripheral options:nil];
}
 
#pragma mark -懒加载代码
-(CBCentralManager*)mgr
{
if(_mgr == nil){
_mgr =[[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
return _mgr;
}
 
-(NSMutableArray*)peripherals
{
if(_peripherals == nil){
_peripherals =[NSMutableArray array];
}
return _peripherals;
}
 
@end


最后

以上就是舒适黑夜为你收集整理的iOS之蓝牙(Bluetooth)的全部内容,希望文章能够帮你解决iOS之蓝牙(Bluetooth)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部