Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

FunLocks「iOS&ビーコン勉強会」向けサンプルアプリ

Notifications You must be signed in to change notification settings

ohayota/FunLocks-handson-ios

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 

Repository files navigation

FunLocks-handson-ios

FunLocks「iOS&ビーコン勉強会」向けサンプルアプリ

ビーコンの検知機能を持ち,ビーコンから検知した信号の情報を表示するアプリ.下図のようなアプリを作る手順をREADMEに記載しました.(このREADMEでは背景色変更やフォント,レイアウトについて書かないため,下の画面とは見た目が大きく異なります.機能自体は同じです.)

BLEビーコン

BLEビーコンとは何か

BLEビーコンは,BLE(Bluetooth Low Energy)という通信技術を利用し,周囲に信号を発信し続ける端末です.消費電力が小さく,電池1個で1年以上使うことができます.小型端末のため,様々な場所に取り付けることが可能です.屋内での測位においては,GPSより優れています.

iBeacon

iBeaconは,Appleが2013年に発表した,BLEビーコンの一種です.この規格では,以下のような特徴があります.

  • 100ミリ秒ごとに信号を発信する(1秒に10回)
  • ビーコンと受信端末の距離を概算できる
  • 一度に検知できる信号(リージョン)は,最高で20個

これ以降の文章では,iBeacon(以下ビーコン)を前提として説明します.

ビーコン信号を利用して得られる情報

iOS端末でiBeaconの信号を受信して扱える情報の例は,以下の通りです.

  • Proximity(近接度.近い順に「Immediate」「Near」「Far」の3段階)
  • RSSI(信号強度.最大で数メートルの誤差)
  • Accuracy(ビーコンとの距離.単位:メートル)
  • Timestamp(最終観測時刻)
  • UUID(ビーコンの固有ID.1つの組織が1つのUUIDを使うといった使い方をする)
  • Major/Minor(同じUUIDを持つビーコンを区別するための値.例えば,建物/階数ごとに設置するビーコンの値を変えることで,建物/階数の特定に利用可能)

前準備

Apple IDの取得

Appleのサイトから,Apple IDを取得してください.

Xcodeのインストール

MacのApp Storeから,Xcodeの最新版をインストールしてください.

開発環境の確認

本ドキュメントで基準とした開発環境は以下の通りです.バージョンが異なっても構いませんが,挙動が異なる場合があるかもしれません.

  • MacOSのバージョン:10.15.7
  • Xcodeのバージョン:12.0.1
  • iOSのバージョン:14.0
  • 対象端末:iPhone

プロジェクトの用意

Xcodeを開き,最初の画面でCreate a new Xcode projectを選択します.

Appを選択して,Nextを押します.

Product Nameに任意の名前を入力してください.Interfaceは,必ずStoryboardにしてください.Life Cycleは,UIKit App Delegateにしてください.確認を終えたらNextを押します.

プロジェクトを保存する場所の指定画面が出ます.好きな場所を選択してください.保存を終えると,下のような画面に遷移します.

iPhoneだけで動くアプリを作るため,iPhoneだけにチェックをつけます.縦向き表示だけにするため,Device OrientationのPortraitだけチェックをつけます.

これでプロジェクトの準備は完了です.

ビーコン検知用のデータ作成

検知したいビーコンの情報を,アプリ側に予め用意しておきます.

BeaconData.jsonという名前のファイルを,任意のエディタで作成してください.作成できたら,以下の記述をコピー&ペーストして保存してください.

[
    {
        "id": 1001,
        "name": "495(廊下側)",
        "info": {
            "uuid": "48534442-4C45-4144-80C0-180000000000",
            "major": 4,
            "minor": 0
        }
    },
    {
        "id": 1002,
        "name": "495(駐車場側)",
        "info": {
            "uuid": "48534442-4C45-4144-80C0-180000000000",
            "major": 4,
            "minor": 1
        }
    },
    {
        "id": 1003,
        "name": "個人ビーコン",
        "info": {
            "uuid": "48534442-4C45-4144-80C0-1800FFFFFFFF",
            "major": 100,
            "minor": 1
        }
    }
]

