CBCentralManager State изначально регистрируется как .unknown - PullRequest
0 голосов
/ 04 декабря 2018

Я построил свой собственный кокопод.Существует общедоступная функция activateBluetooth(), позволяющая разработчику легко запускать свои соединения Bluetooth.Вот как выглядит этот модуль:

import Foundation
import CoreBluetooth

public class Service: NSObject, CBCentralManagerDelegate {

    public static let shared = Service()
    private lazy var centralManager: CBCentralManager = {
         return CBCentralManager(delegate: self, queue: nil)
    }()

    private override init() {
         super.init()
    }

    public func activateBlutooth(completion: () -> Void) {
        centralManagerDidUpdateState(centralManager)
        completion()
     }

    public func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .unknown:
            NSLog("unknown")
        case .resetting:
            NSLog("resetting")
        case .unsupported:
            NSLog("unsupporting")
        case .unauthorized:
            NSLog("unauthorized")
        case .poweredOn:
            NSLog("poweredOn")
        case .poweredOff:
            NSLog("poweredOff")
        }
    }
}

В моем приложении я хочу вызвать activateBluetooth(), а затем сделать что-то в обработчике завершения.Вот как выглядит ViewController:

import UIKit
import Toolkit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        Service.shared.delegate = self
        Service.shared.activateBlutooth {
            //Do something here, currently the state is unknown
            //Need the state to be powered on
        }
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что изначально я получаю состояние центрального менеджера как неизвестное, и только через 3 секунды или около того состояние включается, и я могусделать что-то.Как я могу, со стороны Service, убедиться, что состояние уже включено к моменту запуска обработчика завершения?

1 Ответ

0 голосов
/ 04 декабря 2018

Во-первых, вам нужно решить, что делать, если BLE никогда не станет доступным.Это может быть выключено.Это может быть запрещено профилем MDM.Вы хотите просто подождать в этих случаях (возможно, навсегда) или вы хотите вызвать обратный вызов с ошибкой?

В любом случае вам нужно будет удерживать обработчик завершения, пока он не будет готов к работе.используется.

Вы можете сохранить его следующим образом:

var powerOnCompletion: ((Bool) -> Void)?

public func activateBlutooth(completion: @escaping (Bool) -> Void) {
    // Fancy way to chain together multiple calls to `activateBluetooth`. You could also just be
    // simple and `powerOnCompletion = completion`
    let previousHandler = powerOnCompletion
    powerOnCompletion = { result in
        previousHandler?(result)
        completion(result)
    }

    if centralManager.state == .poweredOn {
        powerOnCompletion?(true)
        powerOnCompletion = nil
    }
}

Затем вы также можете вызвать его в centralManagerDidUpdateState:

public func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .unknown:
        NSLog("unknown")
    case .resetting:
        NSLog("resetting")
    case .unsupported:
        NSLog("unsupporting")
    case .unauthorized:
        NSLog("unauthorized")
        powerOnCompletion?(false)   // error, and it's going to improve soon
        powerOnCompletion = nil
    case .poweredOn:
        NSLog("poweredOn")
        powerOnCompletion?(true)
        powerOnCompletion = nil
    case .poweredOff:
        NSLog("poweredOff")
        powerOnCompletion?(false)   // error, and it's going to improve soon
        powerOnCompletion = nil
    }
}

В зависимости от вашей системы выВозможно, вам захочется подумать о других переходах, например переходить от одного к другому и корректировать их по мере необходимости.Но основной подход заключается в том, что вам придется держаться за обработчик завершения.

Тем не менее, я обычно продолжаю и создаю CBCentralManager во время init (вместо использования lazy),Таким образом, он обычно готов к тому времени, когда что-то ищет его.

...