我试图获取附近的蓝牙设备列表并在UItableview中显示它。
最初我使用storyboard在一个视图控制器文件中编写了这个,但是现在我将文件分离到TableViewController,TableDelegate和TableDataSource,并以编程方式编写,我不确定如何将文件拆分为3并让它工作。这就是我到目前为止所拥有的。它编译,但CBCentralManager从不扫描设备并调用centralManagerDidUpdateState函数
原始代码:
MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
@interface MasterViewController ()
@property NSMutableArray *objects;
@end
@implementation MasterViewController
#pragma mark - CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if ([localName length] > 0) {
if (![_foundPeripherals containsObject:peripheral]) {
NSLog(@"Found: %@", localName);
[_foundPeripherals addObject:peripheral];
[_adData addObject:advertisementData];
[_RSSI addObject:RSSI];
[self.tableView reloadData];
//peripheral.delegate = self;
}
}
}
// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
NSArray *services = @[kDFUServiceUUID, kGuinnessServiceUUID, kHeartrateServiceUUID, kBatteryServiceUUID, kDeviceInfoServiceUUID];
NSDictionary *scanOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
[self.centralManager scanForPeripheralsWithServices:services options:scanOptions];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.deviceData = nil;
_foundPeripherals = [[NSMutableArray alloc] init];
_adData = [[NSMutableArray alloc] init];
_RSSI = [[NSMutableArray alloc] init];
CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
self.centralManager = centralManager;
}
- (void)viewWillDisappear:(BOOL)animated {
[_centralManager stopScan];
NSLog(@"Scanning stopped");
[super viewWillDisappear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = self.objects[indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.foundPeripherals count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
CBPeripheral *peripheral=[_foundPeripherals objectAtIndex:indexPath.row];
cell.textLabel.text = peripheral.name;
return cell;
}
@end
新的,分开的代码,不起作用。
TableViewController.m
#import "TableViewController.h"
#import "TableDataSource.h"
#import "TableDelegate.h"
@interface TableViewController () {
TableDataSource *_dataSource;
TableDelegate *_delegate;
}
@end
@implementation TableViewController
- (void)loadView {
self.view = [[UIView alloc] init];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.view = tableView;
_dataSource = [[TableDataSource alloc] init];
_delegate = [[TableDelegate alloc] init];
_delegate.controller = self;
self.tableView.dataSource = _dataSource;
self.tableView.delegate = _delegate;
[self.tableView registerClass: [UITableViewCell class] forCellReuseIdentifier: @"device"];
}
- (void)viewDidLoad {
[super viewDidLoad];
[_dataSource getBluetoothDevices];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"reloadTable"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(checkRes:) name:@"reloadTable" object:nil];
}
-(void)checkRes:(NSNotification *)notification
{
if ([[notification name] isEqualToString:@"reloadTable"])
{
[self.tableView reloadData];
}
}
TableDelegate.h
#import <UIKit/UIKit.h>
@import CoreBluetooth;
@interface TableDelegate : NSObject <UITableViewDelegate, CBCentralManagerDelegate, CBPeripheralDelegate>
@property (nonatomic, weak) UIViewController *controller;
@end
TableDelegate.m
#import "TableDelegate.h"
#import "TableDataSource.h"
#import "DetailViewController.h"
@interface TableDelegate () {
TableDataSource *_dataSource;
}
@end
@implementation TableDelegate
- (instancetype)initWithDataSource:(TableDataSource *)dataSource {
self = [super init];
if (!self) return nil;
_dataSource = dataSource;
return self;
}
// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
NSArray *services = @[kDFUServiceUUID, kGuinnessServiceUUID, kHeartrateServiceUUID, kBatteryServiceUUID, kDeviceInfoServiceUUID];
NSDictionary *scanOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
[_dataSource.centralManager scanForPeripheralsWithServices:services options:scanOptions];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath: indexPath animated: YES];
DetailViewController *detail = [[DetailViewController alloc] init];
[_controller.navigationController pushViewController: detail animated: YES];
}
@end
TableDataSource.m
#import "TableDataSource.h"
#import "TableViewController.h"
#import "TableDelegate.h"
@interface TableDataSource () {
TableDelegate *_delegate;
}
@end
@implementation TableDataSource
- (instancetype)initWithDelegate:(TableDelegate *)delegate {
self = [super init];
if (!self) return nil;
_delegate = delegate;
return self;
}
- (void)getBluetoothDevices
{
_foundPeripherals = [[NSMutableArray alloc] init];
_adData = [[NSMutableArray alloc] init];
_RSSI = [[NSMutableArray alloc] init];
CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:_delegate queue:nil];
self.centralManager = centralManager;
}
// method called whenever you have successfully connected to the BLE peripheral
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if ([localName length] > 0) {
if (![_foundPeripherals containsObject:peripheral]) {
NSLog(@"Found: %@", localName);
[_foundPeripherals addObject:peripheral];
[_adData addObject:advertisementData];
[_RSSI addObject:RSSI];
[[NSNotificationCenter defaultCenter] postNotificationName:@"reloadTable" object:self];
//peripheral.delegate = self;
}
}
}
// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
NSArray *services = @[kDFUServiceUUID, kGuinnessServiceUUID, kHeartrateServiceUUID, kBatteryServiceUUID, kDeviceInfoServiceUUID];
NSDictionary *scanOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
[self.centralManager scanForPeripheralsWithServices:services options:scanOptions];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
[self getBluetoothDevices];
return [self.foundPeripherals count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"device";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
CBPeripheral *peripheral=[_foundPeripherals objectAtIndex:indexPath.row];
cell.textLabel.text = peripheral.name;
return cell;
}
@end