久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

學(xué)習(xí)ios藍牙技術(shù),仿寫lightblue

 wintelsui 2014-11-14

前言

bluetooth

上一次我們研究完iBeacon,,發(fā)現(xiàn)iBeacon是基于藍牙4.0的一個封裝而已,。那么,今天我們來研究ios的藍牙4.0的應(yīng)用,。最出名的app當(dāng)屬lightblue,,我們不妨來仿寫一個lightblue,這樣基本的ios藍牙編程就算入門了,。

基本理論

框架與概念

在ios中使用藍牙技術(shù),,會用到CoreBluetooth框架。

里面對設(shè)備有2個定義:周邊(peripeheral)設(shè)備 與 中央(central)設(shè)備,。發(fā)送藍牙信號的是周邊設(shè)備,,接收藍牙信號的是中央設(shè)備。

可以這樣理解,,周邊設(shè)備是服務(wù)端,,中央設(shè)備是客戶端。中央設(shè)備可以去搜索周邊有哪些服務(wù)端,,可以選擇連接上其中一臺,,進行信息獲取。

支持藍牙4.0的手機,,可以作為周邊設(shè)備,,也可以作為中央設(shè)備,但是不能同時既為周邊設(shè)備又為中央設(shè)備,。

類解讀

中央設(shè)備用 CBCentralManager 這個類管理,。

周邊設(shè)備用 CBPeripheralManager 這個類管理;

周邊設(shè)備里面還有服務(wù)類 CBService,,服務(wù)里面有各種各樣的特性類 CBCharacteristic,。

仿寫lightblue

基本流程

  1. 假設(shè)我們有2臺以上可用設(shè)備。
  2. 其中一臺作為調(diào)試機,,用來搜索其它設(shè)備,,并連接上去。所以,,是中央設(shè)備central,。
  3. 其它設(shè)備設(shè)置為藍牙發(fā)射器,即是周邊設(shè)備peripheral,。
  4. 調(diào)試機先掃描周邊設(shè)備,,用UITableView展示所掃描到的周邊設(shè)備。
  5. 點擊其中一臺設(shè)備,,進行連接connect,。
  6. 連接上后,獲取其中的所有服務(wù)services,。
  7. 對其中每個服務(wù)進行遍歷,,獲取所有的特性Characteristic
  8. 讀取每個特性,,獲取每個特性的值value,。

至此,lightblue基本的仿寫思路就清晰列出來了,。

1. 掃描設(shè)備

先包含頭文件

1
#import <CoreBluetooth/CoreBluetooth.h>

然后添加協(xié)議 CBCentralManagerDelegate

接著定義2個屬性,, CBCentralManager用來管理我們的中央設(shè)備,NSMutableArray用來保存掃描出來的周邊設(shè)備,。

1
2
  @property (nonatomic, strong) CBCentralManager *centralMgr;
  @property (nonatomic, strong) NSMutableArray *arrayBLE;

中央設(shè)備創(chuàng)建很簡單,,第一個參數(shù)代表 CBCentralManager 代理,第二個參數(shù)設(shè)置為nil,,因為Peripheral Manager將Run在主線程中,。如果你想用不同的線程做更加復(fù)雜的事情,你需要創(chuàng)建一個隊列(queue)并將它放在這兒,。

1
2
self.centralMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
self.arrayBLE = [[NSMutableArray alloc] init];

實現(xiàn)centralManagerDidUpdateState,。當(dāng)Central Manager被初始化,我們要檢查它的狀態(tài),,以檢查運行這個App的設(shè)備是不是支持BLE,。

1
2
3
4
5
6
7
8
9
10
11
12
13
  - (void)centralManagerDidUpdateState:(CBCentralManager *)central
  {
      switch (central.state)
      {
          case CBCentralManagerStatePoweredOn:
              [self.centralMgr scanForPeripheralsWithServices:nil options:nil];
              break;
  
          default:
              NSLog(@"Central Manager did change state");
              break;
      }
  }

