Swift CMMotionActivityManager未显示正确的授权状态

时间:2018-07-22 02:26:22

标签: ios swift xcode core-motion

我正在尝试创建一个非常简单的计步器,并关注https://brightinventions.pl/blog/coremotion-pedometer-swift/上Kamil Wysocki的文章。但是,我的.isActivityAvailable()返回False,阻止其他函数启动。另外,我的CMMotionActivityManager.authorizationStatus()通话返回3(被拒绝)。我一生无法弄清为什么会这样。

我已在“ info.plist”中添加了“ Motion Usage Description”以及描述,并已在我的iPhone模拟器上启用了授权。我还尝试在调试菜单中模拟“城市漫步”模式,但没有帮助。我的代码在下面。

import UIKit
import CoreMotion
import CoreLocation

class ViewController: UIViewController {

    @IBOutlet weak var startButton: UIButton!
    @IBOutlet weak var activityTypeLabel: UILabel!
    @IBOutlet weak var stepsCountLabel: UILabel!

    private let activityManager = CMMotionActivityManager()
    private let pedometer = CMPedometer()
    private var shouldStartUpdating: Bool = false
    private var startDate: Date? = nil

    override func viewDidLoad() {
        super.viewDidLoad()

        startButton.addTarget(self, action: #selector(didTapStartButton), for: .touchUpInside)

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        guard let startDate = startDate else { return }
        updateStepsCountLabelUsing(startDate: startDate)
    }

    @objc private func didTapStartButton() {
        shouldStartUpdating = !shouldStartUpdating
        shouldStartUpdating ? (onStart()) : (onStop())
    }
}


extension ViewController {
    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
    }

    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)
                }
            }
        }
    }

    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 = "Walking"
                } else if activity.stationary {
                    self?.activityTypeLabel.text = "Stationary"
                } else if activity.running {
                    self?.activityTypeLabel.text = "Running"
                } else if activity.automotive {
                    self?.activityTypeLabel.text = "Automotive"
                }
            }
        }
    }

    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
            }
        }
    }
}

Here is my viewController upon running and clicking start

在此先感谢任何可以提供任何知识的人!

1 个答案:

答案 0 :(得分:0)

使用此代码检查授权状态:

 let manager = CMMotionActivityManager()


 let today = Date()

    manager.queryActivityStarting(from: today, to: today, to: OperationQueue.main, withHandler: { (activities: [CMMotionActivity]?, error: Error?) -> () in
        if error != nil {
            let errorCode = (error! as NSError).code
            if errorCode == Int(CMErrorMotionActivityNotAuthorized.rawValue) {
                print("NotAuthorized")
            }
        } else {
            print("Authorized")
         //Start Tracking Activity 
        }
        manager.stopActivityUpdates()
    })

希望这对您有用。