CoreBluetooth學習

  • 設備斷開後調用的函數是哪個呢?CoreBluetooth 框架
  • 2013-06-07 16:59:32
    回覆
    You can search "TemperatureSensor" in the XCode Organizer documentation 

    And you need to restart the scanning function if the device is disconnected: 


    /** Once the disconnection happens, we need to clean up our local copy of the peripheral 
    */ 
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error 

    NSLog(@"Peripheral Disconnected"); 
    [discoveredPeripheral release]; 
    discoveredPeripheral = nil; 

    // We're disconnected, so start scanning again 
    [self scan]; 

  • 2013-06-08 11:00:39
    回覆
    謝謝,我找到這個方法了。還有一個問題,我掃描到服務後,然後調用- (void)connectPeripheral:(CBPeripheral *)peripheral options:(NSDictionary *)options;方法,有時候回調方法-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral執行的很慢,很久才能連接上遍歷服務,請問這是怎麼回事?
  • 2013-06-10 12:19:04
    回覆
    Since the CoreBluetooth framework for the iOS is not really stable, sometimes it will spend about 4s to connect the device. 
    It should be according to the bluetooth device that you want to connect. 
    If it is the other external bluetooth hardware, it should be connected within 1s. 
    If you use back the other iOS device and waiting for the connection, it will take much longer time or fail to connect. 

    So I suggest you to implement the this delegate: 


    /** If the connection fails for whatever reason, we need to deal with it. 
    */ 
    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error 

    NSLog(@"Failed to connect to %@. (%@)", peripheral, [error localizedDescription]); 
    [self cleanup]; 


    But sometime, the CoreBluetooth will become hang in status while it try to connect to the iOS device. 
    And it may be fixed by restarting the bluetooth in the iOS device or you need to restart your iOS device. 
    It seems that we need to wait for Apple to fix this issue. 
  • WAN
    2013-09-24 10:53:48
    回覆
    @Code4appDev : 你好,碰到一個類似的問題。反覆連接單片機a之後,會出現再也連接不上的情況。只要重啓藍牙或者先去連接另外一塊單片機b之後,再回來連接單片機a就可以連接成功。不知道如何解決,請教!!!
  • 2013-06-10 12:19:55
    回覆
    for the -(void)cleanup function: 

    /** Call this when things either go wrong, or you're done with the connection. 
    * This cancels any subscriptions if there are any, or straight disconnects if not. 
    * (didUpdateNotificationStateForCharacteristic will cancel the connection if a subscription is involved) 
    */ 
    - (void)cleanup 

    // Don't do anything if we're not connected 
    if (!discoveredPeripheral.isConnected) { 
    return; 


    // See if we are subscribed to a characteristic on the peripheral 
    if (discoveredPeripheral.services != nil) { 
    for (CBService *service in discoveredPeripheral.services) { 
    if (service.characteristics != nil) { 
    for (CBCharacteristic *characteristic in service.characteristics) { 
    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:myCharacteristicUUID]]) { 
    if (characteristic.isNotifying) { 
    // It is notifying, so unsubscribe 
    [discoveredPeripheral setNotifyValue:NO forCharacteristic:characteristic]; 

    // And we're done. 
    return; 







    // If we've got this far, we're connected, but we're not subscribed, so we just disconnect 
    [centralManager cancelPeripheralConnection:discoveredPeripheral]; 
    }
  • 2013-06-19 15:51:22
    回覆
    可以簡單講一下藍牙4.0連接的步驟嗎? 
    是不是因爲我步驟錯誤,所以連接有問題呢?
  • 2013-06-20 15:41:54
    回覆
    First of All, in the .h, you should implement the CoreBluetooth delegate 

    @interface BlueToothClient : NSObject < CBCentralManagerDelegate, CBPeripheralDelegate> 


    And then create the CBCentralManager instance in .m, 

    // Start up the CBCentralManager 
    centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 

    ---------------Step 1--------------- 

    /** Scan for peripherals - specifically for our service's 128bit CBUUID 
    */ 
    - (void)scan 

    [centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:myServicUUID]] 
    options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }]; 



    ---------------Step 2--------------- 

    /** This callback comes whenever a peripheral that is advertising the TRANSFER_SERVICE_UUID is discovered. 
    * We check the RSSI, to make sure it's close enough that we're interested in it, and if it is, 
    * we start the connection process 
    */ 
    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 

    //NSLog(@"Discovered %@ at %@", peripheral.name, RSSI); 

    // Ok, it's in range - have we already seen it? 
    if (discoveredPeripheral != peripheral) { 

    // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it 
    discoveredPeripheral = peripheral; 
    [discoveredPeripheral retain]; 

    // And connect 
    NSLog(@"Connecting to peripheral %@", peripheral); 
    [centralManager connectPeripheral:peripheral options:nil]; 



    ---------------Step 3--------------- 


    /** We've connected to the peripheral, now we need to discover the services and characteristics to find the 'transfer' characteristic. 
    */ 
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral 

    NSLog(@"Peripheral Connected"); 

    // Stop scanning 
    [centralManager stopScan]; 
    NSLog(@"Scanning stopped"); 

    // Make sure we get the discovery callbacks 
    peripheral.delegate = self; 

    // Search only for services that match our UUID 
    [peripheral discoverServices:@[[CBUUID UUIDWithString:myServicUUID]]]; 



    ---------------Step 4--------------- 

    /** The Transfer Service was discovered 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 

    if (error) { 
    NSLog(@"Error discovering services: %@", [error localizedDescription]); 
    [self cleanup]; 
    return; 


    // Discover the characteristic we want... 

    // Loop through the newly filled peripheral.services array, just in case there's more than one. 
    for (CBService *service in peripheral.services) { 
    [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:myCharacteristicUUID]] forService:service]; 



    ---------------Step 5--------------- 

    /** The Transfer characteristic was discovered. 
    * Once this has been found, we want to subscribe to it, which lets the peripheral know we want the data it contains 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error 

    // Deal with errors (if any) 
    if (error) { 
    NSLog(@"Error discovering characteristics: %@", [error localizedDescription]); 
    [self cleanup]; 
    return; 


    // Again, we loop through the array, just in case. 
    for (CBCharacteristic *characteristic in service.characteristics) { 

    // And check if it's the right one 
    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:myCharacteristicUUID]]) { 

    // If it is, subscribe to it 
    [peripheral setNotifyValue:YES forCharacteristic:characteristic]; 



    // Once this is complete, we just need to wait for the data to come in. 



    ---------------Step 6--------------- 

    /** This callback lets us know more data has arrived via notification on the characteristic 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 

    NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; 

    printf("stringFromData %s\n", [stringFromData UTF8String]); 

    if (error) { 
    NSLog(@"Error didUpdateValueForCharacteristic: %@", [error localizedDescription]); 
    return; 


    // Log it 
    NSLog(@"Received: %@", stringFromData); 


    ---------------Step 7--------------- 

    //For status change handling 

    /** The peripheral letting us know whether our subscribe/unsubscribe happened or not 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 

    if (error) { 
    NSLog(@"Error changing notification state: %@", error.localizedDescription); 


    // Exit if it's not the transfer characteristic 
    if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:myCharacteristicUUID]]) { 
    return; 


    // Notification has started 
    if (characteristic.isNotifying) { 
    NSLog(@"Notification began on %@", characteristic); 


    // Notification has stopped 
    else { 
    // so disconnect from the peripheral 
    NSLog(@"Notification stopped on %@. Disconnecting", characteristic); 
    [centralManager cancelPeripheralConnection:peripheral]; 




    /** Once the disconnection happens, we need to clean up our local copy of the peripheral 
    */ 
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error 

    NSLog(@"Peripheral Disconnected"); 
    [discoveredPeripheral release]; 
    discoveredPeripheral = nil; 

    // We're disconnected, so start scanning again 
    [self scan]; 

  • 2013-06-20 17:41:20
    回覆
    謝啦!我再仔細研究研究。 
    我以前是先掃描列表,然後再點擊列表進行連接,遍歷服務。 
    您的做法是遍歷所有設備的服務,這樣的話會不會太浪費資源啊?
  • 2013-06-21 12:48:42
    回覆
    No, It will only scan for the specific myServicUUID 


    In step 1 

    [centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:myServicUUID]] 

    In step 3 

    // Search only for services that match our UUID 
    [peripheral discoverServices:@[[CBUUID UUIDWithString:myServicUUID]]];
  • 2013-06-24 10:52:29
    回覆
    CBConcretePeripheral: 0x8abf020 UUID = 16E72F7B-3DE9-0D33-1ADC-CB7FB4CB523A 
    這個128位的CBUUID是設備連接的唯一標示,但是當手機重置後這個CBUUID會改變,我怎麼確定我的設備的CBUUID呢? 
  • 2013-06-24 12:07:33
    回覆
    In delegate of - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 

    your can get back the target bluetooth device UUID by peripheral.UUID
  • 2013-06-24 12:16:27
    回覆
    You can try to see the demo save and load function: 

    - (void) addSavedDevice:(CFUUIDRef) uuid 

    NSArray *storedDevices = [[NSUserDefaults standardUserDefaults] arrayForKey:@"StoredDevices"]; 
    NSMutableArray *newDevices = nil; 
    CFStringRef uuidString = NULL; 

    if (![storedDevices isKindOfClass:[NSArray class]]) { 
    NSLog(@"Can't find/create an array to store the uuid"); 
    return; 


    newDevices = [NSMutableArray arrayWithArray:storedDevices]; 

    uuidString = CFUUIDCreateString(NULL, uuid); 
    if (uuidString) { 
    [newDevices addObject:(NSString*)uuidString]; 
    CFRelease(uuidString); 

    /* Store */ 
    [[NSUserDefaults standardUserDefaults] setObject:newDevices forKey:@"StoredDevices"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 


    - (void) loadSavedDevices 

    NSArray *storedDevices = [[NSUserDefaults standardUserDefaults] arrayForKey:@"StoredDevices"]; 

    if (![storedDevices isKindOfClass:[NSArray class]]) { 
    NSLog(@"No stored array to load"); 
    return; 


    for (id deviceUUIDString in storedDevices) { 

    if (![deviceUUIDString isKindOfClass:[NSString class]]) 
    continue; 

    CFUUIDRef uuid = CFUUIDCreateFromString(NULL, (CFStringRef)deviceUUIDString); 
    if (!uuid) 
    continue; 

    [centralManager retrievePeripherals:[NSArray arrayWithObject:(id)uuid]]; 
    CFRelease(uuid); 



    And the delegate function for the Retrieve Peripheral 

    - (void) centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals 

    CBPeripheral *peripheral; 

    /* Add to list. */ 
    for (peripheral in peripherals) { 
    [central connectPeripheral:peripheral options:nil]; 



    - (void) centralManager:(CBCentralManager *)central didRetrievePeripheral:(CBPeripheral *)peripheral 

    [central connectPeripheral:peripheral options:nil]; 


  • 2013-07-01 16:26:07
    回覆
    我想再請問一下,如果我想讓程序在後臺調用回調方法- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI方法改怎麼辦? 
    我發現在後臺的時候程序只能調用啓-(void)centralManagerDidUpdateState:(CBCentralManager *)central
  • 2013-07-03 11:45:57
    回覆
    First of all, if you want to use this delegate "- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI" in background, you need to follow two step: 

    Step 1: Add the key "Required background modes" in the info plist with value "App communicates using CoreBluetooth" 

    Step 2: You can only scan the bluetooth 4.0 device with the specific service in background. You are not allowed to scan any of the bluetooth 4.0 device in background. This means that you cannot pass nil in the service array of the scanning method. You need to pass the specific service array, e.g. 

    [centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"180d"]] options:options]; //Scan for the any bluetooth 4.0 device with "Heart beat service" support
  • ╰☆叛逆の王
    2013-11-28 17:12:20
    回覆
    @Code4appDev : thanks for all your answers! Its' so useful to me.
  • 2013-07-05 09:22:28
    回覆
    感謝您對我問題的回答,麻煩了。
  • 2013-12-10 02:17:34
    回覆
    正好需要這方面的東西 mark下。。。。
  • 2013-12-11 12:35:27
    回覆
    有個問題想請教一下 ,我現在掃描外設的UUID 爲什麼掃描不到呢? 
    我是這麼寫的 
    [_centralManger scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@“0xFFE0”] ] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES, CBCentralManagerOptionRestoreIdentifierKey :@YES }]; 
    現在奇怪的是我想要連接的外設的SeverUUID確實是0xFFE0,但是我掃描這個UUID的時候就是掃描不到, 
    當我[_centralManger scanForPeripheralsWithServices:nil options:nil];這麼寫的時候就能掃描到外設,連接成功後打印出來的SeverUUID也是0xFFE0
  • 2013-12-11 15:14:08
    回覆
    I think you service uuid should be [CBUUID UUIDWithString:@"ffe0"] instead of [CBUUID UUIDWithString:@"0xFFE0"]. 
    The service UUID should be a string and 0xFFE0 looks like a hex string. 

    or you can try this remove the option CBCentralManagerOptionRestoreIdentifierKey: 

    [centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"0xFFE0"] ] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES}];
  • ゞ灬百馫果╰
    2013-12-23 10:30:13
    回覆
    @Code4appDev : 能不能告訴我如何才能將ios設備寫成外設的形式 updateValue:forCharacteristic:onSubscribedCentrals: 這個方法該怎麼用 怎樣才能讓它一直髮送數據呢 用另一臺設備發送setnotify的時候會執行這個方法: peripheralManager:central:didSubscribeToCharacteristic:
  • 2014-01-13 15:36:24
    回覆
    My apps same as below code,but can`t get data from remote peripheral device using - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 

    Any comment and pointer will be welcome. Thanks. 
    ;============================================== 
    // Start up the CBCentralManager 
    centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 

    ---------------Step 1--------------- 

    /** Scan for peripherals - specifically for our service's 128bit CBUUID 
    */ 
    - (void)scan 

    [centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:myServicUUID]] 
    options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }]; 



    ---------------Step 2--------------- 

    /** This callback comes whenever a peripheral that is advertising the TRANSFER_SERVICE_UUID is discovered. 
    * We check the RSSI, to make sure it's close enough that we're interested in it, and if it is, 
    * we start the connection process 
    */ 
    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 

    //NSLog(@"Discovered %@ at %@", peripheral.name, RSSI); 

    // Ok, it's in range - have we already seen it? 
    if (discoveredPeripheral != peripheral) { 

    // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it 
    discoveredPeripheral = peripheral; 
    [discoveredPeripheral retain]; 

    // And connect 
    NSLog(@"Connecting to peripheral %@", peripheral); 
    [centralManager connectPeripheral:peripheral options:nil]; 



    ---------------Step 3--------------- 


    /** We've connected to the peripheral, now we need to discover the services and characteristics to find the 'transfer' characteristic. 
    */ 
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral 

    NSLog(@"Peripheral Connected"); 

    // Stop scanning 
    [centralManager stopScan]; 
    NSLog(@"Scanning stopped"); 

    // Make sure we get the discovery callbacks 
    peripheral.delegate = self; 

    // Search only for services that match our UUID 
    [peripheral discoverServices:@[[CBUUID UUIDWithString:myServicUUID]]]; 



    ---------------Step 4--------------- 

    /** The Transfer Service was discovered 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 

    if (error) { 
    NSLog(@"Error discovering services: %@", [error localizedDescription]); 
    [self cleanup]; 
    return; 


    // Discover the characteristic we want... 

    // Loop through the newly filled peripheral.services array, just in case there's more than one. 
    for (CBService *service in peripheral.services) { 
    [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:myCharacteristicUUID]] forService:service]; 



    ---------------Step 5--------------- 

    /** The Transfer characteristic was discovered. 
    * Once this has been found, we want to subscribe to it, which lets the peripheral know we want the data it contains 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error 

    // Deal with errors (if any) 
    if (error) { 
    NSLog(@"Error discovering characteristics: %@", [error localizedDescription]); 
    [self cleanup]; 
    return; 


    // Again, we loop through the array, just in case. 
    for (CBCharacteristic *characteristic in service.characteristics) { 

    // And check if it's the right one 
    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:myCharacteristicUUID]]) { 

    // If it is, subscribe to it 
    [peripheral setNotifyValue:YES forCharacteristic:characteristic]; 



    // Once this is complete, we just need to wait for the data to come in. 



    ---------------Step 6--------------- 

    /** This callback lets us know more data has arrived via notification on the characteristic 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 

    NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; 

    printf("stringFromData %s\n", [stringFromData UTF8String]); 

    if (error) { 
    NSLog(@"Error didUpdateValueForCharacteristic: %@", [error localizedDescription]); 
    return; 


    // Log it 
    NSLog(@"Received: %@", stringFromData); 


    ---------------Step 7--------------- 

    //For status change handling 

    /** The peripheral letting us know whether our subscribe/unsubscribe happened or not 
    */ 
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 

    if (error) { 
    NSLog(@"Error changing notification state: %@", error.localizedDescription); 


    // Exit if it's not the transfer characteristic 
    if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:myCharacteristicUUID]]) { 
    return; 


    // Notification has started 
    if (characteristic.isNotifying) { 
    NSLog(@"Notification began on %@", characteristic); 


    // Notification has stopped 
    else { 
    // so disconnect from the peripheral 
    NSLog(@"Notification stopped on %@. Disconnecting", characteristic); 
    [centralManager cancelPeripheralConnection:peripheral]; 




    /** Once the disconnection happens, we need to clean up our local copy of the peripheral 
    */ 
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error 

    NSLog(@"Peripheral Disconnected"); 
    [discoveredPeripheral release]; 
    discoveredPeripheral = nil; 

    // We're disconnected, so start scanning again 
    [self scan]; 

  • 2014-01-13 15:57:21
    回覆
    My peripheral device is OEM device and can working fine with OEM iOS apps, but my apps and light blue can`t get any data after paired, but if I open OEM apps and pair with it then closed OEM apps, and then open my apps or light blue, at this time my apps or lighteblue tools can update data by using [peripheral setNotifyValue:YES forCharacteristic:characteristic]; 

    I don`t know that the OEM device used which encryption method then cause my apps can`t get data? Please give me a hand. Thanks.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章