ios开发蓝牙的基本使用

1. 声明一下下

#import <CoreBluetooth/CoreBluetooth.h>

2 初始化在viewdidload 中

self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];

3遵守协议

<CBCentralManagerDelegate,CBPeripheralDelegate>

4一些需要用到的属性

@property (nonatomic, strong) CBCentralManager *centralManager;

@property (nonatomic, strong) CBCharacteristic *writeCMDCharacteristic;

@property (nonatomic, strong) CBPeripheral *connectedPeripheral;

@property (nonatomic, strong) CBService *readWriteService;

@property (nonatomic, strong) NSMutableArray<CBUUID *> *characteristicIDs;

@property (nonatomic, strong) NSMutableArray<CBPeripheral *> *carLocksArray;

@property (nonatomic, strong) CBCharacteristic *readRESCharacteristic;

@property (nonatomic, strong) CBCharacteristic *readWritePasswordCharacteristic;

5 具体代码,发送信息给设备

[self.connectedPeripheral writeValue:[self convertHexStrToData:CMD_UP] forCharacteristic:self.writeCMDCharacteristic type:CBCharacteristicWriteWithoutResponse];

其中CMD_UP 是跟硬件约定好的要发的指令/我这硬件做的是要求发送的信息是16进制的 ,所以得转发,接下来的接受到的依然是16进制的信息,需要转发,方法在文章最后面。

#pragma mark - 字符串与十六进制数据转换

- (NSData *)convertHexStrToData:(NSString *)str

#pragma mark - 懒加载

-(NSMutableArray *)carLocksArray {

if (!_carLocksArray) {

_carLocksArray = [NSMutableArray array];

}

return _carLocksArray;

}

- (NSMutableArray<CBUUID *> *)characteristicIDs {

if (!_characteristicIDs) {

_characteristicIDs = [NSMutableArray array];

for (NSInteger i= 0; i < 6; i ++) {

CBUUID *uuid = [CBUUID UUIDWithString:[NSString stringWithFormat:@"FF0%ld",i+1]];

[_characteristicIDs addObject:uuid];

}

}

return _characteristicIDs;

}

addStateMessage:@"正在搜索‘FF12‘服务..."];

NSLog(@"正在搜索‘FF12‘服务...");

self.connectedPeripheral = peripheral;

[self refreshUIYes];

}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {

[self addStateMessage:[NSString stringWithFormat:@"已断开与%@的连接",peripheral.name]];

NSLog(@"已断开与%@的连接",peripheral.name);

self.connectedPeripheral = nil;

[self refreshUINo];

[self.centralManager connectPeripheral:selectedCarLock options:nil];

[self addStateMessage:[NSString stringWithFormat:@"正在连接 %@...",selectedCarLock.name]];

}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {

[self addStateMessage:[NSString stringWithFormat:@"未能连接上%@",peripheral.name]];

NSLog(@"未能连接上%@",peripheral.name);

[self refreshUINo];

}

