

・言語：Swift  
・使用しているBluetoothデバイス：テキサス・インスツルメンツCC2541 SensorTag

初心者質問ですみません。  
初めて質問させて頂きますので、もしこういう表記した方が答えやすいなどありましたらご教示頂けましたら幸いです。

現在、Bluetoothのボタンが押された時にView上にデータの更新が反映されるものを試しに作っております。  
「iOS×BLE Core
Bluetoothプログラミング」という書籍を参考に進めてはおりまして、セントラルマネージャーやペリフェラルの記述をしているクラス(ViewController)では、sensorTagのボタンが押されるたびに「左」「右」などの更新データをリアルタイムで表示することができました。

しかし、このデータを別クラスのViewControllerで表示しようとしても、リアルタイムにデータが反映されずにうまくいきません。segueでデータを渡す方法など試してみましたが、リアルタイムでの更新ではなく、渡した時のデータのまま表示されてしまいます。

どのような方法で解決したらいいのか検討がつかず、質問させて頂きました。  
簡単な内容かもしれませんが、プログラミング初心者ゆえお許し下さい。

下記がコードです。

ViewController.swift

[code]

    import UIKit
    import CoreBluetooth
    
    
    class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
    
    var isScanning = false
    var centralManager: CBCentralManager!
    var peripheral: CBPeripheral!
    @IBOutlet weak var label: UILabel!
    var chara = NSData()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // セントラルマネージャ初期化
        self.centralManager = CBCentralManager(delegate: self, queue: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    // =========================================================================
    // MARK: CBCentralManagerDelegate
    
    // セントラルマネージャの状態が変化すると呼ばれる
    func centralManagerDidUpdateState(central: CBCentralManager!) {
    
        println("state: \(central.state)")
    }
    
    // 周辺にあるデバイスを発見すると呼ばれる
    func centralManager(central: CBCentralManager!,
        didDiscoverPeripheral peripheral: CBPeripheral!,
        advertisementData: [NSObject : AnyObject]!,
        RSSI: NSNumber!)
    {
        println("発見したBLEデバイス: \(peripheral)")
    
        if (peripheral.name?.hasPrefix("konashi") != nil) {
    
            self.peripheral = peripheral
    
            self.centralManager.connectPeripheral(self.peripheral, options: nil)
        }
    }
    
    // ペリフェラルへの接続が成功すると呼ばれる
    func centralManager(central: CBCentralManager!,
        didConnectPeripheral peripheral: CBPeripheral!)
    {
        println("接続成功！")
    
        // サービス探索結果を受け取るためにデリゲートをセット
        peripheral.delegate = self
    
        // サービス探索開始
        peripheral.discoverServices(nil)
    }
    
    // ペリフェラルへの接続が失敗すると呼ばれる
    func centralManager(central: CBCentralManager!,
        didFailToConnectPeripheral peripheral: CBPeripheral!,
        error: NSError!)
    {
        println("接続失敗・・・")
    }
    
    
    // =========================================================================
    // MARK:CBPeripheralDelegate
    
    // サービス発見時に呼ばれる
    func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) {
    
        if (error != nil) {
            println("エラー: \(error)")
            return
        }
    
        let services: NSArray = peripheral.services
    
        println("\(services.count) 個のサービスを発見！ \(services)")
    
        for obj in services {
    
            if let service = obj as? CBService {
    
                // キャラクタリスティック探索開始
                peripheral.discoverCharacteristics(nil, forService: service)
            }
        }
    }
    
    // キャラクタリスティック発見時に呼ばれる
    func peripheral(peripheral: CBPeripheral!,
        didDiscoverCharacteristicsForService service: CBService!,
        error: NSError!)
    {
        if (error != nil) {
            println("エラー: \(error)")
            return
        }
    
        let characteristics: NSArray = service.characteristics
    
        for obj in characteristics {
    
            if let characteristic = obj as? CBCharacteristic {
    
    
                    // 更新通知受け取りを開始する
                    peripheral.setNotifyValue(
                        true,
                        forCharacteristic: characteristic)
            }
        }
    
    
    }
    
        // Notify開始／停止時に呼ばれる
        func peripheral(peripheral: CBPeripheral!,
        didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic!,
        error: NSError!)
    {
        if error != nil {
    
            println("Notify状態更新失敗...error: \(error)")
        }
        else {
            println("Notify状態更新成功！characteristic UUID:\(characteristic.UUID), isNotifying: \(characteristic.isNotifying)")
        }
    }
    
    // データ更新時に呼ばれる
    func peripheral(peripheral: CBPeripheral!,
        didUpdateValueForCharacteristic characteristic: CBCharacteristic!,
        error: NSError!)
    {
        if error != nil {
            println("データ更新通知エラー: \(error)")
            return
        }
    
        println("データ更新！ characteristic UUID: \(characteristic.UUID), value: \(characteristic.value)")
    
        /**
        Sensor Tag の場合 ボタンから
        * <00>
        * ボタンが離された
        * <01>
        * 右ボタンが押された
        * <02>
        * 左ボタンが押された
        のいずれかの NSData が返ってくる
        */
    
        var keyPress : UInt8 = 0
        characteristic.value .getBytes(&keyPress, length: 1)
    
        chara = characteristic.value
        println("キャラの中身は\(chara)です")
    
        if (keyPress == 0){
            println("ボタンは押されていない")
            label?.text = "押されていない"
        } else if (keyPress == 1){
            label?.text = "右"
            println("右のボタンが押されている")
        } else if (keyPress == 2){
            label?.text = "左"
            println("左のボタンが押されている")
        } else if (keyPress == 3){
              }
          }
    
    
       // =========================================================================
    // MARK: Actions
    
    @IBAction func scanBtnTapped(sender: UIButton) {
    
        if !isScanning {
    
            isScanning = true
    
            self.centralManager.scanForPeripheralsWithServices(nil, options: nil)
    
            sender.setTitle("STOP SCAN", forState: UIControlState.Normal)
        }
        else {
    
            self.centralManager.stopScan()
    
            sender.setTitle("START SCAN", forState: UIControlState.Normal)
    
            isScanning = false
           }
       }
    }
    
