日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS CoreBluetooth 教程

發布時間:2024/9/30 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS CoreBluetooth 教程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

去App Store搜索并下載“LightBlue”這個App,對調試你的app和理解Core Bluetooth會很有幫助。

================================

Demo下載地址:http://download.csdn.net/detail/jimoduwu/7146875

================================

Core?Bluetooth?for?iOS?6

CoreBluetoothAPI是基于BLE4.0的標準的。這個框架涵蓋了BLE標準的所有細節。僅僅只有新的iOS設備和Mac是和BLE標準兼容的:iPhone4SiPhone5MacMiniNew?iPad,MacBook?Air,MacBook?Pro。還有iPhone?iOS6的模擬器也支持。這是非常有用的,在你沒有一個真正的iOS設備而用模擬器去調試你的程序。

相關的類

CoreBluetooth框架中,有兩個主要的角色:周邊和中央(Peripheral?and?Central?,整個框架都是圍繞這兩個主要角色設計的,他倆之間有一系列的回調交換數據。下圖1展示了周邊和中央(Peripheral?and?Central),還有他倆之間的關系。


周邊(Peripheral)是生成或者保存了數據的設備,中央(Central)是使用這些數據的設備。所有可用的iOS設備可以作為周邊(Peripheral)也可以作為中央(Central),但不可以同時既是周邊也是中央。

周邊和中央這兩個角色在CoreBluetooth框架中是用兩個類來表示的,CBPeripheralManager這個類代表周邊,CBCentralManager?這個類代表中央。

在中央這邊,一個CBPeripheral?對象代表著相應的和中央連接著的周邊;同樣的,在周邊這邊,一個CBCentral?對象代表著相應的和周邊連接著的中央。

你可以認為周邊是一個廣播數據的設備,他廣播到外部世界說他這兒有數據,并且也說明了能提供的服務。另一邊,中央開始掃描附近有沒有服務,如果中央發現了想要的服務,然后中央就會請求連接周邊,一旦連接建立成功,兩個設備之間就開始交換傳輸數據了。

除了中央和周邊,我們還要考慮他倆交換的數據結構。這些數據在服務中被結構化,每個服務由不同的特征(Characteristics)組成,特征是包含一個單一邏輯值的屬性類型。如果你去http://developer.bluetooth.org鏈接,你可以找到標準服務和特征的列表。

在中央這邊,CBService?類代表服務,CBCharacteristic?類代表特征。在周邊這邊,CBMutableService?類代表服務,CBMutableCharacteristic?類代表特征。下圖2展示了到目前為止我們所講的所有類。


CBUUID?CBATTRequest?是兩個蘋果公司給我們提供的幫助類,以便于開發者更簡單地操作數據,稍后你將看到怎么使用這兩個類。

用法

很不幸,蘋果公司的CoreBluetooth文檔目前不是很完整,一些復雜的類確實沒有文檔說明。你只能通過去看WWCD視頻去理解這個框架是怎么工作的。因為在前一段時間我已經做過了這些,所以決定分享給大家。在NeuroSky,我們已經用CoreBluetooth框架開發了一些App。我很希望在這個教程可以幫到你。如果你想學到更多關于CoreBluetooth的知識,你可以出席我們的培訓課,在這兒查看下一堂課:?http://training.invasivecode.com

創建一個周邊:

讓我們開始創建一個完整的例子,你需要兩個iOS設備。我將告訴你怎么連接2iOS設備,通過藍牙交換數據,記住檢查你的iOS設備是不是在上邊列出的支持BLE的列表中。

開始創建一個周邊,跟著以下步驟(計劃):

1.創建并且開始Peripheral?Manager

2.設置并且發布這個周邊的所提供的服務。

3.廣播這個服務。

4.和中央相互作用。

Single-View?Application模板創建一個新的Xcode工程。命名為BlueServer?(使用ARC)。工程創建完成后,添加CoreBluetooth.framework?框架。然后打開ViewController.h文件,并且添加以下代碼:

#import?<CoreBluetooth/CoreBluetooth.h>

使view?controller繼承CBPeripheralManagerDelegate?協議,然后添加這個屬性:

@property?(nonatomic,?strong)?CBPeripheralManager?*manager;

ViewController.m中,添加以下代碼到viewDidLoad方法中:

self.manager?=?[[CBPeripheralManager?alloc]?initWithDelegate:self?queue:nil];

這行代碼創建了一個Peripheral?Manager(計劃中的第一項)。第一個參數是設置代理,這兒就是view?controller,第二個參數設置為nil,因為Peripheral?ManagerRun在主線程中。如果你想用不同的線程做更加復雜的事情,你需要創建一個隊列(queue)并將它放在這兒。

一旦Peripheral?Manager被創建,我們應該及時地檢查它的狀態,看正在運行App的這個設備是不是支持BLE標準。所以要實現以下這個代理方法,在這兒你可以做更復雜的一些事情和友好地提醒用戶,如果設備不支持BLE

-?(void)peripheralManagerDidUpdateState:(CBPeripheralManager?*)peripheral?{

????switch?(peripheral.state)?{

????????case?CBPeripheralManagerStatePoweredOn:

????????????[self?setupService];

????????????break;

????????default:

????????????NSLog(@"Peripheral?Manager?did?change?state");

????????????break;

????}

}

這兒,我檢查了周邊的狀態,如果他的狀態是CBPeripheralManagerStatePoweredOn,這個設備是支持BLE并且可用的。

服務和特征(Service?and?Characteristic)

setupService?方法是一個幫助方法,我即將創建它,讓它去準備服務和特征,對于這個例子,我們僅僅需要只有一個特征的一個服務。

每一個服務和特征都需要用一個UUIDunique?identifier)去標識,UUID是一個16bit或者128bit的值。如果你要創建你的中央-周邊App,你需要創建你自己的128bitUUID。你必須要確定你自己的UUID不能和其他已經存在的服務沖突。如果你正要創建一個自己的設備,需要實現標準委員會需求的UUID;如果你只是創建一個中央-周邊App(就像我們現在做的這樣),我建議你打開Mac?OS?XTerminal.app,用uuidgen命令生成一個128bitUUID。你應該用該命令兩次,生成兩個UUID,一個是給服務用的,一個是給特征用的。然后,你需要添加他們到中央和周邊App中。現在,在view?controller的實現之前,我們添加以下的代碼:

