天天看點

iOS學習,藍牙,iOS裝置模拟BLE發送資料

寫在前面

剛開始學習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

繼續閱讀