分离文件后iOS蓝牙的CBCentralManager不扫描设备

时间:2015-01-13 00:00:29

标签: ios objective-c uitableview core-bluetooth

我试图获取附近的蓝牙设备列表并在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

0 个答案:

没有答案