寫在前面
剛開始學習iOS開發,在此過程中學習到很多知識點,寫這些的目的,首先是為了給像我一樣的小白提供一些參考資料,其次是對自己所學知識的一個總結與記錄。 廢話不多說,下面開始。 之前寫過一篇總結,是IOS裝置對藍牙資料的接收,之後更新UI。我現在實際中,負責藍牙子產品的同僚還沒搞定,我如果要繼續做藍牙的相關工作(接收藍牙資料,之後畫圖什麼的)就要自己制造些資料用來接收。這就涉及藍牙的外設,也就是藍牙4.0規範中得BLE,bluetooth smart,下面的工作就是模拟一個這樣的裝置來一直發送資料。
準備工作
1.導入CoreBluetooth架構 2.實作外設代理(請看下面的.h檔案)
正式開始
由于就是用來發資料的,界面簡單,就一個switch,如果開,就廣播,讓别人可以搜尋到。storyboard中拖一個switch ,需要action來控制廣播開關。
沒有多餘viewController,就是建立工程時候自己帶的那個,點開.h檔案,輸入如下:
#import <UIKit/UIKit.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface TBViewController : UIViewController <CBPeripheralManagerDelegate>
@property (nonatomic, strong) CBPeripheralManager *manager;
@end
在編寫.m檔案之前,建立一個頭檔案,用來存放service 和 characteristic的UUID,友善管理。當然,你寫在剛才的.h中也行。不過我還是推薦用專門的.h來管理,UUID.h
#ifndef SmartBicycle_UUID_h
#define SmartBicycle_UUID_h
#define TRANSFER_SERVICE_UUID @"FFF0"
#define TRANSFER_CHARACTERISTIC_UUID @"FFF1"
#endif
倆宏,沒啥難度。下面開始真正工作,在viewController的.m檔案中:
// TBViewController.m
#import "TBViewController.h"
#import "UUID.h"
@interface TBViewController () {
}
@property (strong, nonatomic) CBMutableCharacteristic *customCharacteristic;
@property (strong, nonatomic) CBMutableService *customService;
@property (strong, nonatomic) NSData *dataToSend;
@property (weak, nonatomic) IBOutlet UISwitch *advertisingSwitch;
- (IBAction)switchChanged:(UISwitch *)sender;
@end
@implementation TBViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.manager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
}
#pragma -mark 消失,停止廣告
- (void)viewWillDisappear:(BOOL)animated
{
[self.manager stopAdvertising];
[super viewWillDisappear:animated];
}
#pragma -mark 檢查peripheral狀态
//如果狀态正确,開始服務
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
switch (peripheral.state) {
case CBPeripheralManagerStatePoweredOn:
[self setupService];
break;
default:
NSLog(@"the peripheralManagerState is not PoweredOn");
break;
}
}
#pragma -mark 開始服務
- (void)setupService
{
//CHARACTERISTIC UUID
CBUUID *characteristicUUID = [CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID];
self.customCharacteristic = [[CBMutableCharacteristic alloc] initWithType:characteristicUUID properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];
//SERVICE UUID
CBUUID *serviceUUID = [CBUUID UUIDWithString:TRANSFER_SERVICE_UUID];
self.customService = [[CBMutableService alloc] initWithType:serviceUUID primary:YES];
[self.customService setCharacteristics:@[self.customCharacteristic]];
[self.manager addService:self.customService];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
{
NSLog(@"Central subscribed to characteristic");
int i = rand()%20;
NSString *stringToSend = [NSString stringWithFormat:@"%d", i];
NSLog(@"the random number is ---> %d", i);
NSData *data = [stringToSend dataUsingEncoding:NSUTF8StringEncoding];
if ([self.manager updateValue:data forCharacteristic:self.customCharacteristic onSubscribedCentrals:nil]) {
NSLog(@"success, send number -- > %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}else{
NSLog(@"failed");
}
}
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic
{
NSLog(@"Central unsubscribed from characteristic");
}
- (IBAction)switchChanged:(UISwitch *)sender {
if (self.advertisingSwitch.on) {
// All we advertise is our service's UUID
[self.manager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
}
else {
[self.manager stopAdvertising];
}
}
@end
主要都是一些回調,通過方法名字就知道是在何時回調。 如果有IOS中央訂閱了某個characteristic,就會回調帶didSubscribe的方法,這個方法中實作發送資料。在實際測試中發現,外設會一直回調這個東西,是以會一直發送資料,測試方法就是,産生一個随機數,列印一下,當發生發送資料時,把發送的資料也列印一下,發現兩資料一樣,回調頻率也挺高的。具體多少還沒查,跟一般的手環、心率器頻率應該差不多,可以達到模拟的目的。 注意發送string時候的編碼格式,外設和中央應該一緻,不然有些資料可能在中央沒法顯示。我用的都是UTF8