2016-08-17 2 views
1

Итак, я только начал работать с XCode (v7.3) с использованием языка Swift (v2.2), и я пытаюсь написать одностраничное приложение, которое будет подключаться к целевой BLE устройства, нажав кнопку.Доступ к кнопкам ViewController в классе BluetoothManagerDelegate

Я последовал краткий учебник по рамках основной Bluetooth на следующем веб-сайте: http://hatemfaheem.blogspot.com/2014/12/how-would-you-scan-for-nearby-ble.html

, который был мне создать следующую структуру класса:

class BLEManager{ 
    var centralManager:CBCentralManager 
    var bleHandler:BLEHandler 
    init() { 
     self.bleHandler = BLEHandler() 
     self.centralManager = CBCentralManager(delegate: self.bleHandler, queue: nil 
    } 
} 

class BLEHandler : NSObject, CBCentralManagerDelegate { 
    override init() { 
     super.init() 
    } 
    func CentralManagerDidUpdateState(central: CBCentralManager) { 
     var status:String 
     switch(central.state) { 
     case .PoweredOn 
      status = "Powered On" 
      //ble_show() 
     case .PoweredOff 
      status = "Powered Off" 
      //ble_hide() 
     }//Note: several cases have been omitted to reduce length 
     print(status) 
    } 
} 

var bleManager = BLEManager() 

После введения этих определений классов и объявить экземпляр класс BLEManager внутри класса ViewController моего файла ViewController.swift, я могу увидеть строки «Powered On» и «Powered Off», отображаемые на консоли, когда я включаю и выключаю Bluetooth на своем iPhone во время запуска приложения.

Проблема в том, что я получаю сообщение об ошибке, когда вызываю функции в приведенном выше коде с именем «ble_show()» и «ble_hide» (поэтому они закомментированы). Я предполагаю, что проблема заключается в том, что эти функции являются частью всеобъемлющего класса ViewController, и вы не можете просто вызвать эти функции изнутри вложенного класса: BLEHandler.

Функции ble_show() и ble_hide() просто устанавливают флажок «скрытый» для кнопки, чтобы открыть ее пользователю. Я хочу, чтобы эти кнопки стали доступными только тогда, когда у пользователя включен Bluetooth. Поэтому классу BLEHandler нужно как-то обращаться к этим кнопкам, которые объявлены в классе ViewController, но я, похоже, не понимаю, как это сделать. Я попытался переместить все объявления функций и декларации UIButton внутри класса BLEHandler, но XCode действительно не понравилось, когда я это сделал.

Часть моей проблемы заключается в том, что я изучаю Swift, XCode и базовую инфраструктуру Bluetooth в одно и то же время, поэтому, если бы кто-нибудь мог объяснить, как выполнить то, что я пытаюсь как можно тщательнее, что было бы очень полезно , Я использую программирование в среде с простой функцией main(), а не с использованием класса как main() (именно так я сейчас рассматриваю класс ViewController).

Если я правильно понял, CBCentralManagerDelegate регистрирует часть моего кода на событие, которое вызывает функцию-член CentralManagerDidUpdateState(), когда происходит изменение состояния Bluetooth. Но как я могу сказать моему ViewController что-то делать, когда происходят эти события?

ответ

1

Отделив диспетчер Bluetooth от контроллера вашего вида (что является хорошим дизайном), вы не можете напрямую обновлять элементы в своем контроллере просмотра. Вы можете использовать NSNotification или протокол/делегат, чтобы уведомить контроллер вида о состоянии состояния Bluetooth.

Поскольку может быть много объектов, интересующихся событиями Bluetooth, в этом случае я бы использовал NSNotification.

В классе ViewController, вы можете зарегистрировать наблюдателя для конкретного уведомления:

override func viewDidLoad() { 
    super.viewDidLoad() 

    let notificationCenter = NSNotificationCenter.defaultCenter() 

    notificationCenter.addObserver(self, selector: #selector(ViewController.bluetoothChanged(_:)), name: "bleStateChange", object: nil) 
} 

@objc func bluetoothChanged(notification: NSNotification) { 

    if let status = notification.userInfo["statusString"] as? String { 
     print("Bluetooth status = \(status)") 
    } 
} 

В вашей BLEManager вам необходимо отправить уведомление:

func CentralManagerDidUpdateState(central: CBCentralManager) { 
    var status:String 
    switch(central.state) { 
     case .PoweredOn 
      status = "Powered On" 
      //ble_show() 
     case .PoweredOff 
      status = "Powered Off" 
      //ble_hide() 
    }//Note: several cases have been omitted to reduce length 
    print(status) 
    let notificationCenter = NSNotificationCenter.defaultCenter() 
    let userInfo = ["statusString":"powered off","centralState":central.state.rawValue] as [String:AnyObject] 
    notificationCenter.postNotificationName("bleStateChange", object: nil, userInfo: userInfo) 
} 
+0

Так я добавил код, который вы обеспечил и создал несколько ошибок. Он хочет, чтобы я положил '!' после 'userInfo' в строке: 'if let status = notification.userInfo [" statusString "] as? String {'и он имеет проблему с 'aDict' (использование неразрешенного идентификатора) в строке:' notificationCenter.postNotificationName ("bleStateChange", object: nil, userInfo: aDict) '.Поскольку я действительно не понимаю, что происходит в этом коде, было бы полезно предоставить некоторые подробности о том, что здесь происходит – marco

+0

Думаю, что я понял это сейчас. Я заменил «aDict» на userInfo (объявлен в строке выше) после того, как увидел, что это неиспользуемый словарь, и теперь я могу получить поведение, которое я хотел, с помощью инструкции switch в функции bluetoothChanged(). Спасибо вам за помощь. – marco

+0

Извините, это была ошибка вырезания/вставки с моей игровой площадки. – Paulw11

Смежные вопросы