static?NSString?*?const?kServiceUUID?=?@"312700E2-E798-4D5C-8DCF-49908332DF9F";

static?NSString?*?const?kCharacteristicUUID?=?@"FFA28CDE-6525-4489-801C-1C060CAC9767";

注意:你自己用uuidgen生成的UUID和我的是不一樣的。

現在,以下是setupService?方法的實現:

-?(void)setupService?{

????//?Creates?the?characteristic?UUID

????CBUUID?*characteristicUUID?=?[CBUUID?UUIDWithString:kCharacteristicUUID];

????//?Creates?the?characteristic

????self.customCharacteristic?=?[[CBMutableCharacteristic?alloc]?initWithType:

characteristicUUID?properties:CBCharacteristicPropertyNotify?

value:nil?permissions:CBAttributePermissionsReadable];

????//?Creates?the?service?UUID

????CBUUID?*serviceUUID?=?[CBUUID?UUIDWithString:kServiceUUID];

????//?Creates?the?service?and?adds?the?characteristic?to?it

????self.customService?=?[[CBMutableService?alloc]?initWithType:serviceUUID

?primary:YES];

????//?Sets?the?characteristics?for?this?service

????[self.customService?setCharacteristics:

@[self.customCharacteristic]];

????//?Publishes?the?service

????[self.peripheralManager?addService:self.customService];

}?

首先,我用+UUIDWithString:方法給特征創建了一個UUID對象,然后我用這個UUID對象創建了一個特征。注意:我給初始化特征方法的第三個參數賦值nil,這是,我告訴CoreBluetooth,我將稍后添加一個特征的值。當你想要創建一個動態的數據,一般都這么做。如果你已經有了一直靜態的值要,你可以將它賦值在這兒。

在初始化特征的方法中,第一個參數是剛剛創建的UUID,第二個參數決定這個特征怎么使用。一下是所有可能的值:

?■CBCharacteristicPropertyBroadcast:?permits?broadcasts?of?

the?characteristic?value?using?a?characteristic?configuration

?descriptor.?Not?allowed?for?local?characteristics.

?

?CBCharacteristicPropertyRead:?permits?reads?of?the?

characteristic?value.

?CBCharacteristicPropertyWriteWithoutResponse:

?permits?writes?of?the?characteristic?value,?

without?a?response.

?CBCharacteristicPropertyWrite:?permits?writes?of

?the?characteristic?value.

?CBCharacteristicPropertyNotify:?permits?notifications?

