台風が来るのでiPhone6で気圧計を作る


**※更新版として[台風が多かったのでSwiftUIで気圧計を作る](https://qiita.com/bellx2/items/7ed392d9a6b769566620)を公開しました(2019.11.23)**

iPhone 6/6 Plusで搭載されたM8プロセッサーには気圧センサーがついています。階段の昇り降りなどの高度変化を検知するためが主な目的のようですが、台風も接近してきているので気圧計アプリを作ってみました。

![Screen Shot 2014-10-08 at 18.10.47.png](https://qiita-image-store.s3.amazonaws.com/0/14768/171241d2-4565-fcc7-8f58-c63e3fd8a4af.png "Screen Shot 2014-10-08 at 18.10.47.png")

ついでなので、本来の使い方である相対高度も表示してリセットできるようにしてみました（逆。

※シミュレータでは動きませんので実機転送が必要です。

### 実装

・プロジェクトにCoreMotion.frameworkを追加します。

・Storyboardはこんな感じでLabelが2つとbuttonが一つです。

![スクリーンショット 2014-10-08 18.46.30.png](https://qiita-image-store.s3.amazonaws.com/0/14768/0a69e090-e5d2-0e7c-87dc-747402fef6f1.png "スクリーンショット 2014-10-08 18.46.30.png")

・ViewController.swiftにコードを書きます。CMAltimeter クラスを使います。

```ViewController.swift
import UIKit
import CoreMotion

class ViewController: UIViewController {

    @IBOutlet weak var pressureLabel: UILabel!
    @IBOutlet weak var altitudeLabel: UILabel!
    
    let altimeter = CMAltimeter()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        startUpdate()
    }

    @IBAction func doReset(sender: AnyObject) {
        altimeter.stopRelativeAltitudeUpdates()
        startUpdate()
    }

    func startUpdate(){
        self.pressureLabel.text = "気圧:---- hPa"
        self.altitudeLabel.text = "高さ:-.-- m"
        if (CMAltimeter.isRelativeAltitudeAvailable()) {
            altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler:
                {data, error in
                    if error == nil {
                        let pressure:Double = data.pressure
                        let altitude:Double = data.relativeAltitude
                        self.pressureLabel.text = String(format: "気圧:%.1f hPa",pressure*10)
                        self.altitudeLabel.text = String(format: "高さ:%.2f m",altitude)
                    }
            })
        } else{
            println("not use altimeter")
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}
```

たいしたコードでは無いのでgithubに置くまでも無いかな...。

CMAltitudeData形式で来る値はpressureがkPaなので10倍します。altitudeはmです。

[CMAltitudeData Class Reference](https://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMAltitudeData_class/index.html)

### 気圧について

気象庁から各気象台の測定データとして出ている気圧は海面高度を引いたものになっているようです。アメダスの数値と比較してみると5hPa差があるので5*8=40m。

東京都-アメダスデータ
http://www.jma.go.jp/jp/amedas_h/today-44132.html

標高と大気圧の関係
http://members.jcom.home.ne.jp/tetsuom/NOTE/NtPvsH/HdPvsH.htm

今いる場所の海抜はGoogleMapによると20m、建物のの6Fにいるので3.5m*6=21mで合計41mという事でざっと計算しても正しそうです。本当にやるならGPS情報の高度を使えばちゃんと補正できそうです。


### ごにょごにょ

"let altimeter = CMAltimeter()"をviewDidLoad内でやってしまうと、viewの初期化後にaltimeterが解放されてしまいコールバックが呼ばれませんでした。気づくのに時間がかかりハマりましたのでご注意を。

data.pressure値をそのまま使うと桁が多すぎ、計算に使うと整数になってしまうので、Doubleとして代入しています。この辺り、Swift初心者なのでもっと良い書き方があるかもしてません。

通常の気圧変化で相対高度が変わっていくので、短い間隔で傾向をみたり平均値をとったりした方が良い気がします。

###Siri

Siriで「今の気圧は？」と聞くと気圧を返してくれるのですが、取得している値と微妙に違います。高度補正が入っているのか、別の場所の気圧を言っているのか不明です。

![IMG_0039.PNG](https://qiita-image-store.s3.amazonaws.com/0/14768/c5ad69f9-a8c6-1cb4-50fc-988f9aee672c.png "IMG_0039.PNG")


### 参考

[iOS 8] iPhone 6 / iPhone 6 Plus で使える新機能！ CMAltimeter で高度を取得する
http://dev.classmethod.jp/references/ios8-cmaltimeter/

iOS8の高度計(気圧計)
http://reinforce-lab.github.io/blog/2014/10/03/ios8-barometer/