#pragma mark - CBPeripheralDelegate

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {

if (error) {

[self addStateMessage:[NSString stringWithFormat:@"code:%ld,发现特征值错误: %@",error.code ,error.localizedDescription]];

NSLog(@"code:%ld,发现特征值错误: %@",error.code ,error.localizedDescription);

return;

}

NSString *res = [self convertDataToHexStr:characteristic.value];

//[self addStateMessage:res];

NSLog(@"res = %@",res);

//电量

NSMutableString *muStr = [NSMutableString stringWithFormat:@"%@",res];

NSString *middleStr = [muStr substringWithRange:NSMakeRange(4, 8)];

NSString *lasterStr = [muStr substringFromIndex:muStr.length-2];

//NSLog(@"result:%@",middleStr);

float batteryLow = [[self convertHexStrToString:middleStr] floatValue]/6000;

NSLog(@"10----%f",batteryLow);

NSLog(@"10----%@",[self convertHexStrToString:middleStr]);

//判断是不是回复的

NSString *topStr = @"";

if (muStr.length > 22) {

topStr = [muStr substringToIndex:22];

}

if ([topStr isEqualToString:@"ffacffffffffffffff2902"]) {//是回复的指令

self.top_rightBtn.userInteractionEnabled = YES;

NSString *lasterTwoStr = [muStr substringFromIndex:muStr.length-2];

NSString *lasterFour_TwoStr = [muStr substringWithRange:NSMakeRange(muStr.length-4, 2)];

if ([lasterTwoStr isEqualToString:@"00"]) {

NSLog(@"=====success");

[self refreshUIYes];

if ([lasterFour_TwoStr isEqualToString:@"00"]) {//关锁

NSLog(@"%@",[NSString stringWithFormat:@"关锁成功-%d",repeatNumThree]);

[self addStateMessage:@"关锁成功"];

deviceStatus = NO;

[self refreshUIYes];

}else{//开锁

NSLog(@"%@",[NSString stringWithFormat:@"开锁成功-%d",repeatNumThree]);

[self addStateMessage:@"开锁成功"];

deviceStatus = YES;

[self refreshUIYes];

}

repeatNumThree = 0;

}else if ([lasterTwoStr isEqualToString:@"01"]) {

if ([lasterFour_TwoStr isEqualToString:@"00"]) {//关锁

NSLog(@"关锁失败");

if (repeatNumThree <= 3) {

repeatNumThree ++;

[self liftUpAction];

}else{

[self addStateMessage:@"关锁失败"];

}

}else{//开

NSLog(@"开锁失败");

if (repeatNumThree <= 3) {

repeatNumThree ++;

[self liftDownAction];

}else{

[self addStateMessage:@"开锁失败"];

}

}

}

}else{

NSLog(@"=====自动回复的指令");

//开关状态

//NSLog(@"%@",lasterStr);

if ([lasterStr isEqualToString:@"43"]) {

//NSLog(@"升起的状态");

[self addStateMessage:@"车锁已升起,请放心"];

deviceStatus = NO;

}else{

//NSLog(@"落下的状态");

[self addStateMessage:@"车锁已经落下,可入位"];

deviceStatus = YES;

}

[self refreshUIYes];

//电池电量

if ([lasterStr isEqualToString:@"43"] || [lasterStr isEqualToString:@"4f"]) {

if (batteryLow <= 0.2) {

self.batteryImg.image = [UIImage imageNamed:@"dian_red"];

}else{

self.batteryImg.image = [UIImage imageNamed:@"dian_man"];

}

self.batteryImg.frame = CGRectMake(2, 2, 92*batteryLow, 26);

}

}

//    // 读取密码

//    if (characteristic == self.readWritePasswordCharacteristic) {

//        NSString *hexPassword = [self convertDataToHexStr:characteristic.value];

//        NSString *decimalPassword = [self convertHexStrToString:hexPassword];

//        [self addStateMessage:[NSString stringWithFormat:@"password = %@",decimalPassword]];

//        NSLog(@"password = %@",decimalPassword);

//

//        if ([self.inputPassword isEqualToString:decimalPassword]) {

//            // 当前点击的是更改设备名称

//            if (self.currentSelectedIndexPath.section == 1 && self.currentSelectedIndexPath.row == 0) {

//                // TODO 点击的是更改设备名称

//            }

//

//            // 当前点击的是更改密码

//            if (self.currentSelectedIndexPath.section == 1 && self.currentSelectedIndexPath.row == 1) {

//                ChangePasswordViewController *changePasswordVC = [[ChangePasswordViewController alloc] initWithNibName:NSStringFromClass([ChangePasswordViewController class]) bundle:nil];

//                changePasswordVC.delegate = self;

//                [self.navigationController pushViewController:changePasswordVC animated:YES];

//            }

//        }else {

//            [self addStateMessage:@"密码输入错误"];

//            NSLog(@"密码输入错误");

//        }

//        return;

//    }

//

//    if (characteristic == self.readRESCharacteristic) {

//        NSString *resString = [self convertDataToHexStr:characteristic.value];

//        [self addStateMessage:[NSString stringWithFormat:@"resString = %@",resString]];

//        NSLog(@"resString = %@",resString);

//

//        if ([resString isEqualToString:RES_SUCCEED_UP]) {

////            [self addStateMessage:@"指令发送成功,设备已升起"];

//            NSLog(@"指令发送成功,设备已升起");

//            self.liftUpButton.enabled = NO;

//            self.liftDownButton.enabled = YES;

//        }

//

//        if ([resString isEqualToString:RES_SUCCEED_DOWN]) {

////            [self addStateMessage:@"指令发送成功,设备已降下"];

//            NSLog(@"指令发送成功,设备已降下");

//            self.liftDownButton.enabled = NO;

//            self.liftUpButton.enabled = YES;

//        }

//

//        if ([resString isEqualToString:RES_FAILURE_UP]) {

////            [self addStateMessage:@"车位锁为能成功升起,可能遇到障碍物"];

//            NSLog(@"车位锁为能成功升起");

//            self.liftUpButton.enabled = NO;

//            self.liftUpButton.enabled = YES;

//        }

//    }

}

