蓝牙

作者: 闲得一B | 来源:发表于2016-06-26 22:22 被阅读139次

    iOS中蓝牙的实现方案
    iOS中提供了4个框架用于实现蓝牙连接
    GameKit.framework(用法简单)
    只能用于iOS设备之间的连接,多用于游戏(比如五子棋对战),从iOS7开始过期

    MultipeerConnectivity.framework
    只能用于iOS设备之间的连接,从iOS7开始引入

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

    CoreBluetooth.framework(时下热门)
    可用于第三方蓝牙设备交互,必须要支持蓝牙4.0
    硬件至少是4s,系统至少是iOS6
    蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy)
    目前应用比较多的案例:运动手坏、嵌入式设备、智能家居

    GameKit框架简介

    使用GameKit框架,可以在游戏中增加对等连接,又称对端连接或点对点连接,Peer To Peer。
    使用GameKit框架中的对等网络连接API,可以在游戏玩家之间建立一个对等网络,并在游戏/应用实例之间交换数据。
    GameKit框架可以使用蓝牙在玩家之间创建网络,玩家甚至不需要连接到互联网,就可以彼此对战。

    通过蓝牙实现对等网络连接
    为玩家双方呈现一个GKPeerPickerController,提供了一个标准的用户界面连接两台设备
    ViewControoler遵循GKPeerPickerControllerDelegate协议,处理来自GKPeerPickerController(对端选择器)的信息
    建立连接后,使用GKSession类可以向对端设备发送数据
    在receiveData:fromPeer:inSession:context代理方法中编写代码来处理接收到的数据

    蓝牙对等网络演练——发送照片(1)

    演练目标:通过蓝牙彼此发送照片
    演练步骤:

    1. 基于照片选择项目进行扩展,仅从照片库选择照片
    2. 添加GameKit框架
    3. 创建对等连接
      3.1 实例化对端选择器
      3.2 设置代理,并遵循协议
      3.3 显示对端选择器
    4. 连接建立代理方法
      peerPickerController:didConnectPeer:toSession:
      4.1记录对端连接会话
      4.2 设置数据接收处理
      4.3 关闭对端选择器

    GameKit的蓝牙开发步骤
    显示可以连接的蓝牙设备列表
    GKPeerPickerController *ppc = [[GKPeerPickerController alloc] init];
    ppc.delegate = self;
    [ppc show];

    在代理方法中监控蓝牙的连接

    • (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session {
      NSLog(@"连接到设备:%@", peerID);
      // 关闭蓝牙设备显示界面
      [picker dismiss];
      // 设置接收到蓝牙数据后的监听器
      [session setDataReceiveHandler:self withContext:nil];
      // 保存session
      self.session = session;
      }

    GameKit的蓝牙开发步骤

    处理接收到的蓝牙数据

    • (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {

    }

    利用GKSession给其他设备发送数据
    给指定的连接设备发送数据

    • (BOOL)sendData:(NSData *) data toPeers:(NSArray *)peers withDataMode:(GKSendDataMode)mode error:(NSError **)error;
      给所有连接的设备发送数据
    • (BOOL)sendDataToAllPeers:(NSData *) data withDataMode:(GKSendDataMode)mode error:(NSError **)error;

    GameKit的蓝牙开发注意
    只能用于iOS设备之间的连接

    只能用于同一个应用程序之间的连接

    最好别利用蓝牙发送比较大的数据

    CoreBluetooth
    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的使用场景
    运动手环、智能家居、嵌入式设备等等(金融刷卡器、心电测量器)

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

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

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

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

    CoreBluetooth的开发步骤

    建立中心设备

    扫描外设(Discover Peripheral)

    连接外设(Connect Peripheral)

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

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

    断开连接(Disconnect)

    蓝牙的现状
    绝大多数智能手机支持蓝牙 4.0(BLE)

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

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

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

    
    #import "ViewController.h"
    #import <GameKit/GameKit.h>
    
    @interface ViewController () <UINavigationControllerDelegate, UIImagePickerControllerDelegate, GKPeerPickerControllerDelegate>
    
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    
    /** 会话 */
    @property (nonatomic, strong) GKSession *session;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    }
    
    #pragma mark - 选择照片
    - (IBAction)pickImage {
        // 1.判断照片源是否可用
        if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
        
        // 2.创建照片选择控制器
        UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
        
        // 3.设置代理
        ipc.delegate = self;
        
        // 4.设置照片源
        ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        
        // 5.弹出控制器
        [self presentViewController:ipc animated:YES completion:nil];
    }
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
        // 1.获取照片,并且设置到imageView上
        self.imageView.image = info[UIImagePickerControllerOriginalImage];
        
        // 2.退出控制器
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
    
    #pragma mark - 连接设备
    - (IBAction)connectDevice {
        // 1.创建连接设备的控制器
        GKPeerPickerController *ppc = [[GKPeerPickerController alloc] init];
        
        // 2.设置代理(在代理中可以监听是否连接成功)
        ppc.delegate = self;
        
        // 3.弹出控制器
        [ppc show];
    }
    
    // 当建立连接成功时,会调用该方法
    // peerID : 节点ID,每一个蓝牙设备就是一个节点,都有一个对应的节点ID
    // session : 会话,建立连接之后相当于两个蓝牙之间建立一个会话,之后可以通过会话相互之间传输数据
    - (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
    {
        // 保留会话
        self.session = session;
        
        // 设置句柄
        [self.session setDataReceiveHandler:self withContext:nil];
        
        // 退出控制器
        [picker dismiss];
    }
    
    #pragma mark - 发送照片
    - (IBAction)sendImage {
        // 1.将图片转成NSData
        NSData *imageData = UIImageJPEGRepresentation(self.imageView.image, 0.4);
        
        // 2.发送照片
        /*
         GKSendDataReliable,  可到达,发送数据保证可以到达.
         GKSendDataUnreliable, 不可达到,数据只会发送一次.
         */
        [self.session sendDataToAllPeers:imageData withDataMode:GKSendDataReliable error:nil];
    }
    
    - (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
    {
        // 1.直接转成Image,并且设置到ImageView
        self.imageView.image = [UIImage imageWithData:data];
        
    }
    
    @end
    
    

    相关文章

      网友评论

          本文标题:蓝牙

          本文链接:https://www.haomeiwen.com/subject/lckzdttx.html