🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1543閲覧

###xcodeでアプリを作成し、複数beaconの電波強度(rssi)を棒グラフで同時に可視化したい。

NORMSENSEI

総合スコア11

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/10/02 07:48

###xcodeでアプリを作成し、複数beaconの電波強度(rssi)を同時に可視化したい。

現在Xcode+swift+charts(ライブラリ)を用いて、複数台のbeaconから取得した電波強度(rssi)を棒グラフで並べて比較できるようなアプリを作りたいと考えています。プログラム初心者です。

プログラムについて質問しますが、
そもそもやりたい事を実現できるアプリが既存である事をご存知の方は、そちらを教えていただけると幸いです。
よろしくお願いいたします。

発生している問題・エラーメッセージ

自分の認識では、下記のソースコードのbeaconsのリストで受信している全てのbeaconを取得できるものだと考えているが、複数のbeaconを検出できる位置でテストしているにも関わらず、リストに一つの値しか入っていないため、棒が一本しか出ない。

自分なりの分析では、
beaconsのlistには同じUUIDの物しか入って来ないのでは?
つまりグラフを表示するコードを書く部分が適切でないのではと自分の中で推測しています。

ソースは省略しているので、大部分は下記参照。
https://qiita.com/egplnt/items/b052c0e9cbd4efc90b31