保存できたら,プロジェクトにBeaconData.jsonを追加します.BeaconSampleというディレクトリにカーソルを合わせて右クリックし,出てきたメニューのAdd Files to "BeaconSample"...を選択してください.出てきた画面で,BeaconData.jsonを選択してAddを押すと,プロジェクトに追加されます.

出てきた画面で,BeaconData.jsonを選択してAddを押すと,プロジェクトに追加されます.正しく追加できると,以下のような表示になります.

ビーコンを表すデータモデルの作成

作成したBeaconData.json内のデータを扱うため,1つのビーコンを表すためのデータモデルを作成します.データモデルには以下の情報を持たせます.

  • id(ビーコンごとに割り振るID)
  • name(ビーコンにつける名前)
  • info(ビーコンが持つ値を格納するデータモデルInfo)

上記のうち,infoに含まれるデータは以下の情報です.(各値の役割については,ビーコン信号を利用して得られる情報を参照)

  • uuid
  • major
  • minor

これら2つのデータモデルを実現します.画面上のメニューから,File>New>File...を選択してください.

Swift Fileを選択します.

名前をBeacon.swiftにして,Createを押します.

作成されたファイルは,下図のような中身が書かれています.

Beacon.swiftにBeaconモデルを作ります.以下の記述を追加します.

struct Beacon: Codable, Identifiable {
    let id: Int
    let name: String
    let info: Info
}

Codableは,ビーコン検知用のデータ作成で作成したJSONファイルをデコード(Swiftで扱える形式に変換)するためにつけます.

Identifiableは,一つ一つのオブジェクトが一意(他と重複しない)であることを保証するための記述です.Beaconモデルの中で一意な変数は,idです.

続いて,Beaconモデル内で使われているInfoを作ります.以下の記述を追加します.

struct Info: Codable {
    let uuid: String
    let major: Int
    let minor: Int
}

これで,データモデルを作れました.

JSONファイルをデコードする関数を作成

ビーコンのデータモデルに合わせて,JSONをデコードする関数を作ります.

BeaconSampleというディレクトリにカーソルを合わせて右クリックし,出てきたメニューのNew Fileを選択してください.

出てきた画面で,Swift Fileを選択してNextを押すと,名前の入力画面が出ます.Data.swiftとして,Createを押すと追加されます.

Data.swiftを開き,以下の記述を追加します.

import UIKit

let beaconData: [Beacon] = load("BeaconData.json")

func load<T: Codable>(_ filename: String) -> T {
    let data: Data
    
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }
    
    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }
    
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

これにより,他のファイル内でも,ビーコンの情報を格納したbeaconDataという配列が使えるようになりました.

2つの画面を作成(.swiftファイル)

これ以降,アプリの画面を2つ実装します.

  • ビーコン選択画面(BeaconListViewController.swift)
  • ビーコン検知・情報表示画面(SearchViewController.swift)

ViewController.swiftの名前をBeaconListViewController.swiftに変更します.ViewController.swiftを長押しして離すと,名前を変更できます.

名前を変更した後にBeaconListViewControllerを開き,class ViewControllerの部分をclass BeaconListViewControllerに変更してください.

変更後は以下のようになります.

2つ目の画面として,SearchViewController.swiftというファイルを作成します.

BeaconSampleというディレクトリにカーソルを合わせて右クリックし,出てきたメニューの**New File...**を選択してください.

出てきた画面で,Cocoa Touch Classを選択します.

Nextを押すと,名前の入力画面が出ます.SearchViewController.swiftとして,Nextを押します.ファイルを追加する場所が合っていれば,そのままCreateを押します.

これで,2つの画面を作るためのファイルが用意できました.

2つの画面を作成(.storyboardファイル)

