2014-04-10 34 views
4

我是Objective-C和IOS開發人員的新手。 我嘗試用BLE開發應用程序。如何解決Objective-C中的「NSInternalInconsistencyException」錯誤?

我按照DarkBlue,並在viewDidLoadViewController.m

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    self.defaultBTServer = [BTServer defaultBTServer]; 
    self.defaultBTServer.delegate = (id)self; 
    [self.defaultBTServer startScan]; 

} 

添加以下代碼和BTServer是類似下面的代碼:

// 
// BTServer.m 
// DarkBlue 
// 
// Created by chenee on 14-3-26. 
// Copyright (c) 2014年 chenee. All rights reserved. 
// 

#import "BTServer.h" 

@interface BTServer() 


@end 


@implementation BTServer{ 
    BOOL inited; 
    CBCentralManager *myCenter; 
    //state 
    NSInteger scanState; 
    NSInteger connectState; 
    NSInteger serviceState; 
    NSInteger characteristicState; 
    NSInteger readState; 


    eventBlock connectBlock; 

// CBPeripheral *m_Peripheral; 

} 

static BTServer* _defaultBTServer = nil; 
-(NSInteger)getScanState 
{ 
    return scanState; 
} 
-(NSInteger)getConnectState 
{ 
    return connectState; 
} 
-(NSInteger)getServiceState 
{ 
    return serviceState; 
} 
-(NSInteger)getCharacteristicState 
{ 
    return characteristicState; 
} 
-(NSInteger)getReadState 
{ 
    return readState; 
} 


+(BTServer*)defaultBTServer 
{ 
    if (nil == _defaultBTServer) { 
     _defaultBTServer = [[BTServer alloc]init]; 

     [_defaultBTServer initBLE]; 
    } 

    return _defaultBTServer; 
} 

-(void)initBLE 
{ 
    if (inited) { 
     return; 
    } 
    inited = TRUE; 
    self.delegate = nil; 
    self.discoveredPeripherals = [NSMutableArray array]; 
// self.services = [NSMutableArray array]; 
    self.selectPeripheral = nil; 
    connectState = KNOT; 
    connectBlock = nil; 

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerOptionShowPowerAlertKey, @"zStrapRestoreIdentifier",CBCentralManagerOptionRestoreIdentifierKey,nil]; 

    myCenter = [[CBCentralManager alloc] 
          initWithDelegate:self 
          queue:dispatch_queue_create("com.myBLEQueue", NULL) 
          options:options]; // TODO: options 

    NSLog(@"init bt server ........"); 

} 
-(void)finishBLE 
{ 
    //?? 
} 

#pragma mark -- APIs 
-(void)startScan 
{ 
    [self startScan:10]; 
} 
-(void)startScan:(NSInteger)forLastTime 
{ 
    [self.discoveredPeripherals removeAllObjects]; 
    scanState = KING; 

    //0:retrive 
#if 1 
    //method 1: 
    NSArray *atmp = [NSArray arrayWithObjects:[CBUUID UUIDWithString:UUIDPrimaryService],[CBUUID UUIDWithString:UUIDPrimaryService2], nil]; 
    NSArray *retrivedArray = [myCenter retrieveConnectedPeripheralsWithServices:atmp]; 
    NSLog(@"retrivedArray:\n%@",retrivedArray); 

    for (CBPeripheral* peripheral in retrivedArray) { 
     [self addPeripheral:peripheral advertisementData:nil RSSI:nil]; 
    } 

    //method 2: 
// [myCenter retrieveConnectedPeripherals];//XXX: deprecated\ˈdɛprɪˌket\ but still work 

#endif 
    //1: scan 
// NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil]; 
// [myCenter scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@"0xFFA0"]] options:options]; 
    [myCenter scanForPeripheralsWithServices:nil options:nil]; 


    if (forLastTime > 0) { 
//  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(forLastTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
//   [self stopScan]; 
//  }); 
//  [NSTimer scheduledTimerWithTimeInterval:forLastTime target:self selector:@selector(stopScan) userInfo:nil repeats:NO]; 
     [NSObject cancelPreviousPerformRequestsWithTarget:self 
               selector:@selector(stopScan) 
                object:nil]; 
     [self performSelector:@selector(stopScan) 
        withObject:nil 
        afterDelay:forLastTime]; 
    } 
} 
-(void)stopScan:(BOOL)withOutEvent 
{ 

    if (scanState != KING) { 
     return; 
    } 

    NSLog(@"stop scan ..."); 

    scanState = KSUCCESS; 
    [myCenter stopScan]; 

    if(withOutEvent) 
     return; 

    if (self.delegate) { 
     if([(id)self.delegate respondsToSelector:@selector(didStopScan)]){ 
      [self.delegate didStopScan]; 
     } 
    } 
} 
-(void)stopScan 
{ 
    [self stopScan:FALSE]; 
} 
-(void)cancelConnect 
{ 
    if (myCenter && self.selectPeripheral) { 
     if(self.selectPeripheral.state == CBPeripheralStateConnecting){ 
      NSLog(@"timeout cancel connect to peripheral:%@",self.selectPeripheral.name); 

      [myCenter cancelPeripheralConnection:self.selectPeripheral]; 
      connectState = KNOT; 
     } 
    } 
} 
-(void)connect:(PeriperalInfo *)peripheralInfo 
{ 
    NSLog(@"connecting to peripheral:%@",peripheralInfo.peripheral.name); 

    [myCenter connectPeripheral:peripheralInfo.peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey: @YES, CBConnectPeripheralOptionNotifyOnDisconnectionKey: @YES, CBConnectPeripheralOptionNotifyOnNotificationKey: @YES}]; 

    self.selectPeripheral = peripheralInfo.peripheral; 
    connectState = KING; 

// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AUTO_CANCEL_CONNECT_TIMEOUT * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
//  [self cancelConnect]; 
// 
// }); 
// [NSTimer scheduledTimerWithTimeInterval:AUTO_CANCEL_CONNECT_TIMEOUT target:self selector:@selector(cancelConnect) userInfo:nil repeats:NO]; 
    [NSObject cancelPreviousPerformRequestsWithTarget:self 
              selector:@selector(cancelConnect) 
               object:nil]; 
    [self performSelector:@selector(stopScan) 
       withObject:nil 
       afterDelay:AUTO_CANCEL_CONNECT_TIMEOUT]; 
} 

-(void)connect:(PeriperalInfo *)peripheralInfo withFinishCB:(eventBlock)callback 
{ 
    [self connect:peripheralInfo]; 
    connectBlock = callback; 
} 
-(void)disConnect 
{ 
    if(myCenter && self.selectPeripheral){ 
     [myCenter cancelPeripheralConnection:self.selectPeripheral]; 
    } 
} 
-(void)discoverService:(CBService*)service 
{ 
    if(self.selectPeripheral){ 
     characteristicState = KING; 
     self.discoveredSevice = service; 
     [self.selectPeripheral discoverCharacteristics:nil forService:service]; 
    } 

} 
-(void)readValue:(CBCharacteristic*)characteristic 
{ 
    if (readState == KING) { 
     NSLog(@"BTServer: should wait read over"); 
     return; 
    } 
    if (characteristic != nil) { 
     self.selectCharacteristic = characteristic; 
    } 
    readState = KING; 
    [self.selectPeripheral readValueForCharacteristic:self.selectCharacteristic]; 
} 

#pragma mark CBCentralManagerDelegate 
-(void)addPeripheralInfo:(PeriperalInfo *)peripheralInfo 
{ 
    for(int i=0;i<self.discoveredPeripherals.count;i++){ 
     PeriperalInfo *pi = self.discoveredPeripherals[i]; 

     if([peripheralInfo.uuid isEqualToString:pi.uuid]){ 
      [self.discoveredPeripherals replaceObjectAtIndex:i withObject:peripheralInfo]; 
      return; 
     } 
    } 

    [self.discoveredPeripherals addObject:peripheralInfo]; 

    if (self.delegate) { 
     if([(id)self.delegate respondsToSelector:@selector(didFoundPeripheral)]){ 
      [self.delegate didFoundPeripheral]; 
     } 
    } 
} 
-(void)addPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI 
{ 
    PeriperalInfo *pi = [[PeriperalInfo alloc]init]; 

    pi.peripheral = peripheral; 
    pi.uuid = [peripheral.identifier UUIDString]; 
    pi.name = peripheral.name; 
    switch (peripheral.state) { 
     case CBPeripheralStateDisconnected: 
      pi.state = @"disConnected"; 
      break; 
     case CBPeripheralStateConnecting: 
      pi.state = @"connecting"; 
      break; 
     case CBPeripheralStateConnected: 
      pi.state = @"connected"; 
      break; 
     default: 
      break; 
    } 
    // pi.channel = advertisementData objectForKey: 
    if (advertisementData) { 
     pi.localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]; 
     NSArray *array = [advertisementData objectForKey:CBAdvertisementDataServiceUUIDsKey]; 
     pi.serviceUUIDS = [array componentsJoinedByString:@"; "]; 
    } 


    if (RSSI) { 
     pi.RSSI = RSSI; 
    } 

    [self addPeripheralInfo:pi]; 
} 

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 
{ 
// NSLog(@"discover peripheral: %@; advertisementData: %@; RSSI: %@", peripheral, advertisementData, RSSI); 
    NSLog(@"discover peripheral: %@; RSSI: %@", peripheral.name, RSSI); 

    [self addPeripheral:peripheral advertisementData:advertisementData RSSI:RSSI]; 


} 
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral 
{ 
    NSLog(@"didconnect to peripheral: %@",peripheral.name); 

    connectState = KSUCCESS; 
    if (connectBlock) { 
     connectBlock(peripheral,true,nil); 
     connectBlock = nil; 
    } 


    self.selectPeripheral = peripheral; 
    self.selectPeripheral.delegate = self; 
    serviceState = KING; 
    [self.selectPeripheral discoverServices:nil]; 
} 

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error 
{ 
    NSLog(@"didDisConnected peripheral: %@",peripheral.name); 

    connectState = KFAILED; 
    if (connectBlock) { 
     connectBlock(peripheral,false,nil); 
     connectBlock = nil; 
    } 

    if (self.delegate) { 
     if([(id)self.delegate respondsToSelector:@selector(didDisconnect)]){ 
      [self.delegate didDisconnect]; 
     } 
    } 
} 

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error 
{ 
    NSLog(@"DidFailToConnectPeripheral ....."); 
} 