該当のソースコード(とくに質問したい箇所は//ここがとくに知りたい。参照)

SWIFT

1// 2// NextViewController.swift 3// secondbeaconapp 4// 下記の記事の電波取得を参考に棒グラフで可視化できるように改造 5// 下記の記事とほとんど同じソースなので、詳細は下記の記事参照 6// https://qiita.com/egplnt/items/b052c0e9cbd4efc90b31 7 8 9import UIKit 10import CoreLocation 11import Charts 12 13class NextViewController: UIViewController, CLLocationManagerDelegate { 14 15 //~~~~~~ 16 //省略 17 18 func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) { 19 beaconUuids = NSMutableArray() 20 beaconDetails = NSMutableArray() 21 22 //追加個所 23 var beacons_list : [Double] 24 var beacons_count_list : [String] 25 26 beacons_list = [] 27 beacons_count_list = [] 28 //ここまで 29 30 31 if(beacons.count > 0){ 32 for i in 0 ..< beacons.count { 33 let beacon = beacons[i] 34 let beaconUUID = beacon.proximityUUID; 35 let minorID = beacon.minor; 36 let majorID = beacon.major; 37 let rssi = beacon.rssi; 38 var proximity = "" 39 switch (beacon.proximity) { 40 case CLProximity.unknown : 41 print("Proximity: Unknown"); 42 proximity = "Unknown" 43 break 44 case CLProximity.far: 45 print("Proximity: Far"); 46 proximity = "Far" 47 break 48 case CLProximity.near: 49 print("Proximity: Near"); 50 proximity = "Near" 51 break 52 case CLProximity.immediate: 53 print("Proximity: Immediate"); 54 proximity = "Immediate" 55 break 56 } 57 beaconUuids.add(beaconUUID.uuidString) 58 var myBeaconDetails = "Major: (majorID) " 59 myBeaconDetails += "Minor: (minorID) " 60 myBeaconDetails += "Proximity:(proximity) " 61 myBeaconDetails += "RSSI:(rssi)" 62 print(myBeaconDetails) 63 beaconDetails.add(myBeaconDetails) 64 //label_uuid.text = proximity 65 //label_uuid.text = "UUID:(beaconUUID)" 66 //label_major.text = "Major:(majorID)" 67 //label_minor.text = "Minor:(minorID)" 68 //label_rssi.text = "Rssi:(rssi)" 69 70 //追加箇所 71 beacons_list.append(Double(rssi)) 72 } 73 74       // 75 //ここがとくに知りたい。(知りたい箇所) 76 // 77 print(beacons_list) 78 79 //追加箇所 80 barChartView.animate(yAxisDuration: 0.0) 81 barChartView.pinchZoomEnabled = false 82 barChartView.drawBarShadowEnabled = false 83 barChartView.drawBordersEnabled = false 84 85 barChartView.leftAxis.axisMaximum = 0.0 86 barChartView.leftAxis.axisMinimum = -100.0 87 barChartView.rightAxis.axisMaximum = 0.0 88 barChartView.rightAxis.axisMaximum = -100.0 89 90 barChartView.rightAxis.enabled = false 91 92 if (beacons_list.count>=1){ 93 94 for i in 0 ..< beacons_list.count{ 95 beacons_count_list.append("(i)") 96 } 97 98 print("check") 99 print(beacons_count_list) 100 101 setChart(dataPoints: beacons_count_list, values: beacons_list) 102 103 } 104 105 } 106 } 107 108 109 110 //グラフ可視化のための関数既存のqiitaのソースにない部分 111 112 override func didReceiveMemoryWarning() { 113 super.didReceiveMemoryWarning() 114 } 115 116 func setChart(dataPoints: [String], values: [Double]) { 117 barChartView.noDataText = "You need to provide data for the chart." 118 119 var dataEntries: [BarChartDataEntry] = [] 120 121 for i in 0..<dataPoints.count { 122 let dataEntry = BarChartDataEntry(x: Double(i), y: values[i]) 123 dataEntries.append(dataEntry) 124 125 } 126 127 let chartDataSet = BarChartDataSet(entries: dataEntries 128 , label: "電波強度") 129 130 let color = UIColor(red:0.188, green:0.639, blue:0.702, alpha:1.0) 131 chartDataSet.colors = [color] 132 let chartData = BarChartData(dataSet: chartDataSet) 133 barChartView.data = chartData 134 135 //ここx軸listを作成する関数なりが必要 136 137 let xaxis = XAxis() 138 xaxis.valueFormatter = BarChartFormatter(label_list: dataPoints) 139 barChartView.xAxis.valueFormatter = xaxis.valueFormatter 140 barChartView.xAxis.labelCount = dataPoints.count 141 142 } 143 144 public class BarChartFormatter: NSObject, IAxisValueFormatter{ 145 // x軸のラベル(サンプルソースは月) 146 147 var beacons_label: [String]! 148 149 init(label_list: [String]){ 150 beacons_label = label_list 151 } 152 153 // デリゲート。TableViewのcellForRowAtで、indexで渡されたセルをレンダリングするのに似てる。 154 public func stringForValue(_ value: Double, axis: AxisBase?) -> String { 155 156 return beacons_label[Int(value)] 157 } 158 159 } 160 161} 162

試したこと

複数台のbeaconが検出できる位置でアプリを起動しテストした。
しかし一つのbeaconしか検出できない。

補足情報(FW/ツールのバージョンなど)

swift 4.5
xcode 10.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayabusabusash

2019/10/03 01:38 編集

CLBeaconRegionの生成部分でMajorとMinor両方指定したりとかはしてませんか? 追記: デリゲートメソッドの引数beaconsには指定したUUIDのもののみ流れてきた気がします。 なので同じUUIDの違うMajor、Minorのデバイスは認識できますが、 違うUUIDのデバイスを認識するためにはUUID分CLBeaconRegionを作る必要があると思います。 同時に20台まで認識できるらしいです。 ( https://grandbig.github.io/blog/2015/11/16/multi-ibeacon-region-2/ )
NORMSENSEI

2019/10/03 05:49

質問にわざわざ回答いただきありがとうございます。 参考にしているQiitaのソースコードでもありますように、 UUIDList=[”~”,”~”,"~"] のように設定する部分があり、複数のUUIDをいれ、 Major値、Minor値の指定などは特に参考のソースを触っていないのでしていないと思います。 昨日から分かったことがあります。 location_managerの中で ローカル変数beacons_listにrssiをappendしていましたが、 その場合だとlistに一つの値しか入ってきませんでした。 location_manager外のグローバル変数でbeacons_listを定義して、 appendすると、複数のbeaconの値が入ってきていることが確認できました。 ただその方法だとずっとbeacons_listに同じbeaconのrssi値を含めて たまっていってしまうので、 とりあえず検知できる相異なるビーコンを検知した場合、 いったんbeacons_listを空にする処理が書きたいのです。 どういったタイミングで空にするのが適切なのか、 またそのソースをどのように書けばいいのか、わかりません。 説明が下手で申し訳ないのですが、よろしくお願いいたします。
hayabusabusash

2019/10/04 00:56

なるほど。 それならやはりデリゲートメソッド内での処理に問題がありそうですね。 → 検知できる相異なるビーコンを検知した場合、 いったんbeacons_listを空にする処理が書きたい こちらに関してですが、 UUIDの違うビーコンを検知した時にリストを空にしてグラフも空にするということでしょうか?
NORMSENSEI

2019/10/04 07:02 編集

ありがとうございます。 もともと複数台のbeaconから取得した電波強度(rssi)を棒グラフで並べて比較できるようにするにはという話がもともとやりたいことなので、 (棒グラフはリアルタイムで更新。) そのためのデータをためるコードの書き方と、 どこに可視化のコードを書くとよいかという話になります。 私が初心者過ぎて delegateというのに慣れていなくてどう処理が進んでいるのかいまいち読めていないのです。 私が上に書いたソースというよりも下記のソースをもとに https://qiita.com/egplnt/items/b052c0e9cbd4efc90b31 どこに書けばよいか相談したい感じです。 beacons_listを空にするなどの話は気にしなくて良いです。 かえって理解しにくいコメント書いてすみません。
guest

回答1

0

ベストアンサー

データをためるコードの書き方

こちらに関してはViewControllerでrssiを貯めておく配列なりを持っておけばいいて、
その配列にCLLocationManagerのデリゲートメソッドで受け取ったビーコンをappendして行けばいいと思います。

どこに可視化のコードを書くとよいか

こちらグラフの描画ということなら今と同じ検知したビーコンを受け取るタイミングでいいと思います。
なのでrssiを貯めておく配列にappendしたタイミングでグラフを更新すればいいんじゃないかなと。

簡単にですがコードにしてみました。

ただ、手元に機材がなく、同じ状況を想定した確認をすることができなかったので、
ちゃんとした動作を確認することはできませんでした。申し訳ないです。

Swift

1class NextViewController: UIViewController, CLLocationManagerDelegate { 2 3 // rssiを貯めておく配列 4 private var rssiArray: [Int] = [Int]() 5 6 // 省略します 7 8 func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) { 9 // CLBeaconからrssi(Int)を取り出してappend 10 rssiArray.append(contentsOf: beacons.map { $0.rssi }) 11 12 // ここでグラフの更新 13 } 14}

投稿2019/10/05 07:17

hayabusabusash

総合スコア767

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問