0

그룹 프로젝트의 일부로 구축중인 응용 프로그램에서 Bluetooth 장치를 검색하는 데 문제가 있습니다. 다음 뷰의 코드는 다음과 같습니다 때때로 그것은 단지 한 번 내 노트북을 나열합니다 블루투스Bluetooth 컨트롤러에 여러 버전의 장치 목록이 표시됨 - Swift 3.1

UITableView displaying Bluetooth devices

사용하여 스캔 할 때이 나에게 다음과 같은 결과를 제공하지만 간헐적으로

import UIKit 
import CoreBluetooth 

class bluetoothConnectViewController: UIViewController, UITableViewDelegate, CBCentralManagerDelegate, UITableViewDataSource { 

    //----------------------- 
    // MARK: Variables 
    //----------------------- 

    var centralManager: CBCentralManager? 
    var peripherals = Array<CBPeripheral>() 

    //----------------------- 
    // MARK: Outlets 
    //----------------------- 

    @IBOutlet weak var tableView: UITableView! 

    //----------------------- 
    // MARK: Core Functions 
    //----------------------- 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     //Initialise CoreBluetooth Central Manager 
     centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main, options: nil) 

     // Table pull to refresh 
     let refreshControl = UIRefreshControl() 
     refreshControl.addTarget(self, action: #selector(refresh(_:)), for: .valueChanged) 

     tableView.refreshControl = refreshControl 

     tableView.delegate = self 
     tableView.dataSource = self 
    } 

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

    //----------------------- 
    // MARK: Custom Functions 
    //----------------------- 

    func refresh(_ refreshControl: UIRefreshControl) { 
     // Do your job, when done: 
     refreshControl.endRefreshing() 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return peripherals.count 
    } 

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
     return "Connect to device" 
    } 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     var cell = tableView.dequeueReusableCell(withIdentifier: "cell") 

     if cell == nil { 
      cell = UITableViewCell(style: .default, reuseIdentifier: "cell") 
     } 

     let peripheral = peripherals[indexPath.row] 
     cell?.textLabel?.text = peripheral.name 

     return cell! 
    } 

    //----------------------- 
    // MARK: BLE Functions 
    //----------------------- 

    func centralManagerDidUpdateState(_ central: CBCentralManager) { 
     if (central.state == .poweredOn){ 
      self.centralManager?.scanForPeripherals(withServices: nil, options: nil) 
     } 
     else { 
      let alert = UIAlertController(title: "Bluetooth not enabled", message: "Enable bluetooth to scan for devuices", preferredStyle: .actionSheet) 

      alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil)) 
      alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { (UIAlertAction) in 
       let url = URL(string: "prefs:root=Bluetooth")! 
       UIApplication.shared.open(url, options: [:], completionHandler: nil) 

      })) 
     } 
    } 

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { 
     peripherals.append(peripheral) 
     tableView.reloadData() 
    } 
} 

, 내가 뭘 잘못하고 있는지 알려주시겠습니까?

+0

를 추가하기 전에 포함되어 있는지 여부를 판단한다. didDiscover 메서드에서 얻은 CBPeripheral 개체의 identifier 속성을 배열의 CBPeripheral 개체의 identifier 속성과 비교해야합니다. –

+0

동일한 문제가 거기에 설명되어 있습니다 : http://stackoverflow.com/questions/43351664/why-is-corebluetooth-discovering-the-same-peripheral-again-and-again-and-again "적극적 광고". – Larme

답변

1

동일한 CBPeripheral 개체가 주변 배열에 다시 삽입 된 것으로 보입니다.

didDiscover 메서드에서 얻은 CBPeripheral 개체의 identifier 속성을 추가하기 전에 주변 장치 배열의 CBPeripheral 개체의 identifier 속성과 비교해야합니다.

0

주변 장치 배열에서 이미 사용할 수있는 CBPeripheral의 속성 인 CDUUID를 비교해야 할 때마다 didDiscover 메서드가 수행됩니다. 존재하지 않으면 배열에 삽입해야합니다. 그렇지 않으면 그대로 두십시오.

이 줄을 사용하여 CBUUID를 얻었습니다. CBUUID * uuid = peripheral.UUID; 이 UUID가 이미 배열에 있는지 확인합니다.

0

주변 장치는 데이터를 계속 브로드 캐스트하므로 대리 메서드 centralManager(_:didDiscover:advertisementData:rssi:)이 여러 번 수신됩니다.

Set를 사용 peripherals의 종류를 바꿀 수있다이 문제를 해결하거나 주변 배열 동일한 CBPeripheral 객체를 추가하는 것 같다 주연이

+0

발견 된 장치에 대한 CBPeripheral 인스턴스의 1 : 1 매핑이 있다고 가정하지 않고 peripheral.identifier의 고유성을 확인했습니다. 프레임 워크가 동일한 장치에 대해 서로 다른 인스턴스를 제공 할 수 있다고 생각합니다. – CuriousRabbit