iOS開發(fā)丨藍(lán)牙4.0復(fù)制粘貼就能使用的CoreBluetooth藍(lán)牙框架

作為多年的iOS藍(lán)牙開發(fā)者,下面共享一下我自己搭建和使用的藍(lán)牙框架飒箭。首先創(chuàng)建一個(gè)類BluetoothManager,用來管理CBCentralManager和CBPeripheral蜒灰,以及一些掃描連接的公共方法弦蹂,其中數(shù)據(jù)和狀態(tài)回調(diào)使用通知的形式進(jìn)行處理,這樣在整個(gè)項(xiàng)目中强窖,只需要保存一份BluetoothManager就可以了凸椿,而不是在每個(gè)需要藍(lán)牙的頁面都生成CBCentralManager。

BluetoothManager.h文件實(shí)現(xiàn):

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 通知回調(diào)翅溺,需要接受消息的類必須注冊對應(yīng)的通知

static NSString * const BLENotificationBLECenterChangeState    = @"BLENotificationBLECenterChangeState";     // 藍(lán)牙狀態(tài)改變
static NSString * const BLENotificationPeripheralDidConnected  = @"BLENotificationPeripheralDidConnected";   // 設(shè)備連接成功
static NSString * const BLENotificationPeripheralConnectFailed = @"BLENotificationPeripheralConnectFailed";  // 設(shè)備連接失敗
static NSString * const BLENotificationPeripheralDisconnected  = @"BLENotificationPeripheralDisconnected";   // 設(shè)備斷開連接
static NSString * const BLENotificationPeripheralDidSendValue  = @"BLENotificationPeripheralDidSendValue";   // 寫入設(shè)備數(shù)據(jù)
static NSString * const BLENotificationPeripheralReceiveValue  = @"BLENotificationPeripheralReceiveValue";   // 收到設(shè)備數(shù)據(jù)
static NSString * const BLENotificationPeripheralSessionError  = @"BLENotificationPeripheralSessionError";   // 設(shè)備會(huì)話異常
static NSString * const BLENotificationPeripheralReadRSSIValue = @"BLENotificationPeripheralReadRSSIValue";  // 設(shè)備信號(hào)強(qiáng)度

/////////////////////////////////////////////////////////////////////////////////////////////////////////

static NSString * const BLEUUIDServicesSession      = @"1234";  // 通信Services
static NSString * const BLEUUIDCharacteristicRead   = @"CF16";  // 讀特征值
static NSString * const BLEUUIDCharacteristicWrite  = @"00000000-0000-0000-0000-000000123456";  // 寫特征值
static NSString * const BLEUUIDCharacteristicNotify = @"00000000-0000-0000-0000-000000563412";  // 通知特征值

/////////////////////////////////////////////////////////////////////////////////////////////////////////

typedef void (^ScanBlock)(CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI);
typedef void (^WriteBlock)(BOOL success);
typedef void (^TimeoutBlock)(void);

/////////////////////////////////////////////////////////////////////////////////////////////////////////

@interface BluetoothManager : NSObject

@property (strong, nonatomic) CBCentralManager *central;
@property (strong, nonatomic) CBPeripheral *peripheral;  // 當(dāng)前已連接上的設(shè)備
@property (strong, nonatomic) CBPeripheral *willConnectPeripheral;  // 將要連接的設(shè)備脑漫,作為臨時(shí)賦值保存,否則會(huì)出現(xiàn)無法連接的情況

+ (BluetoothManager *)sharedModel;
/// names傳入@[@""]則不過濾設(shè)備名咙崎,scanSystem是否掃描系統(tǒng)當(dāng)前已綁定設(shè)備
- (void)scanWithPrefixNames:(NSArray *)names timeout:(NSTimeInterval)timeout scanBlock:(ScanBlock)scanBlock timeoutBlock:(TimeoutBlock)timeoutBlock;
- (void)stopScan;
- (void)connect:(CBPeripheral *)peripheral timeout:(NSTimeInterval)timeout;
- (void)disconnect:(CBPeripheral *)peripheral;
- (BOOL)getWriteState;
- (void)readValueFromePeripheral;
- (void)writeValueToPeripheral:(NSData *)value block:(WriteBlock)block;

@end

其中BLEUUIDServicesSession优幸、BLEUUIDCharacteristicRead、BLEUUIDCharacteristicWrite褪猛、BLEUUIDCharacteristicNotify是需要你根據(jù)實(shí)際項(xiàng)目的需要進(jìn)行替換的藍(lán)牙UUID网杆。