-scanForPeripheralsWithServices:options:方法是中央設(shè)備開始掃描,可以設(shè)置為特定UUID來指,,來差找一個指定的服務(wù)了,。我們需要掃描周邊所有設(shè)備,第一個參數(shù)設(shè)置為nil,。

當(dāng)發(fā)起掃描之后,,我們需要實現(xiàn) centralManager:didDiscoverPeripheral:advertisementData:RSSI: 通過該回調(diào)來獲取發(fā)現(xiàn)設(shè)備。

這個回調(diào)說明著廣播數(shù)據(jù)和信號質(zhì)量(RSSI-Received Signal Strength Indicator)的周邊設(shè)備被發(fā)現(xiàn),。通過信號質(zhì)量,,可以用判斷周邊設(shè)備離中央設(shè)備的遠近。

1
2
3
4
5
6
7
8
9
  - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
  {
      BLEInfo *discoveredBLEInfo = [[BLEInfo alloc] init];
      discoveredBLEInfo.discoveredPeripheral = peripheral;
      discoveredBLEInfo.rssi = RSSI;
  
      // update tableview
      [self saveBLE:discoveredBLEInfo];
  }

BLEInfo是我新建的一個類,,用來存儲周邊設(shè)備信息的,,具體如下:

1
2
3
4
5
6
  @interface BLEInfo : NSObject
  
  @property (nonatomic, strong) CBPeripheral *discoveredPeripheral;
  @property (nonatomic, strong) NSNumber *rssi;
  
  @end

保存周邊設(shè)備信息,并把它們顯示到UITableView上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  - (BOOL)saveBLE:(BLEInfo *)discoveredBLEInfo
  {
      for (BLEInfo *info in self.arrayBLE)
      {
          if ([info.discoveredPeripheral.identifier.UUIDString isEqualToString:discoveredBLEInfo.discoveredPeripheral.identifier.UUIDString])
          {
              return NO;
          }
      }
  
      [self.arrayBLE addObject:discoveredBLEInfo];
      [self.tableView reloadData];
      return YES;
  }

掃描到的周邊設(shè)備展示如下:

掃描到的周邊設(shè)備

2. 連接設(shè)備

當(dāng)我們點擊其中一個設(shè)備,,嘗試進行連接,。lightblue是點擊后就立馬連接的,,然后在下一個UITableView來展示該周邊設(shè)備的服務(wù)與特性。

而我是進入下一頁UITableView才開始連接,,差別不大,。但是注意的是,一定要把我們之前的self.centralMgr傳遞到下一頁的UITableView來使用,,并且重新設(shè)置delegate,。

用來展示服務(wù)和特性的UITableViewController:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  #import <UIKit/UIKit.h>
  #import <CoreBluetooth/CoreBluetooth.h>
  
  @interface BLEInfoTableViewController : UITableViewController
  <
  CBPeripheralManagerDelegate,
  CBCentralManagerDelegate,
  CBPeripheralDelegate
  >
  
  @property (nonatomic, strong) CBCentralManager *centralMgr;
  @property (nonatomic, strong) CBPeripheral *discoveredPeripheral;
  
  // tableview sections,保存藍牙設(shè)備里面的services字典,,字典第一個為service,,剩下是特性與值
  @property (nonatomic, strong) NSMutableArray *arrayServices;
  
  // 用來記錄有多少特性,當(dāng)全部特性保存完畢,,刷新列表
  @property (atomic, assign) int characteristicNum;
  
  @end

記得把之前的centrlMgr傳過來,,記得要重新設(shè)置delegate:

1
2
3
4
5
6
7
8
9
10
11
12
- (void)viewDidLoad
{
    [super viewDidLoad];

    [_centralMgr setDelegate:self];
    if (_discoveredPeripheral)
    {
        [_centralMgr connectPeripheral:_discoveredPeripheral options:nil];
    }
    _arrayServices = [[NSMutableArray alloc] init];
    _characteristicNum = 0;
}