-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {

//[self addStateMessage:[NSString stringWithFormat:@"已找到指定服务,扫描特征..."]];

NSLog(@"已找到指定服务,扫描特征...");

for (CBService *service in peripheral.services) {

if ([service.UUID.UUIDString isEqualToString:READ_WRITE_SERVICEID]) {

self.readWriteService = service;

break;

}

}

if (self.readWriteService != nil) {

[self.connectedPeripheral discoverCharacteristics:self.characteristicIDs forService:self.readWriteService];

}

}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {

[self addStateMessage:[NSString stringWithFormat:@"已经链接车位锁,等待发送指令"]];

NSLog(@"已找到相应特征,等待发指令...");

self.writeCMDCharacteristic = [service.characteristics objectAtIndex:0];

self.readRESCharacteristic = [service.characteristics objectAtIndex:1];

self.readWritePasswordCharacteristic = [service.characteristics objectAtIndex:4];

[self.connectedPeripheral setNotifyValue:YES forCharacteristic:self.readRESCharacteristic];

[self.connectedPeripheral setNotifyValue:YES forCharacteristic:self.readWritePasswordCharacteristic];

// self.liftUpButton.enabled = YES;

//self.liftDownButton.enabled = YES;

[self.connectedPeripheral writeValue:[self convertHexStrToData:RECEIVESTATUS] forCharacteristic:self.writeCMDCharacteristic type:CBCharacteristicWriteWithoutResponse];

}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {

[self addStateMessage:[NSString stringWithFormat:@"发送指令已完成,等待结果..."]];

NSLog(@"发送指令已完成,等待结果...");

}

- (void)addStateMessage:(NSString *)message {

NSLog(@"%@",message);

int xStart = 10;

if (bgStatuslab ==nil) {

UIImage *img = [UIImage imageNamed:@"green_icon"];

CGFloat scale = [UIScreen mainScreen].scale;

UIImage *dot9 = [img resizableImageWithCapInsets:(UIEdgeInsets){0/scale,20/scale,5/scale,20/scale} resizingMode:UIImageResizingModeStretch];  //{top/scale,left/scale,bottom/scale,right/scale}  top  left bottom right 表示图片不拉伸的尺寸.

self.status_new_img.image = dot9;

bgStatuslab = [[UILabel alloc] initWithFrame:CGRectMake(xStart, 5, self.status_new_img.frame.size.width - xStart*2, self.status_new_img.frame.size.height - 10)];

bgStatuslab.textAlignment = NSTextAlignmentCenter;

bgStatuslab.textColor = [UIColor whiteColor];

bgStatuslab.font = [UIFont systemFontOfSize:13];

[self.status_new_img addSubview:bgStatuslab];

}

self.status_new_img.frame = CGRectMake(110, 50, [self receiveTextWidthWithString:message] + 30, 30);

bgStatuslab.frame = CGRectMake(xStart, 5, self.status_new_img.frame.size.width - xStart*2, self.status_new_img.frame.size.height - 10);

bgStatuslab.text = message;

}

