BabyBluetooth.m 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /*
  2. BabyBluetooth
  3. 简单易用的蓝牙ble库,基于CoreBluetooth 作者:刘彦玮
  4. https://github.com/coolnameismy/BabyBluetooth
  5. */
  6. // Created by 刘彦玮 on 15/3/31.
  7. // Copyright (c) 2015年 刘彦玮. All rights reserved.
  8. #import "BabyBluetooth.h"
  9. @implementation BabyBluetooth{
  10. BabyCentralManager *babyCentralManager;
  11. BabyPeripheralManager *babyPeripheralManager;
  12. BabySpeaker *babySpeaker;
  13. int CENTRAL_MANAGER_INIT_WAIT_TIMES;
  14. NSTimer *timerForStop;
  15. }
  16. //单例模式
  17. + (instancetype)shareBabyBluetooth {
  18. static BabyBluetooth *share = nil;
  19. static dispatch_once_t oneToken;
  20. dispatch_once(&oneToken, ^{
  21. share = [[BabyBluetooth alloc]init];
  22. });
  23. return share;
  24. }
  25. - (instancetype)init {
  26. self = [super init];
  27. if (self) {
  28. //初始化对象
  29. babyCentralManager = [[BabyCentralManager alloc]init];
  30. babySpeaker = [[BabySpeaker alloc]init];
  31. babyCentralManager->babySpeaker = babySpeaker;
  32. babyPeripheralManager = [[BabyPeripheralManager alloc]init];
  33. babyPeripheralManager->babySpeaker = babySpeaker;
  34. }
  35. return self;
  36. }
  37. #pragma mark - babybluetooth的委托
  38. /*
  39. 默认频道的委托
  40. */
  41. //设备状态改变的委托
  42. - (void)setBlockOnCentralManagerDidUpdateState:(void (^)(CBCentralManager *central))block {
  43. [[babySpeaker callback]setBlockOnCentralManagerDidUpdateState:block];
  44. }
  45. //找到Peripherals的委托
  46. - (void)setBlockOnDiscoverToPeripherals:(void (^)(CBCentralManager *central,CBPeripheral *peripheral,NSDictionary *advertisementData, NSNumber *RSSI))block{
  47. [[babySpeaker callback]setBlockOnDiscoverPeripherals:block];
  48. }
  49. //连接Peripherals成功的委托
  50. - (void)setBlockOnConnected:(void (^)(CBCentralManager *central,CBPeripheral *peripheral))block {
  51. [[babySpeaker callback]setBlockOnConnectedPeripheral:block];
  52. }
  53. //连接Peripherals失败的委托
  54. - (void)setBlockOnFailToConnect:(void (^)(CBCentralManager *central,CBPeripheral *peripheral,NSError *error))block {
  55. [[babySpeaker callback]setBlockOnFailToConnect:block];
  56. }
  57. //断开Peripherals的连接
  58. - (void)setBlockOnDisconnect:(void (^)(CBCentralManager *central,CBPeripheral *peripheral,NSError *error))block {
  59. [[babySpeaker callback]setBlockOnDisconnect:block];
  60. }
  61. //设置查找服务回叫
  62. - (void)setBlockOnDiscoverServices:(void (^)(CBPeripheral *peripheral,NSError *error))block {
  63. [[babySpeaker callback]setBlockOnDiscoverServices:block];
  64. }
  65. //设置查找到Characteristics的block
  66. - (void)setBlockOnDiscoverCharacteristics:(void (^)(CBPeripheral *peripheral,CBService *service,NSError *error))block {
  67. [[babySpeaker callback]setBlockOnDiscoverCharacteristics:block];
  68. }
  69. //设置获取到最新Characteristics值的block
  70. - (void)setBlockOnReadValueForCharacteristic:(void (^)(CBPeripheral *peripheral,CBCharacteristic *characteristic,NSError *error))block {
  71. [[babySpeaker callback]setBlockOnReadValueForCharacteristic:block];
  72. }
  73. //设置查找到Characteristics描述的block
  74. - (void)setBlockOnDiscoverDescriptorsForCharacteristic:(void (^)(CBPeripheral *peripheral,CBCharacteristic *service,NSError *error))block {
  75. [[babySpeaker callback]setBlockOnDiscoverDescriptorsForCharacteristic:block];
  76. }
  77. //设置读取到Characteristics描述的值的block
  78. - (void)setBlockOnReadValueForDescriptors:(void (^)(CBPeripheral *peripheral,CBDescriptor *descriptor,NSError *error))block {
  79. [[babySpeaker callback]setBlockOnReadValueForDescriptors:block];
  80. }
  81. //写Characteristic成功后的block
  82. - (void)setBlockOnDidWriteValueForCharacteristic:(void (^)(CBCharacteristic *characteristic,NSError *error))block {
  83. [[babySpeaker callback]setBlockOnDidWriteValueForCharacteristic:block];
  84. }
  85. //写descriptor成功后的block
  86. - (void)setBlockOnDidWriteValueForDescriptor:(void (^)(CBDescriptor *descriptor,NSError *error))block {
  87. [[babySpeaker callback]setBlockOnDidWriteValueForDescriptor:block];
  88. }
  89. //characteristic订阅状态改变的block
  90. - (void)setBlockOnDidUpdateNotificationStateForCharacteristic:(void (^)(CBCharacteristic *characteristic,NSError *error))block {
  91. [[babySpeaker callback]setBlockOnDidUpdateNotificationStateForCharacteristic:block];
  92. }
  93. //读取RSSI的委托
  94. - (void)setBlockOnDidReadRSSI:(void (^)(NSNumber *RSSI,NSError *error))block {
  95. [[babySpeaker callback]setBlockOnDidReadRSSI:block];
  96. }
  97. //discoverIncludedServices的回调,暂时在babybluetooth中无作用
  98. - (void)setBlockOnDidDiscoverIncludedServicesForService:(void (^)(CBService *service,NSError *error))block {
  99. [[babySpeaker callback]setBlockOnDidDiscoverIncludedServicesForService:block];
  100. }
  101. //外设更新名字后的block
  102. - (void)setBlockOnDidUpdateName:(void (^)(CBPeripheral *peripheral))block {
  103. [[babySpeaker callback]setBlockOnDidUpdateName:block];
  104. }
  105. //外设更新服务后的block
  106. - (void)setBlockOnDidModifyServices:(void (^)(CBPeripheral *peripheral,NSArray *invalidatedServices))block {
  107. [[babySpeaker callback]setBlockOnDidModifyServices:block];
  108. }
  109. //设置蓝牙使用的参数参数
  110. - (void)setBabyOptionsWithScanForPeripheralsWithOptions:(NSDictionary *) scanForPeripheralsWithOptions
  111. connectPeripheralWithOptions:(NSDictionary *) connectPeripheralWithOptions
  112. scanForPeripheralsWithServices:(NSArray *)scanForPeripheralsWithServices
  113. discoverWithServices:(NSArray *)discoverWithServices
  114. discoverWithCharacteristics:(NSArray *)discoverWithCharacteristics {
  115. BabyOptions *option = [[BabyOptions alloc]initWithscanForPeripheralsWithOptions:scanForPeripheralsWithOptions connectPeripheralWithOptions:connectPeripheralWithOptions scanForPeripheralsWithServices:scanForPeripheralsWithServices discoverWithServices:discoverWithServices discoverWithCharacteristics:discoverWithCharacteristics];
  116. [[babySpeaker callback]setBabyOptions:option];
  117. }
  118. /*
  119. channel的委托
  120. */
  121. //设备状态改变的委托
  122. - (void)setBlockOnCentralManagerDidUpdateStateAtChannel:(NSString *)channel
  123. block:(void (^)(CBCentralManager *central))block {
  124. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnCentralManagerDidUpdateState:block];
  125. }
  126. //找到Peripherals的委托
  127. - (void)setBlockOnDiscoverToPeripheralsAtChannel:(NSString *)channel
  128. block:(void (^)(CBCentralManager *central,CBPeripheral *peripheral,NSDictionary *advertisementData, NSNumber *RSSI))block {
  129. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnDiscoverPeripherals:block];
  130. }
  131. //连接Peripherals成功的委托
  132. - (void)setBlockOnConnectedAtChannel:(NSString *)channel
  133. block:(void (^)(CBCentralManager *central,CBPeripheral *peripheral))block {
  134. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnConnectedPeripheral:block];
  135. }
  136. //连接Peripherals失败的委托
  137. - (void)setBlockOnFailToConnectAtChannel:(NSString *)channel
  138. block:(void (^)(CBCentralManager *central,CBPeripheral *peripheral,NSError *error))block {
  139. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnFailToConnect:block];
  140. }
  141. //断开Peripherals的连接
  142. - (void)setBlockOnDisconnectAtChannel:(NSString *)channel
  143. block:(void (^)(CBCentralManager *central,CBPeripheral *peripheral,NSError *error))block {
  144. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnDisconnect:block];
  145. }
  146. //设置查找服务回叫
  147. - (void)setBlockOnDiscoverServicesAtChannel:(NSString *)channel
  148. block:(void (^)(CBPeripheral *peripheral,NSError *error))block {
  149. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnDiscoverServices:block];
  150. }
  151. //设置查找到Characteristics的block
  152. - (void)setBlockOnDiscoverCharacteristicsAtChannel:(NSString *)channel
  153. block:(void (^)(CBPeripheral *peripheral,CBService *service,NSError *error))block {
  154. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnDiscoverCharacteristics:block];
  155. }
  156. //设置获取到最新Characteristics值的block
  157. - (void)setBlockOnReadValueForCharacteristicAtChannel:(NSString *)channel
  158. block:(void (^)(CBPeripheral *peripheral,CBCharacteristic *characteristic,NSError *error))block {
  159. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnReadValueForCharacteristic:block];
  160. }
  161. //设置查找到Characteristics描述的block
  162. - (void)setBlockOnDiscoverDescriptorsForCharacteristicAtChannel:(NSString *)channel
  163. block:(void (^)(CBPeripheral *peripheral,CBCharacteristic *service,NSError *error))block {
  164. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnDiscoverDescriptorsForCharacteristic:block];
  165. }
  166. //设置读取到Characteristics描述的值的block
  167. - (void)setBlockOnReadValueForDescriptorsAtChannel:(NSString *)channel
  168. block:(void (^)(CBPeripheral *peripheral,CBDescriptor *descriptor,NSError *error))block {
  169. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnReadValueForDescriptors:block];
  170. }
  171. //写Characteristic成功后的block
  172. - (void)setBlockOnDidWriteValueForCharacteristicAtChannel:(NSString *)channel
  173. block:(void (^)(CBCharacteristic *characteristic,NSError *error))block {
  174. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidWriteValueForCharacteristic:block];
  175. }
  176. //写descriptor成功后的block
  177. - (void)setBlockOnDidWriteValueForDescriptorAtChannel:(NSString *)channel
  178. block:(void (^)(CBDescriptor *descriptor,NSError *error))block {
  179. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidWriteValueForDescriptor:block];
  180. }
  181. //characteristic订阅状态改变的block
  182. - (void)setBlockOnDidUpdateNotificationStateForCharacteristicAtChannel:(NSString *)channel
  183. block:(void (^)(CBCharacteristic *characteristic,NSError *error))block {
  184. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidUpdateNotificationStateForCharacteristic:block];
  185. }
  186. //读取RSSI的委托
  187. - (void)setBlockOnDidReadRSSIAtChannel:(NSString *)channel
  188. block:(void (^)(NSNumber *RSSI,NSError *error))block {
  189. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidReadRSSI:block];
  190. }
  191. //discoverIncludedServices的回调,暂时在babybluetooth中无作用
  192. - (void)setBlockOnDidDiscoverIncludedServicesForServiceAtChannel:(NSString *)channel
  193. block:(void (^)(CBService *service,NSError *error))block {
  194. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidDiscoverIncludedServicesForService:block];
  195. }
  196. //外设更新名字后的block
  197. - (void)setBlockOnDidUpdateNameAtChannel:(NSString *)channel
  198. block:(void (^)(CBPeripheral *peripheral))block {
  199. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidUpdateName:block];
  200. }
  201. //外设更新服务后的block
  202. - (void)setBlockOnDidModifyServicesAtChannel:(NSString *)channel
  203. block:(void (^)(CBPeripheral *peripheral,NSArray *invalidatedServices))block {
  204. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBlockOnDidModifyServices:block];
  205. }
  206. //设置蓝牙运行时的参数
  207. - (void)setBabyOptionsAtChannel:(NSString *)channel
  208. scanForPeripheralsWithOptions:(NSDictionary *) scanForPeripheralsWithOptions
  209. connectPeripheralWithOptions:(NSDictionary *) connectPeripheralWithOptions
  210. scanForPeripheralsWithServices:(NSArray *)scanForPeripheralsWithServices
  211. discoverWithServices:(NSArray *)discoverWithServices
  212. discoverWithCharacteristics:(NSArray *)discoverWithCharacteristics {
  213. BabyOptions *option = [[BabyOptions alloc]initWithscanForPeripheralsWithOptions:scanForPeripheralsWithOptions connectPeripheralWithOptions:connectPeripheralWithOptions scanForPeripheralsWithServices:scanForPeripheralsWithServices discoverWithServices:discoverWithServices discoverWithCharacteristics:discoverWithCharacteristics];
  214. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES]setBabyOptions:option];
  215. }
  216. #pragma mark - babybluetooth filter委托
  217. //设置查找Peripherals的规则
  218. - (void)setFilterOnDiscoverPeripherals:(BOOL (^)(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI))filter {
  219. [[babySpeaker callback]setFilterOnDiscoverPeripherals:filter];
  220. }
  221. //设置连接Peripherals的规则
  222. - (void)setFilterOnConnectToPeripherals:(BOOL (^)(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI))filter {
  223. [[babySpeaker callback]setFilterOnconnectToPeripherals:filter];
  224. }
  225. //设置查找Peripherals的规则
  226. - (void)setFilterOnDiscoverPeripheralsAtChannel:(NSString *)channel
  227. filter:(BOOL (^)(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI))filter {
  228. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setFilterOnDiscoverPeripherals:filter];
  229. }
  230. //设置连接Peripherals的规则
  231. - (void)setFilterOnConnectToPeripheralsAtChannel:(NSString *)channel
  232. filter:(BOOL (^)(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI))filter {
  233. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setFilterOnconnectToPeripherals:filter];
  234. }
  235. #pragma mark - babybluetooth Special
  236. //babyBluettooth cancelScan方法调用后的回调
  237. - (void)setBlockOnCancelScanBlock:(void(^)(CBCentralManager *centralManager))block {
  238. [[babySpeaker callback]setBlockOnCancelScan:block];
  239. }
  240. //babyBluettooth cancelAllPeripheralsConnectionBlock 方法调用后的回调
  241. - (void)setBlockOnCancelAllPeripheralsConnectionBlock:(void(^)(CBCentralManager *centralManager))block{
  242. [[babySpeaker callback]setBlockOnCancelAllPeripheralsConnection:block];
  243. }
  244. //babyBluettooth cancelScan方法调用后的回调
  245. - (void)setBlockOnCancelScanBlockAtChannel:(NSString *)channel
  246. block:(void(^)(CBCentralManager *centralManager))block {
  247. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnCancelScan:block];
  248. }
  249. //babyBluettooth cancelAllPeripheralsConnectionBlock 方法调用后的回调
  250. - (void)setBlockOnCancelAllPeripheralsConnectionBlockAtChannel:(NSString *)channel
  251. block:(void(^)(CBCentralManager *centralManager))block {
  252. [[babySpeaker callbackOnChnnel:channel createWhenNotExist:YES] setBlockOnCancelAllPeripheralsConnection:block];
  253. }
  254. #pragma mark - 链式函数
  255. //查找Peripherals
  256. - (BabyBluetooth *(^)()) scanForPeripherals {
  257. return ^BabyBluetooth *() {
  258. [babyCentralManager->pocket setObject:@"YES" forKey:@"needScanForPeripherals"];
  259. return self;
  260. };
  261. }
  262. //连接Peripherals
  263. - (BabyBluetooth *(^)()) connectToPeripherals {
  264. return ^BabyBluetooth *() {
  265. [babyCentralManager->pocket setObject:@"YES" forKey:@"needConnectPeripheral"];
  266. return self;
  267. };
  268. }
  269. //发现Services
  270. - (BabyBluetooth *(^)()) discoverServices {
  271. return ^BabyBluetooth *() {
  272. [babyCentralManager->pocket setObject:@"YES" forKey:@"needDiscoverServices"];
  273. return self;
  274. };
  275. }
  276. //获取Characteristics
  277. - (BabyBluetooth *(^)()) discoverCharacteristics {
  278. return ^BabyBluetooth *() {
  279. [babyCentralManager->pocket setObject:@"YES" forKey:@"needDiscoverCharacteristics"];
  280. return self;
  281. };
  282. }
  283. //更新Characteristics的值
  284. - (BabyBluetooth *(^)()) readValueForCharacteristic {
  285. return ^BabyBluetooth *() {
  286. [babyCentralManager->pocket setObject:@"YES" forKey:@"needReadValueForCharacteristic"];
  287. return self;
  288. };
  289. }
  290. //设置查找到Descriptors名称的block
  291. - (BabyBluetooth *(^)()) discoverDescriptorsForCharacteristic {
  292. return ^BabyBluetooth *() {
  293. [babyCentralManager->pocket setObject:@"YES" forKey:@"needDiscoverDescriptorsForCharacteristic"];
  294. return self;
  295. };
  296. }
  297. //设置读取到Descriptors值的block
  298. - (BabyBluetooth *(^)()) readValueForDescriptors {
  299. return ^BabyBluetooth *() {
  300. [babyCentralManager->pocket setObject:@"YES" forKey:@"needReadValueForDescriptors"];
  301. return self;
  302. };
  303. }
  304. //开始并执行
  305. - (BabyBluetooth *(^)()) begin {
  306. return ^BabyBluetooth *() {
  307. //取消未执行的stop定时任务
  308. [timerForStop invalidate];
  309. dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  310. [self resetSeriseParmeter];
  311. //处理链式函数缓存的数据
  312. if ([[babyCentralManager->pocket valueForKey:@"needScanForPeripherals"] isEqualToString:@"YES"]) {
  313. babyCentralManager->needScanForPeripherals = YES;
  314. }
  315. if ([[babyCentralManager->pocket valueForKey:@"needConnectPeripheral"] isEqualToString:@"YES"]) {
  316. babyCentralManager->needConnectPeripheral = YES;
  317. }
  318. if ([[babyCentralManager->pocket valueForKey:@"needDiscoverServices"] isEqualToString:@"YES"]) {
  319. babyCentralManager->needDiscoverServices = YES;
  320. }
  321. if ([[babyCentralManager->pocket valueForKey:@"needDiscoverCharacteristics"] isEqualToString:@"YES"]) {
  322. babyCentralManager->needDiscoverCharacteristics = YES;
  323. }
  324. if ([[babyCentralManager->pocket valueForKey:@"needReadValueForCharacteristic"] isEqualToString:@"YES"]) {
  325. babyCentralManager->needReadValueForCharacteristic = YES;
  326. }
  327. if ([[babyCentralManager->pocket valueForKey:@"needDiscoverDescriptorsForCharacteristic"] isEqualToString:@"YES"]) {
  328. babyCentralManager->needDiscoverDescriptorsForCharacteristic = YES;
  329. }
  330. if ([[babyCentralManager->pocket valueForKey:@"needReadValueForDescriptors"] isEqualToString:@"YES"]) {
  331. babyCentralManager->needReadValueForDescriptors = YES;
  332. }
  333. //调整委托方法的channel,如果没设置默认为缺省频道
  334. NSString *channel = [babyCentralManager->pocket valueForKey:@"channel"];
  335. [babySpeaker switchChannel:channel];
  336. //缓存的peripheral
  337. CBPeripheral *cachedPeripheral = [babyCentralManager->pocket valueForKey:NSStringFromClass([CBPeripheral class])];
  338. //校验series合法性
  339. [self validateProcess];
  340. //清空pocjet
  341. babyCentralManager->pocket = [[NSMutableDictionary alloc]init];
  342. //开始扫描或连接设备
  343. [self start:cachedPeripheral];
  344. });
  345. return self;
  346. };
  347. }
  348. //私有方法,扫描或连接设备
  349. - (void)start:(CBPeripheral *)cachedPeripheral {
  350. if (babyCentralManager->centralManager.state == CBCentralManagerStatePoweredOn) {
  351. CENTRAL_MANAGER_INIT_WAIT_TIMES = 0;
  352. //扫描后连接
  353. if (babyCentralManager->needScanForPeripherals) {
  354. //开始扫描peripherals
  355. [babyCentralManager scanPeripherals];
  356. }
  357. //直接连接
  358. else {
  359. if (cachedPeripheral) {
  360. [babyCentralManager connectToPeripheral:cachedPeripheral];
  361. }
  362. }
  363. return;
  364. }
  365. //尝试重新等待CBCentralManager打开
  366. CENTRAL_MANAGER_INIT_WAIT_TIMES ++;
  367. if (CENTRAL_MANAGER_INIT_WAIT_TIMES >= KBABY_CENTRAL_MANAGER_INIT_WAIT_TIMES ) {
  368. BabyLog(@">>> 第%d次等待CBCentralManager 打开任然失败,请检查你蓝牙使用权限或检查设备问题。",CENTRAL_MANAGER_INIT_WAIT_TIMES);
  369. return;
  370. //[NSException raise:@"CBCentralManager打开异常" format:@"尝试等待打开CBCentralManager5次,但任未能打开"];
  371. }
  372. dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, KBABY_CENTRAL_MANAGER_INIT_WAIT_SECOND * NSEC_PER_SEC);
  373. dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  374. [self start:cachedPeripheral];
  375. });
  376. BabyLog(@">>> 第%d次等待CBCentralManager打开",CENTRAL_MANAGER_INIT_WAIT_TIMES);
  377. }
  378. //sec秒后停止
  379. - (BabyBluetooth *(^)(int sec)) stop {
  380. return ^BabyBluetooth *(int sec) {
  381. BabyLog(@">>> stop in %d sec",sec);
  382. //听见定时器执行babyStop
  383. timerForStop = [NSTimer timerWithTimeInterval:sec target:self selector:@selector(babyStop) userInfo:nil repeats:NO];
  384. [timerForStop setFireDate: [[NSDate date]dateByAddingTimeInterval:sec]];
  385. [[NSRunLoop currentRunLoop] addTimer:timerForStop forMode:NSRunLoopCommonModes];
  386. return self;
  387. };
  388. }
  389. //私有方法,停止扫描和断开连接,清空pocket
  390. - (void)babyStop {
  391. BabyLog(@">>>did stop");
  392. [timerForStop invalidate];
  393. [self resetSeriseParmeter];
  394. babyCentralManager->pocket = [[NSMutableDictionary alloc]init];
  395. //停止扫描,断开连接
  396. [babyCentralManager cancelScan];
  397. [babyCentralManager cancelAllPeripheralsConnection];
  398. }
  399. //重置串行方法参数
  400. - (void)resetSeriseParmeter {
  401. babyCentralManager->needScanForPeripherals = NO;
  402. babyCentralManager->needConnectPeripheral = NO;
  403. babyCentralManager->needDiscoverServices = NO;
  404. babyCentralManager->needDiscoverCharacteristics = NO;
  405. babyCentralManager->needReadValueForCharacteristic = NO;
  406. babyCentralManager->needDiscoverDescriptorsForCharacteristic = NO;
  407. babyCentralManager->needReadValueForDescriptors = NO;
  408. }
  409. //持有对象
  410. - (BabyBluetooth *(^)(id obj)) having {
  411. return ^(id obj) {
  412. [babyCentralManager->pocket setObject:obj forKey:NSStringFromClass([obj class])];
  413. return self;
  414. };
  415. }
  416. //切换委托频道
  417. - (BabyBluetooth *(^)(NSString *channel)) channel {
  418. return ^BabyBluetooth *(NSString *channel) {
  419. //先缓存数据,到begin方法统一处理
  420. [babyCentralManager->pocket setValue:channel forKey:@"channel"];
  421. return self;
  422. };
  423. }
  424. - (void)validateProcess {
  425. NSMutableArray *faildReason = [[NSMutableArray alloc]init];
  426. //规则:不执行discoverDescriptorsForCharacteristic()时,不能执行readValueForDescriptors()
  427. if (!babyCentralManager->needDiscoverDescriptorsForCharacteristic) {
  428. if (babyCentralManager->needReadValueForDescriptors) {
  429. [faildReason addObject:@"未执行discoverDescriptorsForCharacteristic()不能执行readValueForDescriptors()"];
  430. }
  431. }
  432. //规则:不执行discoverCharacteristics()时,不能执行readValueForCharacteristic()或者是discoverDescriptorsForCharacteristic()
  433. if (!babyCentralManager->needDiscoverCharacteristics) {
  434. if (babyCentralManager->needReadValueForCharacteristic||babyCentralManager->needDiscoverDescriptorsForCharacteristic) {
  435. [faildReason addObject:@"未执行discoverCharacteristics()不能执行readValueForCharacteristic()或discoverDescriptorsForCharacteristic()"];
  436. }
  437. }
  438. //规则: 不执行discoverServices()不能执行discoverCharacteristics()、readValueForCharacteristic()、discoverDescriptorsForCharacteristic()、readValueForDescriptors()
  439. if (!babyCentralManager->needDiscoverServices) {
  440. if (babyCentralManager->needDiscoverCharacteristics||babyCentralManager->needDiscoverDescriptorsForCharacteristic ||babyCentralManager->needReadValueForCharacteristic ||babyCentralManager->needReadValueForDescriptors) {
  441. [faildReason addObject:@"未执行discoverServices()不能执行discoverCharacteristics()、readValueForCharacteristic()、discoverDescriptorsForCharacteristic()、readValueForDescriptors()"];
  442. }
  443. }
  444. //规则:不执行connectToPeripherals()时,不能执行discoverServices()
  445. if(!babyCentralManager->needConnectPeripheral) {
  446. if (babyCentralManager->needDiscoverServices) {
  447. [faildReason addObject:@"未执行connectToPeripherals()不能执行discoverServices()"];
  448. }
  449. }
  450. //规则:不执行needScanForPeripherals(),那么执行connectToPeripheral()方法时必须用having(peripheral)传入peripheral实例
  451. if (!babyCentralManager->needScanForPeripherals) {
  452. CBPeripheral *peripheral = [babyCentralManager->pocket valueForKey:NSStringFromClass([CBPeripheral class])];
  453. if (!peripheral) {
  454. [faildReason addObject:@"若不执行scanForPeripherals()方法,则必须执行connectToPeripheral方法并且需要传入参数(CBPeripheral *)peripheral"];
  455. }
  456. }
  457. //抛出异常
  458. if ([faildReason lastObject]) {
  459. NSException *e = [NSException exceptionWithName:@"BadyBluetooth usage exception" reason:[faildReason lastObject] userInfo:nil];
  460. @throw e;
  461. }
  462. }
  463. - (BabyBluetooth *) and {
  464. return self;
  465. }
  466. - (BabyBluetooth *) then {
  467. return self;
  468. }
  469. - (BabyBluetooth *) with {
  470. return self;
  471. }
  472. - (BabyBluetooth *(^)()) enjoy {
  473. return ^BabyBluetooth *(int sec) {
  474. self.connectToPeripherals().discoverServices().discoverCharacteristics()
  475. .readValueForCharacteristic().discoverDescriptorsForCharacteristic().readValueForDescriptors().begin();
  476. return self;
  477. };
  478. }
  479. #pragma mark - 工具方法
  480. //断开连接
  481. - (void)cancelPeripheralConnection:(CBPeripheral *)peripheral {
  482. [babyCentralManager cancelPeripheralConnection:peripheral];
  483. }
  484. //断开所有连接
  485. - (void)cancelAllPeripheralsConnection {
  486. [babyCentralManager cancelAllPeripheralsConnection];
  487. }
  488. //停止扫描
  489. - (void)cancelScan{
  490. [babyCentralManager cancelScan];
  491. }
  492. //读取Characteristic的详细信息
  493. - (BabyBluetooth *(^)(CBPeripheral *peripheral,CBCharacteristic *characteristic)) characteristicDetails {
  494. //切换频道
  495. [babySpeaker switchChannel:[babyCentralManager->pocket valueForKey:@"channel"]];
  496. babyCentralManager->pocket = [[NSMutableDictionary alloc]init];
  497. return ^(CBPeripheral *peripheral,CBCharacteristic *characteristic) {
  498. //判断连接状态
  499. if (peripheral.state == CBPeripheralStateConnected) {
  500. self->babyCentralManager->oneReadValueForDescriptors = YES;
  501. [peripheral readValueForCharacteristic:characteristic];
  502. [peripheral discoverDescriptorsForCharacteristic:characteristic];
  503. }
  504. else {
  505. BabyLog(@"!!!设备当前处于非连接状态");
  506. }
  507. return self;
  508. };
  509. }
  510. - (void)notify:(CBPeripheral *)peripheral
  511. characteristic:(CBCharacteristic *)characteristic
  512. block:(void(^)(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error))block {
  513. //设置通知
  514. [peripheral setNotifyValue:YES forCharacteristic:characteristic];
  515. [babySpeaker addNotifyCallback:characteristic withBlock:block];
  516. }
  517. - (void)cancelNotify:(CBPeripheral *)peripheral
  518. characteristic:(CBCharacteristic *)characteristic {
  519. [peripheral setNotifyValue:NO forCharacteristic:characteristic];
  520. [babySpeaker removeNotifyCallback:characteristic];
  521. }
  522. //获取当前连接的peripherals
  523. - (NSArray *)findConnectedPeripherals {
  524. return [babyCentralManager findConnectedPeripherals];
  525. }
  526. //获取当前连接的peripheral
  527. - (CBPeripheral *)findConnectedPeripheral:(NSString *)peripheralName {
  528. return [babyCentralManager findConnectedPeripheral:peripheralName];
  529. }
  530. //获取当前corebluetooth的centralManager对象
  531. - (CBCentralManager *)centralManager {
  532. return babyCentralManager->centralManager;
  533. }
  534. /**
  535. 添加断开自动重连的外设
  536. */
  537. - (void)AutoReconnect:(CBPeripheral *)peripheral{
  538. [babyCentralManager sometimes_ever:peripheral];
  539. }
  540. /**
  541. 删除断开自动重连的外设
  542. */
  543. - (void)AutoReconnectCancel:(CBPeripheral *)peripheral{
  544. [babyCentralManager sometimes_never:peripheral];
  545. }
  546. - (CBPeripheral *)retrievePeripheralWithUUIDString:(NSString *)UUIDString {
  547. CBPeripheral *p = nil;
  548. @try {
  549. NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:UUIDString];
  550. p = [self.centralManager retrievePeripheralsWithIdentifiers:@[uuid]][0];
  551. } @catch (NSException *exception) {
  552. BabyLog(@">>> retrievePeripheralWithUUIDString error:%@",exception)
  553. } @finally {
  554. }
  555. return p;
  556. }
  557. #pragma mark - peripheral model
  558. //进入外设模式
  559. - (CBPeripheralManager *)peripheralManager {
  560. return babyPeripheralManager.peripheralManager;
  561. }
  562. - (BabyPeripheralManager *(^)()) bePeripheral {
  563. return ^BabyPeripheralManager* () {
  564. return babyPeripheralManager;
  565. };
  566. }
  567. - (BabyPeripheralManager *(^)(NSString *localName)) bePeripheralWithName {
  568. return ^BabyPeripheralManager* (NSString *localName) {
  569. babyPeripheralManager.localName = localName;
  570. return babyPeripheralManager;
  571. };
  572. }
  573. - (void)peripheralModelBlockOnPeripheralManagerDidUpdateState:(void(^)(CBPeripheralManager *peripheral))block {
  574. [[babySpeaker callback]setBlockOnPeripheralModelDidUpdateState:block];
  575. }
  576. - (void)peripheralModelBlockOnDidAddService:(void(^)(CBPeripheralManager *peripheral,CBService *service,NSError *error))block {
  577. [[babySpeaker callback]setBlockOnPeripheralModelDidAddService:block];
  578. }
  579. - (void)peripheralModelBlockOnDidStartAdvertising:(void(^)(CBPeripheralManager *peripheral,NSError *error))block {
  580. [[babySpeaker callback]setBlockOnPeripheralModelDidStartAdvertising:block];
  581. }
  582. - (void)peripheralModelBlockOnDidReceiveReadRequest:(void(^)(CBPeripheralManager *peripheral,CBATTRequest *request))block {
  583. [[babySpeaker callback]setBlockOnPeripheralModelDidReceiveReadRequest:block];
  584. }
  585. - (void)peripheralModelBlockOnDidReceiveWriteRequests:(void(^)(CBPeripheralManager *peripheral,NSArray *requests))block {
  586. [[babySpeaker callback]setBlockOnPeripheralModelDidReceiveWriteRequests:block];
  587. }
  588. - (void)peripheralModelBlockOnDidSubscribeToCharacteristic:(void(^)(CBPeripheralManager *peripheral,CBCentral *central,CBCharacteristic *characteristic))block {
  589. [[babySpeaker callback]setBlockOnPeripheralModelDidSubscribeToCharacteristic:block];
  590. }
  591. - (void)peripheralModelBlockOnDidUnSubscribeToCharacteristic:(void(^)(CBPeripheralManager *peripheral,CBCentral *central,CBCharacteristic *characteristic))block {
  592. [[babySpeaker callback]setBlockOnPeripheralModelDidUnSubscribeToCharacteristic:block];
  593. }
  594. @end