我有一个 Shearwell 棒式阅读器,它通过 BLE 读取牛标签、绵羊标签和山羊标签。连接 BLE 设备时,设备列表出现在 SDLBluetoothConnectViewController 的 tableView 中,然后消失。我也无法使用 segue 从设备中获取信息。蓝牙图标闪烁 3 次,未与设备配对。谁能看到我找了好几个小时的错误在哪里!!提前致谢!
这是 SDLStickreader.m
// A StickReader is a wrapper for a CBPeripheral that has been discovered using a filter for StickReader UUID.
#import "SDLStickReader.h"
#import "SDLStickReaderManager.h"
#import "SDLStickReaderPrivate.h"
#import "SDLSerialPort.h"
//#import "SDLIdentifier.h"
@interface SDLStickReader () <SerialPortDelegate>
@property (strong, nonatomic) CBPeripheral *peripheral;
@end
@implementation SDLStickReader
static SDLStickReaderManager * _manager;
NSMutableData *_data;
SDLSerialPort *serialPort;
BOOL waitingForConfigInfo = YES;
NSMutableString *configString;
+(SDLStickReaderManager *)manager {
if (nil == _manager) {
_manager = [[SDLStickReaderManager alloc] init];
}
return _manager;
}
+ (instancetype)forPeripheral: (CBPeripheral *)peripheral {
return [[self alloc] initWithPeripheral:peripheral];
}
- (instancetype)initWithPeripheral: (CBPeripheral *)peripheral {
self = [super init];
if (self) {
_detail = @"";
self.peripheral = peripheral;
//peripheral.delegate = self;
__tagReadService = [CBUUID UUIDWithString:SDL_STICKREADER_TAGREAD_UUID];
if (peripheral.state == CBPeripheralStateConnected) {
NSLog(@"periperal is connected");
} else {
NSLog(@"periperal is NOT connected");
}
_data = [[NSMutableData alloc] init];
serialPort = [[SDLSerialPort alloc] initWithPeripheral:peripheral andDelegate:self];
peripheral.delegate = self;
[serialPort open ];
}
return self;
}
-(BOOL)hasPeripheral: (CBPeripheral *)peripheral {
return [self.peripheral isEqual: peripheral];
}
-(NSUUID *)identifier {
return self.peripheral.identifier;
}
-(NSString *)name {
return self.peripheral.name;
}
-(NSString *)description {
return [NSString stringWithFormat: @"Peripheral: %@", self.name];
}
-(NSString *)state {
switch (self.peripheral.state) {
case CBPeripheralStateConnected:
return SDL_STICKREADER_STATE_CONNECTED;
case CBPeripheralStateConnecting:
return SDL_STICKREADER_STATE_CONNECTING;
case CBPeripheralStateDisconnected:
return SDL_STICKREADER_STATE_DISCONNECTED;
}
}
// Every time the peripheral sends new data, it calls the delegate peripheral:didUpdateValueForCharacteristic:error: method. The second argument contains the characteristic that you can read.
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic: (CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(@"Error");
return;
}
if ([self.characteristics containsObject: characteristic.UUID]) {
NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
// Have we got everything we need?
NSUInteger startOfEom = [stringFromData rangeOfString: SDL_STICKREADER_EOM].location;
if (NSNotFound == startOfEom) {
// it is not the EOM so append the data to what we have so far and wait for more.
[_data appendData: characteristic.value];
} else {
// contains EOM, so remove the
NSString *lastPart = [stringFromData substringToIndex:startOfEom];
NSString *message = [[NSString alloc] initWithData: _data encoding:NSUTF8StringEncoding];
if (nil != lastPart && lastPart.length > 0) {
message = [message stringByAppendingString:lastPart];
}
if (nil != self.listener) {
[self.listener stickReader:self didReadTag:message];
}
[_data setLength:0];
}
}
}
// Method that ensures that the CBCentral knows when a notification state for a given characteristic changes. Track it in order to understand when a characteristic state changes (update app values). You should check if the characteristic notification has stopped. If it has, you should disconnect from it:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (![self.characteristics containsObject: characteristic.UUID]) {
return;
}
if (characteristic.isNotifying) {
NSLog(@"Notification began ");
} else {
// Notification has stopped
NSLog(@"Notification stopped ");
//[_manager cancelPeripheralConnection:peripheral];
}
}
/////////////////////////////////////////////////////////////////////////////////////
- (void) port: (SDLSerialPort*) serialPort event : (SPEvent) ev error: (NSInteger)err {
if (SP_EVT_OPEN == ev) {
//NSLog(@"serialPortOpened");
configString = [[NSMutableString alloc] init];
[serialPort write: [@"c\r" dataUsingEncoding: NSUTF8StringEncoding]];
} else {
NSLog(@"serialPortClosed");
}
}
- (void) writeComplete: (SDLSerialPort*) serialPort withError: (NSInteger)err {
NSLog(@"writeComplete");
}
- (void) port: (SDLSerialPort*) serialPort receivedData: (NSData*)data {
if (data.length > 0) {
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString: @"|()#"];
NSString *str = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"receivedData: %@", str);
if ([str hasPrefix: @"Shearwell"]) {
_detail = str;
//NSLog(@"updating: %@", str);
[[SDLStickReader manager] addedShearwellStickReader: self];
} else if (NSNotFound != [str rangeOfCharacterFromSet: charSet].location ) {
// Data
if (waitingForConfigInfo) {
[configString appendString:str];
if (NSNotFound != [configString rangeOfString: @"(cS)"].location) {
// got end of config string, parse config.
NSRange found = [configString rangeOfString: @"#18|"];
if (NSNotFound != found.location) {
NSRange getRange = NSMakeRange(found.location + found.length, 1);
NSString *str = [configString substringWithRange: getRange];
self.eidFormat = [str integerValue];
NSLog(@"StickReader format: %d", self.eidFormat);
}
waitingForConfigInfo = NO;
[serialPort write: [@"v\r" dataUsingEncoding: NSUTF8StringEncoding]];
}
} else {
// Users data
[self.listener stickReader:self didReadData: str];
}
} else {
// Tag
if (nil != self.listener) {
[self.listener stickReader:self didReadTag: str];
}
}
}
}
和我的 SDLBluetoothConnectViewController.m
#import "SDLBluetoothConnectViewController.h"
#import "SDLStickReaderManager.h"
#import "SDLStickReader.h"
#import "SDLViewController.h"
@interface SDLBluetoothConnectViewController () <UITableViewDataSource, UITableViewDelegate, SDLStickReaderManagerListener>
@property (weak, nonatomic) IBOutlet UITableView *stickReaderListView;
@property (strong, nonatomic) IBOutlet UILabel *stickReaderNameLabel;
@property (strong, nonatomic) IBOutlet UILabel *stickReaderDescLabel;
@end
/*
This class starts the process of scanning in the 'viewDidLoad' method by setting the SDLStickReaderManager 'singleton' to self. When the scan button is pressed the SDLStickReaderManager scan is called, and each stick reader found is returned via the listener call. This listener call is used to refresh the table view.
When a user selects a stick reader from the list the StickReader view is started and passed the selected stick reader.
*/
@implementation SDLBluetoothConnectViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.stickReaderListView setDelegate: self];
[self.stickReaderListView setDataSource: self];
[SDLStickReader manager].listener = self;
[self.stickReaderListView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)scanButtonPressed:(id)sender {
[SDLStickReader.manager scan];
}
- (IBAction)cancelButtonPressed:(id)sender {
SDLStickReader.manager.listener = nil;
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)viewWillDisappear:(BOOL)animated {
/*
Every time the view disappears, you should stop the scanning process.
*/
[SDLStickReader.manager stopScan];
}
/////////////////////////////////////////////////////////////////////////////////
/////// Table handling //////////////////////////////////////////////////////////
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *stickReaders = SDLStickReader.manager.discoveredStickReaders;
SDLStickReader * stickReader = [stickReaders objectAtIndex: indexPath.row];
[SDLStickReader.manager stopScan];
[self performSegueWithIdentifier:@"deviceInfoSegue" sender:self];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *stickReaders = SDLStickReader.manager.discoveredStickReaders;
return stickReaders.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * simpleTableIdentifier = @"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: simpleTableIdentifier];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: simpleTableIdentifier];
}
NSArray *stickReaders = SDLStickReader.manager.discoveredStickReaders;
SDLStickReader * stickReader = [stickReaders objectAtIndex: indexPath.row];
NSString *desc = [stickReader name];
cell.textLabel.text = desc;
return cell;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"deviceInfoSegue"]) {
//some additional info here
}
}
////////////////////////////////////////////////////////////////////////////////// /
/// SDLStickReaderManager callbacks ///////////////////////////////////////////////
-(void)stickReader: (SDLStickReader *)stickReader addedToList: (NSArray *)discoveredStickReaders {
//NSLog(@"View StickReaderAdded");
[self.stickReaderListView reloadData];
//[SDLStickReader.manager connect: stickReader];
}
-(void)connectedStickReader: (SDLStickReader *)stickReader {
//NSLog(@"View StickReader connected");
[self.stickReaderListView reloadData];
}
-(void)disconnectedStickReader: (SDLStickReader *)stickReader {
//NSLog(@"View StickReader disconnected");
[self.stickReaderListView reloadData];
}