- (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals 
{ 
    NSLog(@"retrive connected peripheral %@",peripherals); 
} 

- (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals 
{ 
    NSLog(@"retrive %@",peripherals); 

} 

- (void)centralManagerDidUpdateState:(CBCentralManager *)central 
{ 
    // Determine the state of the peripheral 
    if ([central state] == CBCentralManagerStatePoweredOff) { 
     NSLog(@"CoreBluetooth BLE hardware is powered off"); 
    } 
    else if ([central state] == CBCentralManagerStatePoweredOn) { 
     NSLog(@"CoreBluetooth BLE hardware is powered on and ready"); 
    } 
    else if ([central state] == CBCentralManagerStateUnauthorized) { 
     NSLog(@"CoreBluetooth BLE state is unauthorized"); 
    } 
    else if ([central state] == CBCentralManagerStateUnknown) { 
     NSLog(@"CoreBluetooth BLE state is unknown"); 
    } 
    else if ([central state] == CBCentralManagerStateUnsupported) { 
     NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform"); 
    } 

} 

- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict 
{ 
    NSLog(@"will restore ...."); 
} 


#pragma mark CBPeripheralDelegate 

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 
{ 
    if (nil == error) { 
     serviceState = KSUCCESS; 
//  NSLog(@"found services:\n%@",peripheral.services); 
    }else{ 
     serviceState = KFAILED; 
     NSLog(@"discover service failed:%@",error); 
    } 
} 

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverIncludedServicesForService:(CBService *)service error:(NSError *)error 
{ 
} 

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error 
{ 
    if (nil == error) { 
     characteristicState = KSUCCESS; 
     self.discoveredSevice = service; 
    }else{ 
     characteristicState = KFAILED; 
     self.discoveredSevice = nil; 
     NSLog(@"discover characteristic failed:%@",error); 
    } 

} 

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 
{ 

} 


- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 
{ 
    if (error){ 
     readState = KFAILED; 
     NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]); 
     return; 
    } 

    readState = KSUCCESS; 
    self.selectCharacteristic = characteristic; 
    if (self.delegate && [(id)self.delegate respondsToSelector:@selector(didReadvalue)]) 
     [self.delegate didReadvalue]; 
} 

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error 
{ 
} 

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 
{ 

} 

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error 
{ 
} 

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 
{ 
} 

- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error 
{ 
} 

- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral 
{ 
} 

- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray *)invalidatedServices 
{ 
} 



@end 

但我得到類似如下的錯誤:

2014-04-10 20:28:24.375 BLE_Running[939:60b] *** Assertion failure in -[CBCentralManager initWithDelegate:queue:options:], /SourceCache/CoreBluetooth/CoreBluetooth-109/CBCentralManager.m:168 
2014-04-10 20:28:24.378 BLE_Running[939:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'State restoration of CBCentralManager is only allowed for applications that have specified the "bluetooth-central" background mode' 
*** First throw call stack: 
(0x2fc51f03 0x3a3e6ce7 0x2fc51dd5 0x305fee2f 0x2f971d23 0x8da9d 0x8d7d1 0x89431 0x32485a53 0x32485811 0x3248c489 0x32489dd9 0x324f3a51 0x324f06e5 0x324eacc9 0x32486c97 0x32485df9 0x324ea405 0x34af3b55 0x34af373f 0x2fc1c83f 0x2fc1c7db 0x2fc1afa7 0x2fb857a9 0x2fb8558b 0x324e962b 0x324e4891 0x906b1 0x3a8e4ab7) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
(lldb) 

我有參考CE上的鏈接similar problem,並添加Required background modes像下面的圖片 enter image description here

但似乎不工作...

是否存在有這種錯誤的任何想法?

在此先感謝。

+0

你可以顯示你放在'所需的背景模式'嗎?你乾淨了嗎? – Larme

+0

對不起...我是Objective-C的新手。我沒有在「所需的背景模式」中放入任何東西。我只添加上述圖片所需的'必需的背景模式'項目。我該怎麼辦 ? – Martin

+0

錯誤消息顯示「指定了」藍牙中央「背景模式」。你是否? – matt

回答

0

希望你照顧一下,不要在test-info.plist中錯誤添加背景鍵。它需要在info.plist中。

相關問題