Main.storyboardを開き,画面右上の+ボタンを押します.出てきたビューの検索欄に,ViewControllerと入力します.

最初から配置されているViewControllerの右横に,ViewControllerをドラッグ&ドロップで配置します.配置した後の図は以下です.

先ほど作成した,2つの.swiftファイルを関連づけます.左側のViewControllerを選択し,上に表示されるマークの一番左を選択します(下図で青くなっている部分).

画面右のエリアで,ClassをBeaconListViewControllerに変更します.

同様に右のViewControllerも選択し,ClassをSearchViewControllerに変更します.これで.storyboardと.swiftの関連づけが完了しました.

ビーコンリストを表示する

下のような画面を作ります.

画面下にビーコンリストが表示され,タップすることで詳細画面に遷移します.遷移はここで実装せず,もう一つの画面を実装するときに実装します.

Main.storyboardを開き,画面サイズの設定をします.画面下のエリアで,View asのところをクリックして,対象端末を指定します.

次に右上の+ボタンを押します.TableViewと入力し,検索結果に出てきたTableViewをドラッグ&ドロップし,左のViewController内に配置します.

ひとまずいい感じに大きさを調整して配置します.AutoLayoutについては面倒くさいので触れません(サンプルアプリを参照するか,メンターに質問してください).

配置できたら,画面右上あたりにある以下のアイコンをクリックし,画面を2列にしてください.

2列にしたあと,左側にBeaconListViewController.swiftを表示させると,以下のようになります.

Main.storyboardで配置したTableViewを,BeaconListViewController.swiftに関連づけます.TableViewから,controlキーを押しながらBeaconListViewController.swiftへドラッグ&ドロップします.

名前をtableViewとしてConnectを押します.

正しく関連づけることができれば,コードが以下のように変化します.

次に,BeaconListViewControllerでtableViewを操作するための設定をします.再度Main.storyboardに配置されたTableViewを選択し,ViewController上にあるマークへ,controlキーを押しながらドラッグ&ドロップします.

出てきたダイアログのうち,dataSourceを選択します.

同様の手順をもう一度繰り返し,delegateも選択してください.

上記の操作が完了したら,次はBeaconListViewController.swiftを編集します.

ファイルの一番下の行から,以下の記述を追加します.

extension BeaconListViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // TableViewCellがタップされたときの処理
    }
}

extension BeaconListViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return beaconData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")
        cell.accessoryType = .disclosureIndicator
        // ここでTableViewCellへ表示する情報を指定する
        return cell
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Observable - 観測可能"
    }
}

2つのextensionにより,BeaconListViewControllerというclassは,UITableViewDelegateUITableViewDataSourceという2つのprotocolを持つようになりました.これによって,以下のようなことが可能になります.

  • TableViewに表示するTableViewCellの行数指定
  • TableViewCellのスタイル指定
  • TableViewCellに表示する情報の指定
  • TableViewCellをタップしたときの挙動の指定

これら以外にも,関数によって可能になる処理があります.詳細はUITableViewDelegateUITableViewDataSourceを参照してください.

ここで一度,iPhoneへビルドして動かしてみます.MacにiPhoneをケーブルで繋ぎます.接続したiPhoneを対象に選択して,三角のボタンを押してビルドします.

ビルドすると,下の画面のようになります.

何も書いていないTableViewCellが,2行表示されています.今のところ,タップしても変化はありません.

次に,2行のTableViewCellに以下の情報を表示させてみます.

  • ビーコンに割り当てられた名前(Beaconモデルのname)
  • ビーコンのUUID(Infoモデルのuuid)

extension BeaconListViewController: UITableViewDataSourceにある,2つ目の関数を以下のように改変します.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")
    cell.accessoryType = .disclosureIndicator
    cell.textLabel?.text = beaconData[indexPath.row].name
    cell.detailTextLabel?.text = beaconData[indexPath.row].info.uuid
    return cell
}

