Swift - 在 Firebase 数据库中存储计步器的日期

Swift - Store Dates of Step Counter in Firebase Database

我创建了一个存储在 firebase 数据库中的计步器。但是,它只存储那一天的步数数据,当我开始另一天时,步数就会消失。我猜我需要将这些数据存储在不同的日期下,以查看每天走了多少步。我不知道如何将其实现到我自己的代码中。任何有关如何将日期添加到单独的子节点的帮助将不胜感激。

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

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

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

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)

}

// 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)
 }
@IBAction func Ready(_ sender: AnyObject) {
    self.startButton.isHidden = true
}

// Ready? button tapped
@objc private func didTapStartButton() {
    let popOverVC = UIStoryboard(name: "Tab Bar", bundle: nil).instantiateViewController(withIdentifier: "PopUp") as! PopUpViewController
    self.addChildViewController(popOverVC)
    self.view.addSubview(popOverVC.view)
    popOverVC.didMove(toParentViewController: self)
    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?.updateStepCounterValue(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"
            } else if activity.stationary {
                self?.activityTypeLabel.text = "You're still"
            } else if activity.running {
                self?.activityTypeLabel.text = "You're running"
            } else if activity.automotive {
                self?.activityTypeLabel.text = "Driving"
            }
        }
    }
}
// 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)
        }
    }
}

我认为这可能会帮助您朝着正确的方向前进,如果没有,请告诉我,我会进行编辑。

这是 10k 英尺高度的概念。

您的步骤数据需要存储在单独的节点中,因此示例 Firebase 结构如下所示

users
   uid_0
      name: "Connor"
      steps:
        -asjs89u8d094f
           date: 20180320
           pedometer: 74
        -u999d9ks90dfk
           date: 20180321
           pedometer: 82

一个而不是这个

ref.child("user/(user)/pedometer").setValue(self.stepNumberVule)

会是这样的

let thisUsersStepsRef = your_firebase.child("users").child(uid).child("steps")
let refToAdd = thisUsersStepsRef.childByAutoId()
refToAdd.setValue(["date": "20180320", "pedometer", "74")

这将在 uid_0 节点中写入这样的结构。

 steps:
    -asjs89u8d094f
       date: 20180320
       pedometer: 74

-asjd...和 ​​-u999... 键是使用 childByAutoId 创建的,我只是将这些字符串用作占位符。

以这种方式存储它可以让每天的步数分开记录。将节点名称(键)与其包含的子数据分离通常是个好主意;从长远来看,它使改变事情变得容易得多,并使其更易于管理和扩展。