of?the?characteristic?value,?without?a?response.

?CBCharacteristicPropertyIndicate:?permits?indications

?of?the?characteristic?value.

?CBCharacteristicPropertyAuthenticatedSignedWrites:?

permits?signed?writes?of?the?characteristic?value

?CBCharacteristicPropertyExtendedProperties:?if?set,?

additional?characteristic?properties?are?defined?in?

the?characteristic?extended?properties?descriptor.?

Not?allowed?for?local?characteristics.

?CBCharacteristicPropertyNotifyEncryptionRequired??:?

if?set,?only?trusted?devices?can?enable?notifications

?of?the?characteristic?value.

?CBCharacteristicPropertyIndicateEncryptionRequired:

?if?set,?only?trusted?devices?can?enable?indications?

of?the?characteristic?value.

?

最后一個參數是屬性的讀、寫、加密的權限,可能的值是以下的:

?CBAttributePermissionsReadable

?CBAttributePermissionsWriteable

?CBAttributePermissionsReadEncryptionRequired

?CBAttributePermissionsWriteEncryptionRequired

?

在創建了一個特征以后,又用了一次+UUIDWithString:方法,創建了一個服務。最后,我將特征添加到了服務上。記住,每一個服務可以包含多個特征。參見下圖3.


因此,我們需要創建一個特征的數組并且把這個數組傳給服務。在這個例子中,數組僅僅包含一個特征。

代碼的最后一行把服務添加到周邊管理者(Peripheral?Manager)是用于發布服務。一旦完成這個,周邊管理者會通知他的代理方法-peripheralManager:didAddService:error:。現在,如果沒有Error,你可以開始廣播服務了:

-?(void)peripheralManager:(CBPeripheralManager?*)peripheral

?didAddService:(CBService?*)service?error:(NSError?*)error?{

????if?(error?==?nil)?{

????????//?Starts?advertising?the?service

????????[self.peripheralManager?startAdvertising:

@{?CBAdvertisementDataLocalNameKey?:?

@"ICServer",?CBAdvertisementDataServiceUUIDsKey?:

?@[[CBUUID?UUIDWithString:kServiceUUID]]?}];

????}

}

當周邊管理者開始廣播服務,他的代理接收-peripheralManagerDidStartAdvertising:error:?消息,并且當中央預定了這個服務,他的代理接收?-peripheralManager:central:didSubscribeToCharacteristic:消息,這兒是你給中央生成動態數據的地方。

現在,要發送數據到中央,你需要準備一些數據,然后發送updateValue:forCharacteristic:onSubscribedCentrals:?到周邊。


創建一個中央

現在,我們已經有了一個周邊,讓我們創建我們的中央。中央就是那個處理周邊發送來的數據的設備。在下圖1中,CBCentralManager對象代表中央。

創建一個新的Xcode工程,命名為BlueClient,記得使用ARC。添加CoreBluetooth.framework框架到你的工程,并且導入頭文件到view?controller,以下代碼:

#import?<CoreBluetooth/CoreBluetooth.h>

在中央這邊,你的類必須要繼承這兩個協議:CBCentralManagerDelegateCBPeripheralDelegate,以下代碼:

@interface?ViewController?:?UIViewController?<CBCentralManagerDelegate,

?CBPeripheralDelegate>

并且添加以下兩個屬性:

@property?(nonatomic,?strong)?CBCentralManager?*manager;

@property?(nonatomic,?strong)?NSMutableData?*data;

現在,我要創建一個中央對象了:

self.manager?=?[[CBCentralManager?alloc]?initWithDelegate:self?queue:nil];

和創建周邊時一樣,第一個參數代表CBCentralManager?代理,在這個例子中就是這個view?controller;第二個參數設置為nil,因為Peripheral?ManagerRun在主線程中。如果你想用不同的線程做更加復雜的事情,你需要創建一個隊列(queue)并將它放在這兒。

Central?Manager被初始化,我們要檢查它的狀態,以檢查運行這個App的設備是不是支持BLE。實現以下的代理方法:

-?(void)centralManagerDidUpdateState:

(CBCentralManager?*)central?{

????switch?(central.state)?{

????????case?CBCentralManagerStatePoweredOn:

????????????//?Scans?for?any?peripheral

????????????[self.manager?scanForPeripheralsWithServices:

@[?[CBUUID?UUIDWithString:kServiceUUID]?]

?options:@{CBCentralManagerScanOptionAllowDuplicatesKey?:

?@YES?}];

????????????break;

????????default:

????????????NSLog(@"Central?Manager?did?change?state");

????????????break;

????}

}

