【问题标题】:Swift CMMotionActivityManager not displaying correct authorization StatusSwift CMMotionActivityManager 未显示正确的授权状态
【发布时间】:2018-07-22 02:26:22
【问题描述】:

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

我已将 Motion Usage Description 添加到我的 info.plist 中,并在我的 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

非常感谢任何可以提供任何知识的人!!!

【问题讨论】:

  • 请尝试在 iOS 设备中运行您的代码,因为核心运动使用设备传感器获取用户活动。

标签: ios swift xcode core-motion


【解决方案1】:

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

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

希望这对你有用。

【讨论】:

    猜你喜欢
    • 2014-06-15
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    相关资源
    最近更新 更多