菜鸟教程小白 发表于 2022-12-11 20:24:11

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


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

<p>我已将 Motion Usage Description 添加到我的 info.plist 中,并在我的 iPhone 模拟器上启用了授权。我还尝试在调试菜单中模拟“城市漫步”模式,但没有帮助。我的代码如下。</p>

<pre><code>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(&#34;Stop&#34;, for: .normal)
      startDate = Date()
      checkAuthorizationStatus()
      startUpdating()
    }

    private func onStop() {
      startButton.setTitle(&#34;Start&#34;, for: .normal)
      startDate = nil
      stopUpdating()
    }

    private func startUpdating() {
      if CMMotionActivityManager.isActivityAvailable() {
            startTrackingActivityType()
      } else {
            activityTypeLabel.text = &#34;Not available&#34;
      }

      if CMPedometer.isStepCountingAvailable() {
            startCountingSteps()
      } else {
            stepsCountLabel.text = &#34;Not available&#34;
      }
    }

    private func checkAuthorizationStatus() {
      switch CMMotionActivityManager.authorizationStatus() {
      case CMAuthorizationStatus.denied:
            onStop()
            activityTypeLabel.text = &#34;Not available&#34;
            stepsCountLabel.text = &#34;Not available&#34;
      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()) {
             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) {
             (activity: CMMotionActivity?) in
            guard let activity = activity else { return }
            DispatchQueue.main.async {
                if activity.walking {
                  self?.activityTypeLabel.text = &#34;Walking&#34;
                } else if activity.stationary {
                  self?.activityTypeLabel.text = &#34;Stationary&#34;
                } else if activity.running {
                  self?.activityTypeLabel.text = &#34;Running&#34;
                } else if activity.automotive {
                  self?.activityTypeLabel.text = &#34;Automotive&#34;
                }
            }
      }
    }

    private func startCountingSteps() {
      pedometer.startUpdates(from: Date()) {
             pedometerData, error in
            guard let pedometerData = pedometerData, error == nil else { return }

            DispatchQueue.main.async {
                self?.stepsCountLabel.text = pedometerData.numberOfSteps.stringValue
            }
      }
    }
}
</code></pre>

<p> <a href="/image/zfrzX.png" rel="noreferrer noopener nofollow">Here is my viewController upon running and clicking start</a> </p>

<p>非常感谢任何可以提供任何知识的人!!!</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>使用此代码检查授权状态:</p>

<pre><code> let manager = CMMotionActivityManager()


let today = Date()

    manager.queryActivityStarting(from: today, to: today, to: OperationQueue.main, withHandler: { (activities: ?, error: Error?) -&gt; () in
      if error != nil {
            let errorCode = (error! as NSError).code
            if errorCode == Int(CMErrorMotionActivityNotAuthorized.rawValue) {
                print(&#34;NotAuthorized&#34;)
            }
      } else {
            print(&#34;Authorized&#34;)
         //Start Tracking Activity
      }
      manager.stopActivityUpdates()
    })
</code></pre>

<p>希望这对你有用。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swift CMMotionActivityManager 未显示正确的授权状态,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/51461556/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/51461556/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swift CMMotionActivityManager 未显示正确的授权状态