-scanForPeripheralsWithServices:options:?方法是用于告訴Central?Manager,要開始尋找一個指定的服務了。如果你將第一個參數設置為nilCentral?Manager就會開始尋找所有的服務。

kServiceUUID?和創建周邊的那個工程中用的是一樣的UUID。所以,再添加一次以下兩行代碼:

static?NSString?*?const?kServiceUUID?=?@"312700E2-E798-4D5C-8DCF-49908332DF9F";

static?NSString?*?const?kCharacteristicUUID?=?@"FFA28CDE-6525-4489-801C-1C060CAC9767";

記住UUID是你自己用uuidgen命令生成的。

一旦一個周邊在尋找的時候被發現,中央的代理會收到以下回調:

-?(void)centralManager:(CBCentralManager?*)

central?didDiscoverPeripheral:(CBPeripheral?*)peripheral

?advertisementData:(NSDictionary?*)advertisementData

?RSSI:(NSNumber?*)RSSI???

這個調用通知Central?Manager代理(在這個例子中就是view?controller),一個附帶著廣播數據和信號質量(RSSI-Received?Signal?Strength?Indicator)的周邊被發現。這是一個很酷的參數,知道了信號質量,你可以用它去判斷遠近。

任何廣播、掃描的響應數據保存在advertisementData?中,可以通過CBAdvertisementData?來訪問它。現在,你可以停止掃描,而去連接周邊了:

-?(void)centralManager:(CBCentralManager?*)central

?didDiscoverPeripheral:(CBPeripheral?*)peripheral

?advertisementData:(NSDictionary?*)advertisementData

?RSSI:(NSNumber?*)RSSI?{

????//?Stops?scanning?for?peripheral

????[self.manager?stopScan];

????if?(self.peripheral?!=?peripheral)?{

????????self.peripheral?=?peripheral;

????????NSLog(@"Connecting?to?peripheral?%@",?peripheral);

????????//?Connects?to?the?discovered?peripheral

????????[self.manager?connectPeripheral:peripheral?options:nil];

????}

}

options?參數是一個可選的NSDictionary,如果需要,可以用以下的鍵(Key),它們的值始終是一個boolean

?CBConnectPeripheralOptionNotifyOnConnectionKey.?

This?is?a?NSNumber?(Boolean)?indicating?that?the?

system?should?display?an?alert?for?a?given?peripheral,

?if?the?application?is?suspended?when?a?successful?

connection?is?made.?This?is?useful?for?applications

?that?have?not?specified?the?Central?background?mode?

and?cannot?display?their?own?alert.?If?more?than?one?

application?has?requested?notification?for?a?given?

peripheral,?the?one?that?was?most?recently?in?the?

foreground?will?receive?the?alert.

?CBConnectPeripheralOptionNotifyOnDisconnectionKey.?

This?is?a?NSNumber?(Boolean)?indicating?that?the?

system?should?display?a?disconnection?alert?for?a?

given?peripheral,?if?the?application?is?suspended?

at?the?time?of?the?disconnection.?This?is?useful?for

applications?that?have?not?specified?the?Central?

background?mode?and?cannot?display?their?own?

alert.?If?more?than?one?application?has?requested

?notification?for?a?given?peripheral,?the?one?that?was

?most?recently?in?the?foreground?will?receive?the?alert.

?CBConnectPeripheralOptionNotifyOnNotificationKey.?

This?is?a?NSNumber?(Boolean)?indicating?that?the?

system?should?display?an?alert?for?all?notifications?

received?from?a?given?peripheral,?if?the?application

is?suspended?at?the?time.?This?is?useful?for?

applications?that?have?not?specified?the?Central?

background?mode?and?cannot?display?their?own

alert.?If?more?than?one?application?has?requested

notification?for?a?given?peripheral,?the?one?that?

was?most?recently?in?the?foreground?will?receive?the?alert.

?

基于連接的結果,代理(這個例子中是view?controller)會接收centralManager:didFailToConnectPeripheral:error:或者centralManager:didConnectPeripheral:。如果成功了,你可以問廣播服務的那個周邊。因此,在didConnectPeripheral?回調中,你可以寫以下代碼:

-?(void)centralManager:(CBCentralManager?*)central?