cell内のtextLabelの内容,detailLabelの内容を更新する処理を追加しました.これで再度ビルドすると,以下のような表示になります.

BeaconData.jsonに入れていた情報をもとに,TableViewCellに表示する情報を変えることができました.これでBeaconListViewControllerの表示内容の実装は完了です.

ビーコン検知・情報表示を実装する

下のような情報を表示する画面を作ります.(このREADMEでは背景色変更やフォント,レイアウトについて書かないため,下の画面とは見た目が大きく異なります.)

ビーコンを検知する

ビーコンの検知には,iPhoneの位置情報を利用する必要があります.ユーザに対して位置情報利用許可をとるために,いくつかの設定をします.

一番上の階層を選択したあと,infoタブを選択すると,以下の表示になります.

Custom iOS Target Propertiesに2項目を追加します.項目にカーソルを合わせると,+マークのボタンが表示されます.

ボタンをクリックすると項目が追加されるので,以下2つの項目を探して追加します.

  • Privacy - Location When In Use Usage Description
  • Privacy - Location Always and When In Use Usage Description

2項目とも,Valueの欄にはビーコンとの距離測定に利用しますと入力します.

SearchViewController.swiftを開き,位置情報利用許可のダイアログを表示する処理を記述します.位置情報を扱うために以下のimport文を追加します.

import CoreLocation

位置情報を扱うために使う,CLLocationManagerを生成します.SearchViewControllerクラスの中身は,以下のように記述します.

class SearchViewController: UIViewController {
    
    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
    }

}

その下に,locationManagerを使うためのextensionを記述します.

extension SearchViewController: CLLocationManagerDelegate {
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedAlways {
            // 位置情報利用が許可されているときの処理
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        // beaconsから,信号を受け取ったビーコンの情報を参照する
    }
    
}

ここから先は,変数として定義したlocationManagerを使ってビーコン検知を実装します.

画面を開いたときに呼び出す関数として,ビーコン検知を開始するstartScanningを定義します.SearchViewControllerに以下を追記します.

func startScanning() {
    let uuid = UUID(uuidString: selectedBeacon!.info.uuid)!
    let major = CLBeaconMajorValue(selectedBeacon!.info.major)
    let minor = CLBeaconMinorValue(selectedBeacon!.info.minor)
    
    let beaconRegion = CLBeaconRegion(beaconIdentityConstraint: CLBeaconIdentityConstraint(uuid: uuid, major: major, minor: minor), identifier: "MyBeacon")
    
    locationManager.startMonitoring(for: beaconRegion)
    locationManager.startRangingBeacons(satisfying: beaconRegion.beaconIdentityConstraint)
}

記述した直後には,SelectedBeaconという変数がないためエラーが出ます.ひとまず,var locationManager: CLLocationManager!の下に以下の記述を追加します.

var selectedBeacon: Beacon? = beaconData[0]

beaconData[0]の部分は,あとで,BeaconListViewControllerで選択したビーコンを入れるように変更します.今の状態は仮置きと覚えておいてください.

先ほど定義したstartScanningを,位置情報利用が許可されているときに呼び出すようにします.extension内の1つ目の関数を,以下のように置き換えます.

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    if status == .authorizedAlways {
        if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
            if CLLocationManager.isRangingAvailable() {
                startScanning()
            }
        }
    }
}

これで,自動的にビーコン検知が開始されるようになりました.

ビーコンリストからの遷移を実装する

BeaconListViewController.swiftに戻り,ビーコン検知・情報表示画面への遷移を実装します.UITableViewDelegateについてのextensionを,以下の記述に置き換えます.

extension BeaconListViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let searchViewController = self.storyboard?.instantiateViewController(withIdentifier: "SearchViewController") as! SearchViewController
        searchViewController.selectedBeacon = beaconData[indexPath.row]
        self.present(searchViewController, animated: true, completion: nil)
    }
}

このままビルドすると,withIdentifier: "SearchViewController"の部分でエラーが出ます.これを避けるために,一度Main.storyboardを開きます.右のSearchViewControllerを選択し,画面右のエリアのIdentityを編集します.