其中,

[centralMgr connectPeripheral:discoveredPeripheral options:nil];

就是中央設(shè)備向周邊設(shè)備發(fā)起連接,。

我們可以實現(xiàn)下面的函數(shù),,如果連接失敗,就會得到回調(diào):

1
2
3
4
  - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
  {
      NSLog(@"didFailToConnectPeripheral : %@", error.localizedDescription);
  }

我們必須實現(xiàn)didConnectPeripheral,,只要連接成功,,就能回調(diào)到該函數(shù),開始獲取服務(wù),。

1
2
3
4
5
6
7
8
9
  - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
  {

      [self.arrayServices removeAllObjects];

      [_discoveredPeripheral setDelegate:self];

      [_discoveredPeripheral discoverServices:nil];
  }

discoverServices就是查找該周邊設(shè)備的服務(wù),。

3. 獲取服務(wù)

當(dāng)找到了服務(wù)之后,就能進入didDiscoverServices的回調(diào),。我們把全部服務(wù)都保存起來,。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
  {
      if (error)
      {
          NSLog(@"didDiscoverServices : %@", [error localizedDescription]);
  //        [self cleanup];
          return;
      }
  
      for (CBService *s in peripheral.services)
      {
          NSLog(@"Service found with UUID : %@", s.UUID);
          NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithDictionary:@{SECTION_NAME:s.UUID.description}];
          [self.arrayServices addObject:dic];
          [s.peripheral discoverCharacteristics:nil forService:s];
      }
  }

4. 獲取特性

我們通過discoverCharacteristics來獲取每個服務(wù)下的特性,通過下面的回調(diào)來獲取,。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
  {
      if (error)
      {
          NSLog(@"didDiscoverCharacteristicsForService error : %@", [error localizedDescription]);
          return;
      }
  
      for (CBCharacteristic *c in service.characteristics)
      {
          self.characteristicNum++;
          [peripheral readValueForCharacteristic:c];
      }
  }

5. 獲取特性值

readValueForCharacteristic可以讀取特性的值,。

通過下面的回調(diào),就能得到特性值,。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
  {
      self.characteristicNum--;
      if (self.characteristicNum == 0)
      {
          [self.tableView reloadData];
      }
  
      if (error)
      {
          NSLog(@"didUpdateValueForCharacteristic error : %@", error.localizedDescription);
          return;
      }
  
      NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
  
      if ([stringFromData isEqualToString:@"EOM"])
      {
          NSLog(@"the characteristic text is END");
  //        [peripheral setNotifyValue:NO forCharacteristic:characteristic];
  //        [self.centralMgr cancelPeripheralConnection:peripheral];
      }
  
      for (NSMutableDictionary *dic in self.arrayServices)
      {
          NSString *service = [dic valueForKey:SECTION_NAME];
          if ([service isEqual:characteristic.service.UUID.description])
          {
              NSLog(@"characteristic.description : %@", characteristic.UUID.description);
              [dic setValue:characteristic.value forKey:characteristic.UUID.description];
          }
      }
  }

連接到周邊設(shè)備獲得的藍牙信息

其它

本來蘋果是提供了xcode5.0加ios7的模擬器來實現(xiàn)模擬器開啟藍牙的,,本來連文章都給出了:https://developer.apple.com/library/ios/technotes/tn2295/_index.html

后來蘋果把這文章給刪了,還把ios7模擬器支持開啟藍牙給去掉,。

那么,,可以通過這個文章http://blog.csdn.net/zhenyu5211314/article/details/24399887,使用6.0的模擬器來調(diào)試。

參考文章

iOS CoreBluetooth 教程

藍牙 BLE CoreBluetooth 初探

藍牙4.0 For IOS

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多