【发布时间】:2015-07-29 13:37:15
【问题描述】:
我现在正在开发一个适用于 BLE、后端服务器和位置的应用程序。我面临一个我不知道如何解决的问题,这就是人们所说的“回调地狱”。 iOS 中的整个 CoreBluetooth 框架都基于委托模式,在您可以使用 CBPeripheral 之前,必须至少进行 3 个回调:
DidConnectToPeripheral
DidDiscoverServices
DidDiscoverCharacteristics
但实际上可能还有更多,您对设备执行的每个操作都会作为对其中一个功能的回调返回。现在,当我想“租用”这个 ble 产品时,我必须连接到它,连接后向服务器发送请求并获取用户的当前位置,之后我必须在蓝牙设备中写入一个值并获得确认.这不会那么困难,但不幸的是,这些阶段中的每一个都是失败的,因此需要添加错误处理。更不用说实现超时了。
我确信我不是唯一一个解决此类问题的人,所以我环顾四周,发现 2 件事可能会有所帮助:
- wwdc 2015 中的 Advanced NSOperations 演讲,但在尝试了 4 天后,似乎代码错误太多。
- Promisekit 但我找不到封装 CoreBluetooth 的方法。
拥有更复杂应用程序的人如何处理这个问题?在 swift 或 objc 中。
一些有问题的示例代码:
-(void)startRentalSessionWithLock:(DORLock *)lock timeOut:(NSTimeInterval)timeout forSuccess:(void (^)(DORRentalSession * session))successBlock failure:(failureBlock_t)failureBlock{
//we set the block to determine what happens
NSAssert(lock.peripheral, @"lock has to have peripheral to connect to");
if (!self.rentalSession) {
self.rentalSession = [[DORRentalSession alloc] initWithLock:nil andSessionDict:@{} active:NO];
}
self.rentalSession.lock = lock;
[self connectToLock:self.rentalSession.lock.peripheral timeOut:timeout completionBlock:^(CBPeripheral *peripheral, NSError *error) {
self.BTConnectionCompleted = nil;
if (!error) {
[[INTULocationManager sharedInstance] requestLocationWithDesiredAccuracy:INTULocationAccuracyHouse timeout:1 delayUntilAuthorized:YES block:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {
if (status == INTULocationStatusSuccess || status == INTULocationStatusTimedOut) {
[self startServerRentalForSessionLockWithUserLocation:currentLocation.coordinate forSuccess:^(DORRentalSession *session) {
if (self.rentalSession.lock.peripheral && self.rentalSession.lock.peripheral.state == CBPeripheralStateConnected) {
[self.rentalSession.lock.peripheral setNotifyValue:YES forCharacteristic:self.rentalSession.lock.charectaristics.sensorCharacteristic];
}else{
//shouldnt come here
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.rentalSession.lock.peripheral.state == CBPeripheralStateConnected) {
!self.rentalSession.lock.open ? [self sendUnlockBLECommandToSessionLock] : nil;
if (successBlock) {
successBlock(session);
}
}else{
[self endCurrentRentalSessionWithLocation:self.rentalSession.lock.latLng andPositionAcc:@(1) Success:^(DORRentalSession *session) {
if (failureBlock) {
failureBlock([[NSError alloc] initWithDomain:DonkeyErrorDomain code:46 userInfo:@{NSLocalizedDescriptionKey:@"Could't connect to lock"}],200);
}
} failure:^(NSError *error, NSInteger httpCode) {
if (failureBlock) {
failureBlock([[NSError alloc] initWithDomain:DonkeyErrorDomain code:45 userInfo:@{NSLocalizedDescriptionKey:@"fatal error"}],200);
}
}];
}
});
} failure:^(NSError *error, NSInteger httpCode) {
if (failureBlock) {
failureBlock(error,httpCode);
}
}];
}else{
NSError *gpsError = [self donkeyGPSErrorWithINTULocationStatus:status];
if (failureBlock) {
failureBlock(gpsError,200);
}
}
}];
}else{
if (failureBlock) {
failureBlock(error,200);
}
}
}];
}
【问题讨论】:
标签: ios objective-c bluetooth callback core-bluetooth