以下の2項目を編集します.

  • Storyboard IDにSearchViewControllerと書きます.
  • Use Storyboard IDにチェックを入れます.

これが終わったらビルドしてください.TableViewCellをタップすると,下から新しい画面が出てくるようになっているはずです.これで画面遷移の実装ができました.

先ほど追記したsearchViewController.selectedBeacon = beaconData[indexPath.row]によって,SearchViewControllerにビーコンの情報を渡すことができました.SearchViewControllerで仮置きにしていた変数selectedBeaconを,以下のように置き換えてください.

var selectedBeacon: Beacon?

ビーコンの情報表示を実装する

前の画面(BeaconListViewController.swift)で選択したビーコンを検知したとき,信号の情報を表示するようにします.

Main.storyboardを開きます.画面右上の+ボタンを押し,SearchViewControllerに,Labelを5つドラッグ&ドロップします.配置したLabelは,できるだけ横幅を広げておいてください.

5つのLabelを,SearchViewController.swiftに関連づけます(tableViewを関連づけたときと同じような手順です).関連づけたLabelには,順番に以下5つの名前をつけてください.

  • proximityLabel
  • uuidLabel
  • majorMinorLabel
  • timestampLabel
  • rssiAccuracyLabel

関連づけができると,下のようなコードになります.

それぞれのLabelに表示する情報は,以下の通りです.

  • ビーコンの近接度(IMMEDIATE,NEAR,FAR,UNKNOWN)
  • ビーコンのUUID
  • ビーコンのメジャー値とマイナー値
  • ビーコンの信号が最後に観測された時刻
  • ビーコンの信号強度,概算距離(単位:メートル)

ここから,検知したビーコン信号の値を取り出す処理を追加します.

まずは,前の画面(BeaconListViewController)から渡されたselectedBeaconの値(以下3つ)を利用します.

  • ビーコンのUUID
  • ビーコンのメジャー値とマイナー値

selectedBeaconの値を,2つのラベルに表示します.関数viewDidLoadを以下のように記述します.

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.requestAlwaysAuthorization()
    
    uuidLabel.text = selectedBeacon!.info.uuid
    majorMinorLabel.text = "\(selectedBeacon!.info.major) / \(selectedBeacon!.info.minor)"
}

これによって,uuidmajorminorの3つが表示されるようになりました.ビルドしてみます.

画面が小さい端末だと,値が見切れてしまう場合があります.値が見切れてしまう場合,Labelの設定で文字サイズを小さくするか,表示可能な行数を2行に増やすかで対処してください.

続いて,観測したビーコン信号から以下3つの値を取得し,残りのLabelに表示します.

  • ビーコンの近接度(IMMEDIATE,NEAR,FAR,UNKNOWN)
  • ビーコンの信号が最後に観測された時刻
  • ビーコンの信号強度,概算距離(単位:メートル)

近接度を取得して,表示する値を変える関数を追記します.

func updateStatus(proximity: CLProximity, rssi: Int?, accuracy: CLLocationAccuracy?) {
    switch proximity {
    case .far:
        self.proximityLabel.text = "FAR"
    case .near:
        self.proximityLabel.text = "NEAR"
    case .immediate:
        self.proximityLabel.text = "IMMEDIATE"
    default:
        self.proximityLabel.text = "UNKNOWN"
    }
}

関数updateStatusによって,ビーコンへ近ければIMMEDIATENEAR,ビーコンから遠ければFARUNKNOWNが表示されます.

信号強度と概算距離を表示する記述を追加すると,以下のようになります.