BluetoothManager.m文件實(shí)現(xiàn)方法:

#import "BluetoothManager.h"

@interface BluetoothManager () <CBCentralManagerDelegate, CBPeripheralDelegate>

@property (copy, nonatomic)   ScanBlock scanBlock;
@property (copy, nonatomic)   WriteBlock writeBlock;
@property (copy, nonatomic)   TimeoutBlock timeoutBlock;
@property (copy, nonatomic)   NSArray *scanNames;
@property (strong, nonatomic) NSTimer *threadTimer;  // 獲取系統(tǒng)當(dāng)前藍(lán)牙設(shè)備列表線程
@property (strong, nonatomic) CBCharacteristic *characteristicRead;
@property (strong, nonatomic) CBCharacteristic *characteristicWrite;
@property (strong, nonatomic) CBCharacteristic *characteristicNotify;
@property (assign, nonatomic) BOOL isSendingData;    // 是否正在發(fā)送數(shù)據(jù)

@end

@implementation BluetoothManager

+ (BluetoothManager *)sharedModel {
    static BluetoothManager *sharedInstance;
    @synchronized(self) {
        if (!sharedInstance) {
            sharedInstance = [[BluetoothManager alloc] init];
        }
    }
    return sharedInstance;
}

- (id)init {
    if (self = [super init]) {
        self.central = [[CBCentralManager alloc] initWithDelegate:self
                                                            queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
                                                          options:@{CBCentralManagerOptionShowPowerAlertKey : @(NO)}];
    }
    return self;
}

- (void)dealloc {
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark 藍(lán)牙掃描和連接
/////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)scanWithPrefixNames:(NSArray *)names timeout:(NSTimeInterval)timeout scanBlock:(ScanBlock)scanBlock timeoutBlock:(TimeoutBlock)timeoutBlock {
    if (names) self.scanNames = names;
    if (scanBlock) self.scanBlock = scanBlock;
    if (timeoutBlock) self.timeoutBlock = timeoutBlock;
    [self stopScan];
    
    self.central.delegate = self;
    if (self.central.state == CBCentralManagerStatePoweredOn) {
        DLog(@"BluetoothManager: 開始掃描外部設(shè)備!");
        [self.central scanForPeripheralsWithServices:nil
                                             options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @(NO)}];  // 是否允許重復(fù)掃描同一設(shè)備
        if (timeout > 0) {
            [self performSelector:@selector(timeoutScan) withObject:nil afterDelay:timeout];
        }
    }
}

- (void)stopScan {
    [self.threadTimer invalidate];
    [self.central stopScan];
    DLog(@"BluetoothManager: 停止掃描!");
}

- (void)timeoutScan {
    [self stopScan];
    if (self.timeoutBlock) {
        dispatch_async( dispatch_get_main_queue(), ^{
            self.timeoutBlock();
        });
    }
}

- (void)connect:(CBPeripheral *)peripheral timeout:(NSTimeInterval)timeout {
    if (self.peripheral != nil) {
        [self disconnect:self.peripheral];  // 斷開當(dāng)前設(shè)備
    }
    if (peripheral.state != CBPeripheralStateConnected) {  // 連接新設(shè)備
        [self.central connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey : @(YES),
                                                             CBConnectPeripheralOptionNotifyOnDisconnectionKey : @(YES)}];
        if (timeout > 0) {  // 超時(shí)檢測
            [self performSelector:@selector(timeoutConnectPeripheral) withObject:nil afterDelay:timeout];
        }
    }
}

- (void)disconnect:(CBPeripheral *)peripheral {
    if (peripheral.state == CBPeripheralStateConnected) {
        [self.central cancelPeripheralConnection:peripheral];
    }
}

- (void)timeoutConnectPeripheral {
    if (self.peripheral.state != CBPeripheralStateConnected && self.peripheral.state != CBPeripheralStateConnecting) {
        DLog(@"BluetoothManager: 連接超時(shí) = %@", self.peripheral.name);
        dispatch_async( dispatch_get_main_queue(), ^{
            [NSObject cancelPreviousPerformRequestsWithTarget:self];
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralConnectFailed
                                                                object:self.peripheral];
        });
        [self initAllVariables];
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark CBCentralManagerDelegate
/////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    switch (central.state) {
        case CBCentralManagerStatePoweredOn: {
            DLog(@"BluetoothManager: 手機(jī)藍(lán)牙打開!");
        }
            break;
        case CBCentralManagerStatePoweredOff: {
            DLog(@"BluetoothManager: 手機(jī)藍(lán)牙關(guān)閉!");
            [self stopScan];
        }
            break;
        default:
            break;
    }
    dispatch_async( dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationBLECenterChangeState
                                                            object:central];
    });
}

- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI
{
    if ((-1000 <= RSSI.intValue && RSSI.intValue <= 0)
        && [advertisementData objectForKey:@"kCBAdvDataLocalName"] != nil
//        && [advertisementData objectForKey:@"kCBAdvDataServiceUUIDs"] != nil
        && peripheral.name != nil)
    {
        NSString *deviceName = advertisementData[@"kCBAdvDataLocalName"] ? advertisementData[@"kCBAdvDataLocalName"] : peripheral.name;
        DLog(@"BluetoothManager: RSSI = %d, name = %@, advertisementData = %@", [RSSI intValue], deviceName, advertisementData);
        for (NSString *scanName in self.scanNames) {
            if ([scanName isEqualToString:@""]  // 搜索所有名字
                || [deviceName hasPrefix:scanName]  // 搜索開頭包含scanName的名字
                || [deviceName rangeOfString:scanName].location != NSNotFound  // 搜索字符串包含scanName的名字
                )
            {
                if (self.scanBlock) {
                    dispatch_async( dispatch_get_main_queue(), ^{
                        self.scanBlock(peripheral, advertisementData, RSSI);
                    });
                }
            }
        }
    }
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    DLog(@"BluetoothManager: 已連接設(shè)備 = %@", peripheral.name);
    [self initAllVariables];
    self.peripheral = peripheral;
    self.peripheral.delegate = self;
    [self.peripheral discoverServices:nil];
    [self performSelector:@selector(timeoutDiscoverCharacteristics) withObject:nil afterDelay:5.0];
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    DLog(@"BluetoothManager: 連接失敗 = %@", peripheral.name);
    [self initAllVariables];
    dispatch_async( dispatch_get_main_queue(), ^{
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
        [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralConnectFailed
                                                            object:peripheral];
    });
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    DLog(@"BluetoothManager: 斷開設(shè)備 = %@", peripheral.name);
    [self initAllVariables];
    dispatch_async( dispatch_get_main_queue(), ^{
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
        [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralDisconnected
                                                            object:peripheral];
    });
}

- (void)timeoutDiscoverCharacteristics {
    if (self.characteristicRead == nil
        || self.characteristicWrite == nil
        || self.characteristicNotify == nil) {
        DLog(@"BluetoothManager: 查找設(shè)備特征值異常碳却!");
        dispatch_async( dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralSessionError
                                                                object:nil];
        });
    }
}

- (void)initAllVariables {
    self.isSendingData = NO;
    self.characteristicRead = nil;
    self.characteristicWrite = nil;
    self.characteristicNotify = nil;
    self.peripheral = nil;
    self.peripheral.delegate = nil;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark CBPeripheralDelegate
/////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    if ([error code] != 0) {
        DLog(@"BluetoothManager: 藍(lán)牙服務(wù)掃描異常 error = %@", error);
        return;
    }
    DLog(@"BluetoothManager: 藍(lán)牙服務(wù)掃描 = %@", peripheral.services);
    
    for (CBService *services in peripheral.services) {
        if ([[services UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDServicesSession]]) {
            [peripheral discoverCharacteristics:nil forService:services];
        }
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if ([error code] != 0) {
        DLog(@"BluetoothManager: 藍(lán)牙特征值掃描 error = %@", error);
        return;
    }
    DLog(@"BluetoothManager: 藍(lán)牙特征值掃描 %@ = %@", [service UUID], [service characteristics]);
    
    for (CBCharacteristic *characteristic in [service characteristics]) {
        // Read
        if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDCharacteristicRead]]) {
            DLog(@"BluetoothManager: 發(fā)現(xiàn) Read 特征值队秩!");
            self.characteristicRead = characteristic;
            [peripheral readValueForCharacteristic:characteristic];
        }
        // Write
        if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDCharacteristicWrite]]) {
            DLog(@"BluetoothManager: 發(fā)現(xiàn) Write 特征值!");
            self.characteristicWrite = characteristic;
        }
        // Notify
        if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDCharacteristicNotify]]) {
            DLog(@"BluetoothManager: 發(fā)現(xiàn) Notify 特征值追城!");
            self.characteristicNotify = characteristic;
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];
        }
    }
    
    // 發(fā)現(xiàn)全部特征值后刹碾,才表示完全連上設(shè)備
    if (self.characteristicRead != nil && self.characteristicWrite != nil && self.characteristicNotify != nil) {
        dispatch_async( dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralDidConnected
                                                                object:peripheral];
        });
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if ([error code] != 0) {
        DLog(@"BluetoothManager: 數(shù)據(jù)更新 error = %@", error);
        dispatch_async( dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralSessionError
                                                                object:error];
        });
        return;
    }
    
    if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDCharacteristicRead]]
        || [[characteristic UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDCharacteristicNotify]])
    {
        dispatch_async( dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralReceiveValue
                                                                object:characteristic.value];
        });
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if ([error code] != 0) {
        DLog(@"BluetoothManager: 寫值更新 error = %@", error);
        dispatch_async( dispatch_get_main_queue(), ^{
            if (self.writeBlock) {
                self.writeBlock(NO);
            }
            self.isSendingData = NO;
            [NSObject cancelPreviousPerformRequestsWithTarget:self];
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralSessionError
                                                                object:error];
        });
        return;
    }
    
    if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:BLEUUIDCharacteristicWrite]]) {
        dispatch_async( dispatch_get_main_queue(), ^{
            if (self.writeBlock) {
                self.writeBlock(YES);
            }
            self.isSendingData = NO;
            [NSObject cancelPreviousPerformRequestsWithTarget:self];
            [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralDidSendValue
                                                                object:characteristic.value];
        });
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(nullable NSError *)error {
    dispatch_async( dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralReadRSSIValue
                                                            object:RSSI];
    });
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark APP To Peripheral
/////////////////////////////////////////////////////////////////////////////////////////////////////////

- (BOOL)getWriteState {
    if (self.peripheral.state == CBPeripheralStateConnected && self.characteristicWrite != nil) {
        return YES;
    }
    return NO;
}

- (void)readValueFromePeripheral {
    if (self.characteristicRead != nil) {
        [self.peripheral readValueForCharacteristic:self.characteristicRead];
    }
}

- (void)writeValueToPeripheral:(NSData *)value block:(WriteBlock)block {
    if (self.peripheral.state != CBPeripheralStateConnected) {
        [[NSNotificationCenter defaultCenter] postNotificationName:BLENotificationPeripheralDisconnected
                                                            object:nil];
        return;
    }
    if (self.isSendingData) {
        DLog(@"BluetoothSession: ###### 正在發(fā)送數(shù)據(jù)! ######");
        return;
    }
    if (self.characteristicWrite != nil) {
        if (block) self.writeBlock = block;
        self.isSendingData = YES;
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(checkSessionTimeout) object:nil];
        [self.peripheral writeValue:value forCharacteristic:self.characteristicWrite type:CBCharacteristicWriteWithResponse];
        [self performSelector:@selector(checkSessionTimeout) withObject:nil afterDelay:5.0];
        DLog(@"BluetoothManager: 寫入數(shù)據(jù) = %@", value);
    }
}

- (void)checkSessionTimeout {
    if (self.isSendingData == YES) {
        DLog(@"BluetoothSession: ###### 藍(lán)牙通信超時(shí)! ######");
        if (self.writeBlock) {
            self.writeBlock(NO);
        }
        self.isSendingData = NO;
    }
}

@end

使用方法:

1燥撞、在AppDelegate的didFinishLaunchingWithOptions中調(diào)用[BluetoothManager sharedModel]進(jìn)行初始化座柱,如果藍(lán)牙未授權(quán),則此時(shí)系統(tǒng)會(huì)自動(dòng)調(diào)用授權(quán)彈窗物舒。

2色洞、在viewDidLoad中添加藍(lán)牙事件通知監(jiān)聽,在viewDidDisappear中移除通知監(jiān)聽冠胯。

- (void)addBluetoothNotification {
    // 藍(lán)牙連接事件
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(BLENotificationBLECenterChangeState:)
                                                 name:BLENotificationBLECenterChangeState
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(BLENotificationPeripheralDidConnected:)
                                                 name:BLENotificationPeripheralDidConnected
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(BLENotificationPeripheralDisconnected:)
                                                 name:BLENotificationPeripheralDisconnected
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(BLENotificationPeripheralConnectFailed:)
                                                 name:BLENotificationPeripheralConnectFailed
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(BLENotificationPeripheralSessionError:)
                                                 name:BLENotificationPeripheralSessionError
                                               object:nil];
}