didConnectPeripheral:(CBPeripheral?*)peripheral?{

????//?Clears?the?data?that?we?may?already?have

????[self.data?setLength:0];

????//?Sets?the?peripheral?delegate

????[self.peripheral?setDelegate:self];

????//?Asks?the?peripheral?to?discover?the?service

????[self.peripheral?discoverServices:

@[?[CBUUID?UUIDWithString:kServiceUUID]?]];

}

現在,周邊開始用一個回調通知它的代理。在上一個方法中,我請求周邊去尋找服務,周邊代理接收-peripheral:didDiscoverServices:。如果沒有Error,可以請求周邊去尋找它的服務所列出的特征,像以下這么做:

-?(void)peripheral:(CBPeripheral?*)aPeripheral

?didDiscoverServices:(NSError?*)error?{

????if?(error)?{

????????NSLog(@"Error?discovering?service:

?%@",?[error?localizedDescription]);

????????[self?cleanup];

????????return;

????}

????for?(CBService?*service?in?aPeripheral.services)?{

????????NSLog(@"Service?found?with?UUID:?%@",

?service.UUID);

????????//?Discovers?the?characteristics?for?a?given?service

????????if?([service.UUID?isEqual:[CBUUID?

UUIDWithString:kServiceUUID]])?{

????????????[self.peripheral?discoverCharacteristics:

@[[CBUUID?UUIDWithString:

kCharacteristicUUID]]?forService:service];

????????}

????}

}???

現在,如果一個特征被發現,周邊代理會接收-peripheral:didDiscoverCharacteristicsForService:error:。現在,一旦特征的值被更新,用-setNotifyValue:forCharacteristic:,周邊被請求通知它的代理。

-?(void)peripheral:(CBPeripheral?*)peripheral?

didDiscoverCharacteristicsForService:

(CBService?*)service?error:(NSError?*)error?{

????if?(error)?{

????????NSLog(@"Error?discovering?characteristic:

?%@",?[error?localizedDescription]);

????????[self?cleanup];

????????return;

????}

????if?([service.UUID?isEqual:[CBUUID?UUIDWithString:

kServiceUUID]])?{

????????for?(CBCharacteristic?*characteristic?in?

service.characteristics)?{

????????????if?([characteristic.UUID?isEqual:[CBUUID?

UUIDWithString:kCharacteristicUUID]])?{

????????????????[peripheral?setNotifyValue:YES?

forCharacteristic:characteristic];

????????????}

????????}

????}

}

這兒,如果一個特征的值被更新,然后周邊代理接收-peripheral:didUpdateNotificationStateForCharacteristic:error:。你可以用-readValueForCharacteristic:讀取新的值:

-?(void)peripheral:(CBPeripheral?*)peripheral?

didUpdateNotificationStateForCharacteristic:

(CBCharacteristic?*)characteristic?error:(NSError?*)error?{

????if?(error)?{

????????NSLog(@"Error?changing?notification?state:

?%@",?error.localizedDescription);

????}

????//?Exits?if?it's?not?the?transfer?characteristic

????if?(![characteristic.UUID?isEqual:[CBUUID?

UUIDWithString:kCharacteristicUUID]])?{

????????return;

????}

????//?Notification?has?started

????if?(characteristic.isNotifying)?{

????????NSLog(@"Notification?began?on?%@",?characteristic);

????????[peripheral?readValueForCharacteristic:characteristic];

????}?else?{?//?Notification?has?stopped

????????//?so?disconnect?from?the?peripheral

????????NSLog(@"Notification?stopped?on?%@.

??Disconnecting",?characteristic);

????????[self.manager?cancelPeripheralConnection:self.peripheral];

????}

}

當周邊發送新的值,周邊代理接收-peripheral:didUpdateValueForCharacteristic:error:。這個方法的第二個參數包含特征。你可以用value屬性讀取他的值。這是一個包含特征的值的NSData

?結語:

I?showed?you?a?basic?example?on?how?to?use?the?

Core?Bluetooth?framework.?I?hope?that?this?

small?tutorial,?the?WWDC?videos?and?the?

documentation?(the?available?one)?can?help?

you?create?new?iOS?applications?using?the?

Bluetooth?LE.?Check?also?the?examples?

coming?with?the?documentation.?There,?

you?will?find?all?the?delegate?methods

?I?used?in?this?tutorial.

總結

以上是生活随笔為你收集整理的iOS CoreBluetooth 教程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。