2014-08-30 12 views
14

Mam problem z pobraniem Core Bluetooth do wykrywania urządzeń peryferyjnych na iOS 8. Ten sam kod działa poprawnie na urządzeniu iOS 7. Początkowo myślałem, że będzie to problem z uprawnieniami, ponieważ wykonywałem pewne prace iBeacon i są pewne zmiany w podstawowych uprawnieniach lokalizacji na iOS 8. Nie mogłem jednak znaleźć niczego, co by pomogło w tym. Oto link do przykładowego projektu, który działa dobrze dla mnie na iOS 7, ale nie na iOS 8:iOS 8 Core Bluetooth nie odkrywa urządzeń peryferyjnych

https://github.com/elgreco84/PeripheralScanning

Jeśli uruchomić ten projekt na urządzeniu iOS 7 będzie rejestrować dane reklama dla wielu urządzenia wokół mnie. W systemie iOS 8 jedynym wyjściem, jaki widzę, jest to, że stan centralnego menedżera to "Zasilanie włączone".

+0

możliwy duplikat [Kiedy stan CBCentralManager byłby włączony, ale nadal daje mi ostrzeżenie "brak zasilania włączone"?) (Http://stackoverflow.com/questions/17118534/when-would-cbcentralmanagers- state-ever- być zasilany-na-ale-wciąż-daj-mi-a-nie) –

Odpowiedz

30

Nie można rozpocząć skanowania urządzeń peryferyjnych, dopóki nie zostanie włączony tryb "włączony". Być może na twoim urządzeniu z iOS7 masz szczęście z wyczuciem czasu, ale kod jest nadal nieprawidłowy. Twój centralManagerDidUpdateState: powinny być

- (void)centralManagerDidUpdateState:(CBCentralManager *)central 
{ 
    switch (central.state) 
    { 
     case CBCentralManagerStateUnsupported: 
     { 
      NSLog(@"State: Unsupported"); 
     } break; 

     case CBCentralManagerStateUnauthorized: 
     { 
      NSLog(@"State: Unauthorized"); 
     } break; 

     case CBCentralManagerStatePoweredOff: 
     { 
      NSLog(@"State: Powered Off"); 
     } break; 

     case CBCentralManagerStatePoweredOn: 
     { 
      NSLog(@"State: Powered On"); 
      [self.manager scanForPeripheralsWithServices:nil options:nil]; 
     } break; 

     case CBCentralManagerStateUnknown: 
     { 
      NSLog(@"State: Unknown"); 
     } break; 

     default: 
     { 
     } 

    } 
} 

i usunąć wywołanie scanForPeripheralsWithServices od didFinishLaunchingWithOptions

+2

Dziękuję Tyle. Uratowałeś mnie przed wyrzuceniem mojego HRM przez okno. – Craimasjien

+0

Zrobiłem dokładnie to, ale czasami, nie wszystkie razy, 'didDiscoverPerirectal' nie jest w ogóle wywoływany -_- naprawdę zdezorientowany .. – Zennichimaro

+0

ale dla mnie jego wywołanie didDiscoverPeripheral bardzo bardzo ostatnio w iOS 8, jak napraw to? –

4

wpadłem na tym samym numerze budując bardzo podstawową aplikację skanera BLE. Wymagana metoda "centralManagerDidUpdateState" została dodana. Ale nic nie działało.

Uważam, że problem jest związany z queue. umieścić instancję CBCentralManager w fragmencie dispatch_get_main_queue

Ten kod robi że:

 // BLE Stuff 
      let myCentralManager = CBCentralManager() 

     // Put CentralManager in the main queue 
     required init(coder aDecoder: NSCoder) { 
      super.init(coder: aDecoder) 
      myCentralManager = CBCentralManager(delegate: self, queue: dispatch_get_main_queue()) 

      } 

użyciu domyślnego Widok pojedynczy Xcode uruchomić aplikację. Można umieścić to w pliku ViewController.swift:

import UIKit 
    import CoreBluetooth  

    class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate { 


     // BLE Stuff 
     let myCentralManager = CBCentralManager() 
     var peripheralArray = [CBPeripheral]() // create now empty array. 


     // Put CentralManager in the main queue 
     required init(coder aDecoder: NSCoder) { 
      super.init(coder: aDecoder) 
      myCentralManager = CBCentralManager(delegate: self, queue: dispatch_get_main_queue()) 

     } 



     override func viewDidLoad() { 
      super.viewDidLoad() 
      // Do any additional setup after loading the view, typically from a nib. 

     } 


     override func didReceiveMemoryWarning() { 
      super.didReceiveMemoryWarning() 
      // Dispose of any resources that can be recreated. 
     } 

     // Mark CBCentralManager Methods 

     func centralManagerDidUpdateState(central: CBCentralManager!) { 

      updateStatusLabel("centralManagerDidUpdateState") 


      switch central.state{ 
      case .PoweredOn: 
       updateStatusLabel("poweredOn") 


      case .PoweredOff: 
       updateStatusLabel("Central State PoweredOFF") 

      case .Resetting: 
       updateStatusLabel("Central State Resetting") 

      case .Unauthorized: 
       updateStatusLabel("Central State Unauthorized") 

      case .Unknown: 
       updateStatusLabel("Central State Unknown") 

      case .Unsupported: 
       println("Central State Unsupported") 

      default: 
       println("Central State None Of The Above") 

      } 

     } 

     func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!) { 
        println("Did Discover Peripheral") 
      } 
     } 
1

Moja związany problem został rozwiązany przez aktualizację podpis CBCentralManagerDelegate metoda z

func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) 

do

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) 

Uwaga zróżnicowane nazwa parametr didDiscover\Peripheral.

Należy również zauważyć, że ponieważ nie jest to wymagana metoda delegowania, nie ma żadnego ostrzeżenia o tym, że pierwsza wersja nie była w ogóle powiązana z delegatem i dlatego (oczywiście) nigdy nie zostanie wywołana. Przy wszystkich zmianach składni i przestarzałych nazwach/wersjach/dokumentacjach/tutorialach podstawowych metod, chciałbym, aby Swift miał lepszy sposób mówienia kompilatorowi, do którego próbujesz użyć (ważnej) metody delegowania (oprócz polegania na Auto-thinkletion)