- (void)removeBluetoothNotification {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BLENotificationBLECenterChangeState object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BLENotificationPeripheralDidConnected object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BLENotificationPeripheralDisconnected object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BLENotificationPeripheralSessionError object:nil];
}

3火诸、實(shí)現(xiàn)通知監(jiān)聽的回調(diào)方法,來處理藍(lán)牙設(shè)備的不同情況荠察。

/////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark BluetoothNotification
/////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)BLENotificationBLECenterChangeState:(NSNotification *)notif {
    CBCentralManager *central = notif.object;
    if (central.state == CBCentralManagerStatePoweredOn) {
        // 藍(lán)牙打開
    }
    else {
        // 藍(lán)牙關(guān)閉
    }
}

- (void)BLENotificationPeripheralDidConnected:(NSNotification *)notif {
    // 設(shè)備連接成功
}

- (void)BLENotificationPeripheralDisconnected:(NSNotification *)notif {
    // 設(shè)備斷開連接
}

- (void)BLENotificationPeripheralConnectFailed:(NSNotification *)notif {
    // 設(shè)備連接失敗
}

- (void)BLENotificationPeripheralSessionError:(NSNotification *)notif {
    // 藍(lán)牙異常狀態(tài)處理
}

4置蜀、調(diào)用scanWithPrefixNames進(jìn)行掃描設(shè)備,如傳入@[@"FOT"]表示只搜索設(shè)備名為FOT開頭的藍(lán)牙設(shè)備悉盆,如果不希望過濾設(shè)備名盯荤,可傳入@[@""];timeout可以指定掃描時(shí)間焕盟,一般為10秒秋秤,10秒過后自動(dòng)停止掃描,也可以傳0脚翘,這時(shí)候會(huì)在后臺(tái)一直掃描灼卢,除非調(diào)用stopScan方法停止掃描。scanBlock為符合條件的設(shè)備回調(diào)来农,你可以在這里對設(shè)備進(jìn)行判斷和連接操作鞋真。timeoutBlock為超時(shí)后的回調(diào),如果不使用可傳nil沃于。

// 掃描設(shè)備名為ABC123的藍(lán)牙設(shè)備涩咖,如果掃描到則進(jìn)行連接
[[BluetoothManager sharedModel] scanWithPrefixNames:@[@"ABC123"] timeout:0.0 scanBlock:^(CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
    [BluetoothManager sharedModel].willConnectPeripheral = peripheral;  // 必須保存此變量,才可正常連接
    [[BluetoothManager sharedModel] connect:[BluetoothManager sharedModel].willConnectPeripheral timeout:10.0];  //連接指定設(shè)備
    [[BluetoothManager sharedModel] stopScan];  // 停止掃描
} timeoutBlock:nil];

5揽涮、使用writeValueToPeripheral來將值寫入設(shè)備中抠藕。

[[BluetoothManager sharedModel] writeValueToPeripheral:data block:^(BOOL success) {
    if (success) {
        // 數(shù)據(jù)寫入成功
    }
    else {
        // 數(shù)據(jù)寫入失敗
    }
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蒋困,隨后出現(xiàn)的幾起案子盾似,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件零院,死亡現(xiàn)場離奇詭異溉跃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)告抄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門撰茎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人打洼,你說我怎么就攤上這事龄糊。” “怎么了募疮?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵炫惩,是天一觀的道長。 經(jīng)常有香客問我阿浓,道長他嚷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任芭毙,我火速辦了婚禮筋蓖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘退敦。我一直安慰自己粘咖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布苛聘。 她就那樣靜靜地躺著涂炎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪设哗。 梳的紋絲不亂的頭發(fā)上唱捣,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機(jī)與錄音网梢,去河邊找鬼震缭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛战虏,可吹牛的內(nèi)容都是我干的拣宰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烦感,長吁一口氣:“原來是場噩夢啊……” “哼巡社!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起晌该,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后朝群,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了踏志。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凄诞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忍级,到底是詐尸還是另有隱情帆谍,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布轴咱,位于F島的核電站汛蝙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏朴肺。R本人自食惡果不足惜窖剑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戈稿。 院中可真熱鬧西土,春花似錦、人聲如沸鞍盗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽般甲。三九已至肋乍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敷存,已是汗流浹背墓造。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滔岳。 一個(gè)月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓杠娱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谱煤。 傳聞我的和親對象是個(gè)殘疾皇子摊求,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354