0

I just want to build a step counting app for iphones. My application runs correctly when in foreground and save the step data to the firebase but when user terminate the app, the step counting stops so I dug the internet to solve the problem and could not figure it out. Can you guys help me that keep counting the steps in the background and write them to firebase in the background?

import UIKit
import CoreMotion
import FirebaseAuth
import FirebaseDatabase
class MainViewController: UIViewController {

//MARK: - Constants and Variables
let pedometer = CMPedometer()
let userDefault = UserDefaults.standard
var ref : DatabaseReference!
let user = Auth.auth().currentUser
var someInt: Int?

//MARK: - IBOutlets and IBActions
@IBOutlet weak var stepCountLabel: UILabel!

@IBAction func logOutBtn(_ sender: UIButton) {
    logout()
}

//MARK: - viewDidLoad
override func viewDidLoad() {
    super.viewDidLoad()
    stepCountLabel.text = "0"
    getFirebaseData()
    
}


//MARK: - Functions
func getFirebaseData() {
    ref = Database.database().reference()
    let uid = user!.uid
    ref.child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
        
        // Get user value
        let value = snapshot.value as? [String : Any]
        let userDict = [
            "nickname" : value?["nickname"],
            "step_count" : value?["step_count"]
        ]
        
        
        DispatchQueue.main.async {
            self.someInt = userDict["step_count"] as? Int
            self.startPedometer(number: self.someInt ?? 0)
            self.stepCountLabel.text = String(self.someInt ?? 0)
        }
    })
    {
        (error) in
        print(error.localizedDescription)
    }
}

func startPedometer (number: Int) {
    pedometer.startUpdates(from: Date()) { (data, error) in
        if error == nil {
            self.getFirebaseData()
            //create data reference
            self.ref = Database.database().reference()
            //rewrite the step data on the child
            self.ref.child("users/ (self.user!.uid)/step_count").setValue(data!.numberOfSteps.intValue + number)
        } else{
            print("An error was occured: \(error!)")
        }
    }
}



func logout() {
    pedometer.stopUpdates()
    do {
        try Auth.auth().signOut()
        userDefault.setValue(false, forKey: "userSignedIn")
    }
    catch {
        print("already logged out")
    }
    navigationController?.popToRootViewController(animated: true)
  }
}
  • You're not going to be counting steps and networking in the background. Your app is suspended, and anyway, your users will be angry when you wear down the battery unnecessarily. If you need step data you can collect it from the device when you come to the foreground again. – matt Dec 12 '20 at 21:24
  • oh I did not know that. so how can I collect data from the device when user comes back in foreground again? how can I know when user terminate the app and when started the app? – Muhammet Taha Genç Dec 12 '20 at 21:26
  • You get app/scene delegate messages that tell you when those things happen. – matt Dec 12 '20 at 21:29
  • Thank you man i did not think that before. lol – Muhammet Taha Genç Dec 12 '20 at 21:38

0 Answers0