1. 程式人生 > >IOS藍芽連線和傳送資料

IOS藍芽連線和傳送資料

首先要確定藍芽是否開啟
本文使用的是 Objective-C語言
1.新建一個藍芽幫助類BlueHelp
並匯入

pragma mark - CBPeripheralDelegate

//只要掃描到服務就會呼叫,其中的外設就是服務所在的外設
- (void)peripheral:(CBPeripheral )peripheral didDiscoverServices:(NSError )error{
if (error){
NSLog(@”掃描服務出現錯誤,錯誤原因:%@”,error);
}else{
//獲取外設中所掃描到的服務
NSArray *services = peripheral.services;
for (CBService *service in services){
//拿到需要掃描的服務,例如列印一些服務資料
//把所有的service打印出來
NSLog(@”service is :%@”,service);
//從需要的服務中查詢需要的特徵
//從peripheral的services中掃描特徵
[peripheral discoverCharacteristics:nil forService:service];
}
}
}

//只要掃描到特徵就會呼叫,其中的外設和服務就是特徵所在的外設和服務
- (void)peripheral:(CBPeripheral )peripheral didDiscoverCharacteristicsForService:(CBService )service error:(NSError *)error{
if (error){
NSLog(@”掃描特徵出現錯誤,錯誤原因:%@”,error);
}else{
//拿到服務中所有的特徵
NSArray *characteristics = service.characteristics;
//遍歷特徵,拿到需要的特徵進行處理
for (CBCharacteristic *characteristic in characteristics){
NSLog(@”所有的特徵為:%@”,characteristic.UUID.UUIDString);
//如果是溫度資料處理
if([characteristic.UUID.UUIDString isEqualToString:@”你自己的特徵值”]){
//將全部的特徵資訊打印出來
_peripheral = peripheral;
scperipheral = peripheral;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
NSLog(@”%@”,characteristic);
}
//這裡是傳送 裝置設定藍芽傳送溫度資料的值
else if([characteristic.UUID.UUIDString isEqualToString:@”你自己的特徵值”]){
writecharacteristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
NSLog(@”寫入的值為:%@”,characteristic);
}
//如果是ota進行ota升級
else if([characteristic.UUID.UUIDString isEqualToString:@”你需要的特徵值”]){
_peripheral = peripheral;
scperipheral = peripheral;
writeOtacharacteristic = characteristic;
//設定通知
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
//NSLog(@”OTA升級了”);
isOTA = TRUE;
NSString *s = @”OTA”;
NSDictionary *tempOta = [NSDictionary dictionaryWithObject:s forKey:@”ota”];
[[NSNotificationCenter defaultCenter] postNotificationName:@”tempOTA” object:nil userInfo:tempOta];
}
//無鍵按鈕DFU
else if([characteristic.UUID.UUIDString isEqualToString:@”你自己需要的特徵值”]){
writeDfucharacteristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
NSLog(@”寫入的OTA值為:%@”,characteristic);
}
}
}
}

