質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

88.64%

HealthKitから得られた歩数の値をCharts でグラフに表示させたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,618

2828masaya

score 10

初めまして。現在Swiftを勉強している初学者のマサと申します。

前提・実現したいこと

HealthKitから得られた歩数の情報をChartsを使用し、歩数をグラフに表示させたいと思っています。
しかし、HealthKitから歩数の値は取得できているものの、値が horizontaBarChartUpdate() 関数にきちんと渡されずいます。
ここできちんと、getValueSteps に値が入れば、グラフが表示できるのではと考えています。

プリントログで確認した所、先にhorizontaBarChartUpdate()が呼び出されている様にも見えますが、これはSwiftでの関数の呼び出しに順序などがあるのでしょうか?

お聞きしたい事

Q1. horizontaBarChartUpdate() 関数に値を渡す方法。
Q2. Swiftにおいて、特有の関数が呼び出される順序があれば、ヒントをお教え願えたら幸いです。

該当のソースコード

import UIKit
import CoreMotion
import HealthKit
import Charts

class ShowGraphTableViewController: UITableViewController {

    // ここに棒グラフを描く
    @IBOutlet weak var horizontalBarChart: HorizontalBarChartView!

    // HealthKit インスタンス生成
    let healthStore = HKHealthStore()

    // 歩数受け取り用変数
    //var getStepToday: Double!

    override func viewDidLoad() {
        super.viewDidLoad()
        getSteps()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func getSteps() {

        // 初期化
        var sendValueOfSteps: Double = 0.0

        getTodaysSteps { (result) in DispatchQueue.main.async {
            sendValueOfSteps = result
            print("sendValueOfStep : \(sendValueOfSteps)")
            }
        }

        horizontaBarChartUpdate(getValueSteps: sendValueOfSteps)
    }

    // 今日の歩数を取得するための関数
    func getTodaysSteps(completion: @escaping (Double) -> Void) {

        // Returns the shared quantity type for the provided identifier.
        // 識別したデータを取得するために定義する。
        let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!

        let now = Date()
        // スタート日付を設定する。
        let startOfDay = Calendar.current.startOfDay(for: now)

        // Returns a predicate for samples whose start and end dates fall within the specified time interval.
        // 始めと終わりの日付を指定して、時間間隔内にあるサンプルのを返す。
        let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate)

        // A query that performs statistical calculations over a set of matching quantity samples, and returns the results.
        // マッチしたサンプル結果を返すクエリ。
        // execute して結果を取得する。
        let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) {
            (_, result, error) in
            var resultCount = 0.0
            guard let result = result else {
                print("Failed to fetch steps rate")
                completion(resultCount)
                return
            }

            if let sum = result.sumQuantity() {
                resultCount = sum.doubleValue(for: HKUnit.count())
                print("resultCount \(resultCount)")
            }

            DispatchQueue.main.async {
                completion(resultCount)
            }

        }

        //クエリの実行
        healthStore.execute(query)
    }

    func horizontaBarChartUpdate (getValueSteps: Double) {

        // データの挿入
        let entry1 = BarChartDataEntry(x: 1.0, y: getValueSteps)
        print("\(entry1)")

        //データのセット
        let dataSet = BarChartDataSet(entries: [entry1], label: nil)
        let data = BarChartData(dataSets: [dataSet])

        -省略-

        // チャートの表示
        horizontalBarChart.data = data
        // Color の設定
        dataSet.colors = ChartColorTemplates.vordiplom()
    }

}

プリントログ結果

ChartDataEntry, x: 1.0, y 0.0
resultCount 89567.0
sendValueOfStep : 89567.0

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

Swift 5.0
Xcode Version 10.2.1
Charts (3.3.0)

以上です。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

ソースコードを以下の様に修正した所、歩数を取得し、chartsで表示することが出来ました。

class ShowGraphTableViewController: UITableViewController {

    // グラフの生成
    @IBOutlet weak var horizontalBarChart: HorizontalBarChartView!

    // HealthKit インスタンス生成
    let healthStore = HKHealthStore()

    override func viewDidLoad() {
        super.viewDidLoad()

        // getTodaysStep関数へ値を渡す。
        getTodaysStep { (result) in
            DispatchQueue.main.async {
                self.horizontalBarChartUpdate(getStepValues: result)
            }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // 今日の歩数を取得するための関数
    func getTodaysStep(completion: @escaping (Double) -> Void) {
        let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!

        let now = Date()
        let startOfDay = Calendar.current.startOfDay(for: now)
        let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate)

        let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in
            guard let result = result, let sum = result.sumQuantity() else {
                completion(0.0)
                return
            }
            completion(sum.doubleValue(for: HKUnit.count()))
        }

        healthStore.execute(query)

    }

    func horizontalBarChartUpdate(getStepValues: Double) {

        // データの挿入
        let entry1 = BarChartDataEntry(x: 1.0, y: getStepValues)
        print("\(entry1)")

        //データのセット
        let dataSet = BarChartDataSet(entries: [entry1], label: nil)
        let data = BarChartData(dataSets: [dataSet])

        horizontalBarChart.animate(yAxisDuration: 1.0)//グラフのアニメーション(秒数で設定)

        // チャートの表示
        horizontalBarChart.data = data
        // Color の設定
        dataSet.colors = ChartColorTemplates.vordiplom()
    }

}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る