Я создал шагомер, который хранится в базе данных 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)
}
}
}
Я добавил структуру данных firebase, ура





Я думаю, это может помочь вам двигаться в правильном направлении, если нет, дайте мне знать, и я отредактирую.
Вот концепция уровня 10 км.
Данные вашего шага должны храниться в отдельных узлах, поэтому образец структуры 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, и я просто использовал эти строки как заполнители.
Сохранение его таким образом позволяет записывать шаги каждого дня отдельно. Обычно рекомендуется отделить имена узлов (ключи) от дочерних данных, которые они содержат; это значительно упрощает изменение ситуации в долгосрочной перспективе и делает ее более управляемой и расширяемой.
Можете ли вы также показать свою структуру данных? И было бы неплохо, если бы вы могли немного лучше отступить код в вашем вопросе (используя пробелы, а не табуляции)