/*
* 獲取所有的溫度更新資料
* 接收藍芽傳送過來的溫度資料 並經過解析和轉換
*/
- (void)peripheral:(CBPeripheral )peripheral didUpdateValueForCharacteristic:(CBCharacteristic )characteristic error:(NSError *)error
{
if ([characteristic.UUID isEqual:BOOT_LOADER_CHARACTERISTIC_UUID])
{
uint8_t dataPointer = (uint8_t

) [characteristic.value bytes];
NSString *errorCode = [NSString stringWithFormat:@”0x%2x”,dataPointer[1]];
errorCode = [errorCode stringByReplacingOccurrencesOfString:@” ” withString:@”0”];

    // Checking the error code from the response
    if ([errorCode isEqualToString:SUCCESS]&&commandArray.count>0)
    {
        if ([[commandArray objectAtIndex:0] isEqual:@(ENTER_BOOTLOADER)])
        {
            [self getBootLoaderDataFromCharacteristic:characteristic];
        }
        else if ([[commandArray objectAtIndex:0] isEqual:@(GET_FLASH_SIZE)])
        {
            [self getFlashDataFromCharacteristic:characteristic];
        }
        else if ([[commandArray objectAtIndex:0] isEqual:@(SEND_DATA)])
        {
            _isWritePacketDataSuccess = YES;
            [_userDefaults setBool:_isWritePacketDataSuccess forKey:@"WriteSuccess"];
        }
        else if ([[commandArray objectAtIndex:0] isEqual:@(PROGRAM_ROW)])
        {
            _isWritePacketDataSuccess = YES;
            [_userDefaults setBool:_isWritePacketDataSuccess forKey:@"WriteSuccess"];
        }

        else if ([[commandArray objectAtIndex:0] isEqual:@(VERIFY_ROW)])
        {
            [self getRowCheckSumFromCharacteristic:characteristic];
        }
        else if([[commandArray objectAtIndex:0] isEqual:@(VERIFY_CHECKSUM)])
        {
            [self checkApplicationCheckSumFromCharacteristic:characteristic];
        }

        if (cbCharacteristicUpdationHandler != nil)
        {
            cbCharacteristicUpdationHandler(YES,[commandArray objectAtIndex:0],nil);
            [commandArray removeObjectAtIndex:0];
        }

    }
    else
    {
        if(commandArray.count>0){
            if ([[commandArray objectAtIndex:0] isEqual:@(PROGRAM_ROW)])
            {
                _isWritePacketDataSuccess = NO;
            }
            else if ([[commandArray objectAtIndex:0] isEqual:@(SEND_DATA)])
            {
                _isWritePacketDataSuccess = NO;
            }
            if (cbCharacteristicUpdationHandler != nil)
            {
                cbCharacteristicUpdationHandler(YES,[commandArray objectAtIndex:0],nil);
                [commandArray removeObjectAtIndex:0];
            }
        }
    }
}
if(!isOTA&&!_isSendData){
    NSString *temps=[self getTempData:characteristic];
    NSArray *ss = [temps componentsSeparatedByString:@","];
    NSString *tempWendu =ss[0];
    NSString *tempSymbol = ss[1];

    self.currentDate = [NSDate date];

    NSString *dateString = [_dateformatter stringFromDate:self.currentDate];

    NSLog(@" ==save is time=== :%@",dateString);

    NSDate *logDate = [_dateformatter dateFromString:dateString];
    long logTime= (long)[logDate timeIntervalSince1970];
    if(temps!=nil&&![_bluename isEqualToString:@""]&&_bluename!=nil&&_bluename!=NULL){ //把資料存入到資料庫
    NSString *a = [_userDefaults objectForKey:@"tempUnit"];
    //如果是華氏度的時候一定要把它轉為攝氏度之後再來儲存資料 以便資料的統一性
    if([a isEqualToString:@"°F"]){
        float floatString = [tempWendu floatValue];

        float aa = [_normalUtil convertFahrenheitToCelcius:floatString];

        NSString *ftempWendu =  [NSString stringWithFormat:@"%.1f",aa];
        NSString *ftempSymbol = @"°C";

        [_tempDao saveTempname:_bluename saveTempaddre:_blueaddre saveTempwenduname:ftempSymbol saveTempwendu:ftempWendu saveTemptime:logTime];
        }else{

            [_tempDao saveTempname:_bluename saveTempaddre:_blueaddre saveTempwenduname:tempSymbol saveTempwendu:tempWendu saveTemptime:logTime];
        }

        NSLog(@" ==save is success=== :%ld",logTime);
    }

    //當讀取到資料的時候就要存入資料 以後用來藍芽自動的去連線
    if(_saveAutoOnce){
        [_userDefaults setObject:_bluename forKey:@"autoBlueName"];
        [_userDefaults setObject:_blueaddre forKey:@"autoBlueAddre"];
        _saveAutoOnce = false;
    }

    NSString * tp = [temps stringByAppendingString:@","];

    NSString * tempp = [tp stringByAppendingString:_blueaddre];

    NSDictionary *tempDict = [NSDictionary dictionaryWithObject:tempp forKey:@"temp"];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"tempNofiction" object:nil userInfo:tempDict];
}

}

上面這些程式碼可以不看 我寫的是一些資料的轉換
下面我們可以看下藍芽寫入資料
//也可以自定義主要是給外部呼叫
//傳送資料

-(void)writeBlueValue:(NSString *)value{
_isSendData = TRUE;
[self writeValue:value forCharacteristic:writecharacteristic];
}

/*
這個是給藍芽傳送資料用的
*/
-(void)writeValue:(NSString )value forCharacteristic:(CBCharacteristic )characteristic
{
// NSData *data = [value dataUsingEncoding:4];
NSData *data = [_normalUtil stringToBytes:value];
NSLog(@”send data is:%@:characteristic:%@”,data,writecharacteristic);
//is no write bluetooth data
if(writecharacteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
//send phone on bluetooth data
[selectPeriperal writeValue:data forCharacteristic:writecharacteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[selectPeriperal writeValue:data forCharacteristic:writecharacteristic type:CBCharacteristicWriteWithResponse];

}
//傳送完成後 又要它歸位
_isSendData = FALSE;
NSLog(@"已經向外設%@的特徵值%@寫入資料",selectPeriperal.name,writecharacteristic.description);

}

一般傳送資料都需要用到 NSData資料型別格式下面我有幾個方法
/**
* Method to convert hex to byteArray。這裡是將16進位制轉換為NSData
*/

-(NSMutableData )dataFromHexString:(NSString )string
{
NSMutableData *data = [NSMutableData new];
NSCharacterSet *hexSet = [[NSCharacterSet characterSetWithCharactersInString:@”0123456789ABCDEF “] invertedSet];

// Check whether the string is a valid hex string. Otherwise return empty data
if ([string rangeOfCharacterFromSet:hexSet].location == NSNotFound) {

    string = [string lowercaseString];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i = 0;
    int length = (int)string.length;

    while (i < length-1)
    {
        char c = [string characterAtIndex:i++];

        if (c < '0' || (c > '9' && c < 'a') || c > 'f')
            continue;
        byte_chars[0] = c;
        byte_chars[1] = [string characterAtIndex:i++];
        whole_byte = strtol(byte_chars, NULL, 16);
        [data appendBytes:&whole_byte length:1];
    }
}
return data;

}

還有一種是
//字串轉為陣列
-(NSData )stringToBytes:(NSString )string{
int a = [string intValue];
NSData *aData = [string dataUsingEncoding: NSUTF8StringEncoding];
Byte testByte = (Byte )[aData bytes];
testByte[0] = (Byte)(a>>24&0xff);
testByte[1] = (Byte) (a>>16&0xff);
testByte[2] = (Byte)(a>>8&0xff);
testByte[3] = (Byte)(a&0xff);

NSData *adata = [[NSData alloc] initWithBytes:testByte length:4];

return adata;

}

這些方法比較常用的
好了基本思路就這樣 原始碼 過段時間放上來 。