Core Motion计步器保存到Firebase

时间:2018-03-21 16:53:32

标签: swift firebase firebase-realtime-database core-motion

在此代码中是一个工作计步器,显示移动速度和当前步骤。我想知道的是如何将我的步骤保存到我的firebase数据库中?我的IBAction按钮保存确实提交到我的firebase数据库,但它提交了数字0.我如何提交stepCountlabel显示的数字?

import UIKit
import CoreMotion
import Dispatch
import Firebase

class PedometerViewController: UIViewController {

// Declarations of Pedometer
private let activityManager = CMMotionActivityManager()
private let pedometer = CMPedometer()
private var shouldStartUpdating: Bool = false
private var startDate: Date? = nil
var stepNumberVule: Int = 0 // FIREBASE CODE

// Storyboard connections
@IBOutlet weak var startButton: UIButton!
@IBOutlet weak var stepsCountLabel: UILabel!
@IBOutlet weak var activityTypeLabel: UILabel!

// FIREBASE CODE - I WANT TO WORK - ADD STEPS TO FIREBASE DATABASE
func getPedValue() {
    var ref: DatabaseReference!
    ref = Database.database().reference()
    let userID = Auth.auth().currentUser?.uid
    ref.child("user").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let ped:Int = value?["pedometer"] as? Int ?? 0
 self.stepNumberVule = ped
 self.stepsCountLabel.text = ("\(self.stepNumberVule)")
    }) { (error) in
        print(error.localizedDescription)
    }
    }

@IBAction func Save(_ sender: Any) {
    var ref: DatabaseReference!
    ref = Database.database().reference()
    let user = Auth.auth().currentUser!.uid
    let key = ref.child("user").child(user)
    ref.child("user/\(user)/pedometer").setValue(self.stepNumberVule)

}
// END OF FIREBASE CODE


// Do any additional setup after loading the view.
override func viewDidLoad() {
    super.viewDidLoad()
    startButton.addTarget(self, action: #selector(didTapStartButton), for: .touchUpInside)
}
// Do additional tasks associated with presenting the view
    override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    guard let startDate = startDate else { return }
    updateStepsCountLabelUsing(startDate: startDate)
}
// Go! button tapped
    @objc private func didTapStartButton() {
    shouldStartUpdating = !shouldStartUpdating
    shouldStartUpdating ? (onStart()) : (onStop())
}
}

  // Pedometer Extension and its private fuctions (functions are       explained explicitly so no need for comments)
  extension PedometerViewController {
private func onStart() {
    startButton.setTitle("Stop", for: .normal)
    startDate = Date()
    checkAuthorizationStatus()
    startUpdating()
}

private func onStop() {
    startButton.setTitle("Start", for: .normal)
    startDate = nil
    stopUpdating()
 }

private func startUpdating() {
    if CMMotionActivityManager.isActivityAvailable() {
        startTrackingActivityType()
    } else {
        activityTypeLabel.text = "Not available"
 }

    if CMPedometer.isStepCountingAvailable() {
        startCountingSteps()
    } else {
        stepsCountLabel.text = "Not available"
    }
 }

private func checkAuthorizationStatus() {
    switch CMMotionActivityManager.authorizationStatus() {
    case CMAuthorizationStatus.denied:
        onStop()
        activityTypeLabel.text = "Not available"
        stepsCountLabel.text = "Not available"
    default:break
    }
 }

private func stopUpdating() {
    activityManager.stopActivityUpdates()
    pedometer.stopUpdates()
    pedometer.stopEventUpdates()
 }

private func on(error: Error) {
    //handle error
 }

// Update step count
private func updateStepsCountLabelUsing(startDate: Date) {
    pedometer.queryPedometerData(from: startDate, to: Date()) {
        [weak self] pedometerData, error in
        if let error = error {
            self?.on(error: error)
        } else if let pedometerData = pedometerData {
            DispatchQueue.main.async {
                self?.stepsCountLabel.text = String(describing: pedometerData.numberOfSteps)
            }
        }
    }
  }
// Activity type
private func startTrackingActivityType() {
    activityManager.startActivityUpdates(to: OperationQueue.main) {
        [weak self] (activity: CMMotionActivity?) in
        guard let activity = activity else { return }
        DispatchQueue.main.async {
            if activity.walking {
                self?.activityTypeLabel.text = "You're walking, go faster!"
            } else if activity.stationary {
                self?.activityTypeLabel.text = "You're still, stop being lazy"
            } else if activity.running {
                self?.activityTypeLabel.text = "You're running, nice one!"
            } else if activity.automotive {
                self?.activityTypeLabel.text = "Driving doesnt count..."
            }
        }
    }
}
// Start counting steps
private func startCountingSteps() {
    pedometer.startUpdates(from: Date()) {
        [weak self] pedometerData, error in
        guard let pedometerData = pedometerData, error == nil else { return }

        DispatchQueue.main.async {
            self?.stepsCountLabel.text = pedometerData.numberOfSteps.stringValue
        }
    }
}

1 个答案:

答案 0 :(得分:0)

因此,您拥有全局变量stepNumberVule,并且每次调用Save操作时,您都会将此变量的值保存到Firebase,但问题在于您&# 39;请勿在{{1​​}}或updateStepsCountLabelUsing(startDate: Date)中更新此值。如果要保存确切的步数,则应从计步器数据更新startCountingSteps()

E.g:

创建功能

stepNumberVule

然后,调用它来更新你的标签和变量:

private func updateStepCounterValue(_ numberOfSteps: NSNumber) {
    stepNumberVule = numberOfSteps.intValue
    stepsCountLabel.text = numberOfSteps.stringValue
}

// Start counting steps
private func startCountingSteps() {
    pedometer.startUpdates(from: Date()) {
        [weak self] pedometerData, error in

        guard let pedometerData = pedometerData, error == nil else { return }
        DispatchQueue.main.async {
             self?.updateStepCounterValue(pedometerData.numberOfSteps)
        }
    }
}

通过这种方式,您的private func updateStepsCountLabelUsing(startDate: Date) { pedometer.queryPedometerData(from: startDate, to: Date()) { [weak self] pedometerData, error in if let error = error { self?.on(error: error) } else if let pedometerData = pedometerData { DispatchQueue.main.async { self?.updateStepCounterValue(pedometerData.numberOfSteps) } } } } 将始终与计步器中的当前数据保持同步。