[/code]

NextViewController.swift

[code]

    import UIKit
    
    class NextViewController: UIViewController {
    
     @IBOutlet weak var label2: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        var chara2 = ViewController().chara
        println(chara2)
    
        var keyPress2 : UInt8 = 0
        chara2 .getBytes(&keyPress2, length: 1)
        println(keyPress2)
    
        if (keyPress2 == 0){
            println("ボタンは押されていない2")
        } else if (keyPress2 == 1){
            println("右のボタンが押されている2")
        } else if (keyPress2 == 2){
            println("左のボタンが押されている2")
        } else if (keyPress2 == 3){
            println("両方のボタンが押されている2")
        }
    
    
    }
    
    override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
        }
    }
    
[/code]

SensorTagのボタンを押すたびにUILabelに「右」「左」というふうに、文字が表示されます。これを別のクラス(別のUIViewController?)では表示できません状況です。


CC BY-SA 3.0
2015-05-04T02:17:35.487
9806
2023-11-09T02:04:35.497
2015-05-04T07:39:20.247
9379
9379
question
ios swift bluetooth uikit
SwiftでBluetoothで受けとる更新データを別のビューで反映させる方法がわかりません


NextViewController.swiftの10行目`var chara2 =
ViewController().chara`は、なにをしようとしているのでしょうか？`ViewController`を生成直後のプロパティ`chara`の値を取得しようとしているので、`nil`かバイト長0のデータになるはずで、そんなものを取得してなんになるんだろう？というのが、正直な私の印象です。

「segueでデータを渡す方法」は、iOSアプリを新規作成するとき、「master-Detail
Application」を選択した場合に、できるテンプレートが、そのまま参考プログラムになっています。

![Xcode 新規作成画面](https://i.stack.imgur.com/X49Qq.png)

つぶさにていねいに一行ずつコードを分析していくことで、有益なものを得ることができるでしょう。


CC BY-SA 3.0
2015-05-05T10:36:00.460
9840
2015-05-05T10:36:00.460
7362
9806
answer


「centralManagerのdelegate」も「peripheralのdelegate」もself(=ViewController)なので、centralManagerやperipheralの状態変化はviewControllerでしか分かりません。

もし複数のViewやViewControllerで、centralManagerやperipheralの状態を知りたいのであれば、centralManagerやperipheralは特定のviewの持ち物とはせず、NSObjectを継承した
**BLE専用のクラス** を作成し、そのクラスのプロパティでcentralManagerやperipheralを持つようにすることをオススメします。

centralManager や peripheral
の状態変化はself(=BLE専用のクラス)で受けて、BLE関連の状態変化を知りたいViewやViewControllerへは、  
**Notification もしくは delegate(protocol) もしくは KVOで通知する。**  
という設計がいいと思います。

これはSwiftに限らず、Objective-Cでも他の言語でも通用するアプリケーション設計の一般的な考え方だと思います。

いきなりで難しいかもしれませんが、少しでも参考になれば幸いです。


CC BY-SA 3.0
2016-07-12T14:42:11.127
27573
2016-07-12T14:42:11.127
9103
9806
answer