func updateStatus(proximity: CLProximity, rssi: Int?, accuracy: CLLocationAccuracy?) {
    switch proximity {
    case .far:
        self.proximityLabel.text = "FAR"
        self.rssiAccuracyLabel.text = "\(rssi!) / \(floor(Double(accuracy!)*100)/100)(m)"
    case .near:
        self.proximityLabel.text = "NEAR"
        self.rssiAccuracyLabel.text = "\(rssi!) / \(floor(Double(accuracy!)*100)/100)(m)"
    case .immediate:
        self.proximityLabel.text = "IMMEDIATE"
        self.rssiAccuracyLabel.text = "\(rssi!) / \(floor(Double(accuracy!)*100)/100)(m)"
    default:
        self.proximityLabel.text = "UNKNOWN"
        self.rssiAccuracyLabel.text = "- / -"
    }
}

rssiはInt型です.accuracyCLLocationAccurary型のため,Double型に変換してから,floor関数によって小数点第3位以下を丸めました.

次に,定義した関数updateStatusを呼び出す部分の処理を記述します.extension SearchViewController: CLLocationManagerDelegate内の2つ目の関数で,信号を検知できたビーコンたちの情報を扱うことができます.以下のように書き換えます.

func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    for beacon in beacons {
        // 検知できたビーコンが1個でもあった場合の処理
    }
    updateStatus(proximity: .unknown, rssi: nil, accuracy: nil)
}

for文の中で,検知できたビーコンが1個でもあった場合の処理を記述します.今回は,selectedBeaconが持つuuidと,検知できたビーコンのuuidが一致したときに情報を取得します.一致した時の条件をif文として追加すると,以下のようになります.

func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    for beacon in beacons {
        if beacon.uuid.uuidString == selectedBeacon!.info.uuid {
            // 最終観測時刻のLabelを更新する処理
            // 画面を更新する処理
            return // 1個でも一致したら他のビーコンは確認不要なため,関数から脱出する
        }
    }
    updateStatus(proximity: .unknown, rssi: nil, accuracy: nil)
}

uuidが一致したビーコンの観測時刻を取り出し,表示するまでの処理を追加すると,以下のようになります.

func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    for beacon in beacons {
        if beacon.uuid.uuidString == selectedBeacon!.info.uuid {
            let dateFormatter = DateFormatter()
            dateFormatter.locale = Locale(identifier: "ja_JP")
            dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
            timestampLabel.text = dateFormatter.string(from: beacon.timestamp)
            // 画面を更新する処理
            return // 1個でも一致したら他のビーコンは確認不要なため,関数から脱出する
        }
    }
    updateStatus(proximity: .unknown, rssi: nil, accuracy: nil)
}

最終観測時刻はCLBeacon型の中にあるtimestampという変数で取得できます.timestampを日本標準時に直し,みやすい形式に書き換え,Labelのテキストとして表示します.

画面を更新する処理を追加すると,以下のようになります.

func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    for beacon in beacons {
        if beacon.uuid.uuidString == selectedBeacon!.info.uuid {
            let dateFormatter = DateFormatter()
            dateFormatter.locale = Locale(identifier: "ja_JP")
            dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
            timestampLabel.text = dateFormatter.string(from: beacon.timestamp)
            updateStatus(proximity: beacon.proximity, rssi: beacon.rssi, accuracy: beacon.accuracy)
            return // 1個でも一致したら他のビーコンは確認不要なため,関数から脱出する
        }
    }
    updateStatus(proximity: .unknown, rssi: nil, accuracy: nil)
}

CLBeacon型からproximityrssiaccuracyを取り出して,関数updateStatusに渡すことで画面が更新されます.

ビルドすると,以下のような画面になります.

これでビーコン検知・情報表示画面の機能を実装でき,サンプルアプリ同様の最低限の機能が完成しました.

その他

近接度によって背景色を更新する

配布したサンプルアプリ内の関数updateStatusをご覧ください.

AutoLayout

ここに書くのは正直面倒なので,サンプルアプリのMain.storyboardを参照した上で,メンターに質問してください.

サンプルアプリの配置は,情報が見やすくなるようにしたつもりです.

About

FunLocks「iOS&ビーコン勉強会」向けサンプルアプリ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages