読者です 読者をやめる 読者になる 読者になる

koogawa log

iOS、Android、foursquareに関する話題

【Tips】iOSで歩数をカウントする(Swift編)

数年前に書いた下記記事が古くなってきたので、Swift編 として書き直しました。

【Tips】iOSで歩数をカウントする - koogawa log

f:id:koogawa:20160423122813p:plain


CoreMotionを使って、歩数カウントを取得する方法をメモしておきます。

動作環境

Xcode 8.0 + Swift 2.2

実装方法

まずは「CoreMotion.framework」を追加します。

f:id:koogawa:20131122152458p:plain

ヘッダをインポートします。

import CoreMotion

歩数をカウントする

歩数をカウントするためには CMPedometer を使います。

iOS 7で登場した CMStepCounteriOS 8 で早くも deprecated になりました。早かったですね…

まずはインスタンスを生成します。メンバ変数にしないとうまくいかないので注意です。

let pedometer = CMPedometer()

startPedometerUpdatesFromDate メソッドで歩数のカウントを開始します。

if CMPedometer.isStepCountingAvailable() {
    self.pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: {
        [weak self] (data: CMPedometerData?, error: NSError?) -> Void in
        // 歩数が更新されるたびに呼ばれる
        dispatch_async(dispatch_get_main_queue(), {
            if data != nil && error == nil {
                self?.stepLabel.text = "step: \(data!.numberOfSteps)"
            }
        })
    })
}
  • 第1引数:どの時点からのデータを呼び出すか指定(今回は現在日時を指定)
  • 第2引数:歩数更新時に呼び出す handler

第2引数で指定する handler には、計測を始めてからの累計歩数、移動距離など様々な情報が返ってきます。詳細はアップルの公式ドキュメントを参照してください。

歩数カウントが不要になったら、忘れずにカウントを停止しておきます。

self.pedometer.stopPedometerUpdates()

アクティビティの変化を取得する

また、歩数以外にもユーザのアクティビティ情報(歩いているのか、走っているか等)も取得できます。

まずはインスタンスを生成します。メンバ変数にしないとうまくいかないので注意です。

let activityManager = CMMotionActivityManager()

取得を開始します。

if CMMotionActivityManager.isActivityAvailable() {
    self.activityManager.startActivityUpdatesToQueue(NSOperationQueue.mainQueue(),
        withHandler: {
        [weak self] (data: CMMotionActivity?) -> Void in
        dispatch_async(dispatch_get_main_queue(), {
            // アクティビティが変化するたびに呼ばれる
        })
    })
}

アクティビティは CMMotionActivity というクラスで返ってきます。このクラスには次のプロパティが含まれます。

プロパティ 意味
NSDate startDate アクションが発生した時間
CMMotionActivityConfidence confidence データの精度(Low/Medium/High のいずれか)
BOOL stationary 静止状態
BOOL walking 徒歩中
BOOL running ランニング中
BOOL automotive 自動車や電車等の乗り物に乗っている状態
BOOL unknown 不明なアクティビティ

どれかひとつの動作が true になるというわけではなく、例えばautomotivestationary が同時に true になる状況もありえるようです。

最後は忘れずに停止しておきます。

self.activityManager.stopActivityUpdates()

サンプル

注意点

リンク