// 得到文字的宽度

-(int)receiveTextWidthWithString:(NSString *)str

{

CGSize maxWidth = CGSizeMake(MAXFLOAT, 20);

NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:13]};

CGRect rect = [str boundingRectWithSize:maxWidth options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil];

int width = (int)rect.size.width;

return width;

}

#pragma mark - 字符串与十六进制数据转换

- (NSData *)convertHexStrToData:(NSString *)str {

if (!str || [str length] == 0) {

return nil;

}

NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];

NSRange range;

if ([str length] % 2 == 0) {

range = NSMakeRange(0, 2);

} else {

range = NSMakeRange(0, 1);

}

for (NSInteger i = range.location; i < [str length]; i += 2) {

unsigned int anInt;

NSString *hexCharStr = [str substringWithRange:range];

NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];

[scanner scanHexInt:&anInt];

NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];

[hexData appendData:entity];

range.location += range.length;

range.length = 2;

}

NSLog(@"hexdata: %@", hexData);

return hexData;

}

- (NSString *)convertDataToHexStr:(NSData *)data {

if (!data || [data length] == 0) {

return @"";

}

NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];

[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {

unsigned char *dataBytes = (unsigned char*)bytes;

for (NSInteger i = 0; i < byteRange.length; i++) {

NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];

if ([hexStr length] == 2) {

[string appendString:hexStr];

} else {

[string appendFormat:@"0%@", hexStr];

}

}

}];

return string;

}

//16-->10

- (NSString *)convertHexStrToString:(NSString *)str {

if (!str || [str length] == 0) {

return nil;

}

NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];

NSRange range;

if ([str length] % 2 == 0) {

range = NSMakeRange(0, 2);

} else {

range = NSMakeRange(0, 1);

}

for (NSInteger i = range.location; i < [str length]; i += 2) {

unsigned int anInt;

NSString *hexCharStr = [str substringWithRange:range];

NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];

[scanner scanHexInt:&anInt];

NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];

[hexData appendData:entity];

range.location += range.length;

range.length = 2;

}

NSString *string = [[NSString alloc]initWithData:hexData encoding:NSUTF8StringEncoding];

return string;

}

//将NSString转换成十六进制的字符串则可使用如下方式:

- (NSString *)convertStringToHexStr:(NSString *)str {

if (!str || [str length] == 0) {

return @"";

}

NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];

[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {

unsigned char *dataBytes = (unsigned char*)bytes;

for (NSInteger i = 0; i < byteRange.length; i++) {

NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];

if ([hexStr length] == 2) {

[string appendString:hexStr];

} else {

[string appendFormat:@"0%@", hexStr];

}

}

}];

return string;

}

更多的需要跟做硬件的哥们去商议具体怎么沟通.

时间: 2024-10-26 11:27:12

ios开发蓝牙的基本使用的相关文章

iOS开发- 蓝牙后台接收数据(BLE4.0)

最近在做一个蓝牙相关的项目, 需要在应用进入后台, 或者手机属于锁屏状态的情况下, 仍然保持蓝牙连接, 并且能正常接收数据. 本来以后会很麻烦, 但是学习了下..发现就2步而已.简单的不能再简单了. 好了.下面是具体实现办法. 1.在xxx-info.plist文件中, 新建一行  Required background modes , 加入下面两项. App shares data using CoreBluetooth 和  App communicates using CoreBlueto

iOS开发之--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook功能开发汇总

前言 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: 目录 系统应用 系统服务 2.1. 短信与邮件 2.2. 通讯录 2.3. 蓝牙 2.4. 社交 2.5. Game Center 2.6. 应用内购买 2.7. iCloud 2.8. Passbook 1. 系统应用 在开发某些应用时可能希望能够调用iOS系统内置的电话.短信.邮件.浏览

iOS开发 -GameKit蓝牙开发

蓝牙4.0 蓝牙4.0是2012年最新蓝牙版本,是3.0的升级版本:较3.0版本更省电.成本低.3毫秒低延迟.超长有效连接距离.AES-128加密等:通常用在蓝牙耳机.蓝牙音箱等设备上. 蓝牙技术联盟(Bluetooth SIG)2010年7月7日宣布,正式采纳蓝牙4.0核心规范(Bluetooth Core Specification Version 4.0 ),并启动对应的认证计划.会员厂商可以提交其产品进行测试,通过后将获得蓝牙4.0标准认证. 该技术拥有极低的运行和待机功耗,使用一粒纽扣

iOS,蓝牙开发!!--By帮雷

iOS的蓝牙开发大致有以下几种方式. 1 GameKit.framework [只能存在于iOS设备之间,多用于游戏 能搜索到的demo比较多,不确切说名字了,code4app里面就有] 2 CoreBlueTooth.framework [必须要支持蓝牙4.0,且iPhone4以上,即至少4s手机.可与第三方设备交互数据, 官方demo是Temperature Sensor ] 3 ExternalAccessory.framework [可于第三方蓝牙设备交互,但是蓝牙设备必须经过MFI认证

iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总

--系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: 调用系统应用 使用系统服务 短信与邮件 通讯录 蓝牙 社交 Game Center 应用内购买 iCloud Passbook 系统应用 在开发某些应用时可能希望能够调用iOS系统内置的电话.短信.邮件.浏览器应用,此时你可以直接使用UIApplication的OpenUR

iOS开发系列通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开

--系统应用与系统服务 iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务:http://www.jinhusns.com/Products/Download/?type=xcj 调用系统应用 使用系统服务 短信与邮件 通讯录 蓝牙 社交 Game Center 应用内购买 iCloud Passbook 目 录 系统应用 在开发某些应用时可能希望能

iOS开发 之 可穿戴设备 蓝牙4.0 BLE 开发

1 前言 当前有越来越多的可穿戴设备使用了蓝牙4.0 BLE(Bluetooth Low Energy).对于iOS开发而言,Apple之前专门推出CoreBluetooth的Framework来支持BLE的开发.对于硬件开发有了解的朋友应该知道,在之前使用低版本的蓝牙的设备,要连接到iOS设备上,需要注册MFI,拥有MFI协议才能进行相应的开发.如果大家关注我之前对LEGO EV3的研究,就可以发现,EV3是使用了蓝牙2.1,因此需要MFI协议来进行开发. 本文将一步一步讲解如何使用CoreB

iOS开发长文--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总

链接:http://www.cocoachina.com/ios/20150129/11068.html iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: 调用系统应用 使用系统服务 短信与邮件 通讯录 蓝牙 社交 Game Center 应用内购买 iCloud Passbook 系统应用 在开发某些应用时可能希望能够调用iOS系统内置的电话.

iOS开发之蓝牙(一)GameKit

iOS中蓝牙的实现方案 iOS中提供了4个框架用于实现蓝牙连接 GameKit.framework(用法简单)只能用于iOS设备之间的连接,多用于游戏(比如五子棋对战),从iOS7开始过期 MultipeerConnectivity.framework  只能用于iOS设备之间的连接,从iOS7开始引入,主要用于文件共享(仅限于沙盒的文件) ExternalAccessory.framework  可用于第三方蓝牙设备交互,但是蓝牙设备必须经过苹果MFi认证(国内较少) CoreBluetoot