core-motion – 在IOS 11中,后台的DeviceMotion停止工作

我的应用程序在后台报告并记录位置,高度,旋转和加速度计数据(DeviceMotion).这适用于ios 10.3.3.在 IOS 11上,当设备被锁定时,我不再拥有访问运动数据.不过,高度数据和位置数据仍然会流式传输到控制台.

IOS 11中的某些内容发生了变化,导致我无法访问动态数据,或者我正在尝试以Apple现在阻止的方式访问它,例如OperationQueue.main

以下是我开始动态更新的方法.如果手机解锁,一切正常.如果我锁定手机,没有更新更新:

let motionManager = self.motionManager

    if motionManager.isDeviceMotionAvailable {
        motionUpdateInterval = 0.15
        motionManager.deviceMotionUpdateInterval = motionUpdateInterval

        motionManager.startDeviceMotionUpdates(using: .xArbitraryZVertical,to: OperationQueue.main) {deviceMotion,error in
            guard let deviceMotion = deviceMotion else { return }

我找不到关于运动背景模式改变的任何信息,但似乎必须有一种方法否则RunKeeper,Strava会破坏.在IOS11发布之前,有人可以帮助我重新开始工作吗?

谢谢!

解决方法

还遇到了这个问题.

我们的解决方案是确保我们启用并运行另一个后台模式(在我们的示例中,位置更新音频)并在切换后台/前景时重新启动核心动作更新.

代码示例:

import UIKit
import CoreMotion

final class MotionDetector {
    private let motionManager = CMMotionManager()
    private let opQueue: OperationQueue = {
        let o = OperationQueue()
        o.name = "core-motion-updates"
        return o
    }()

    private var shouldRestartMotionUpdates = false

    init() {
        NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: .UIApplicationDidEnterBackground,object: nil)
        NotificationCenter.default.addObserver(self,selector: #selector(appDidBecomeActive),name: .UIApplicationDidBecomeActive,object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self,object: nil)
        NotificationCenter.default.removeObserver(self,object: nil)
    }

    func start() {
        self.shouldRestartMotionUpdates = true
        self.restartMotionUpdates()
    }

    func stop() {
        self.shouldRestartMotionUpdates = false
        self.motionManager.stopDeviceMotionUpdates()
    }

    @objc private func appDidEnterBackground() {
        self.restartMotionUpdates()
    }

    @objc private func appDidBecomeActive() {
        self.restartMotionUpdates()
    }

    private func restartMotionUpdates() {
        guard self.shouldRestartMotionUpdates else { return }

        self.motionManager.stopDeviceMotionUpdates()
        self.motionManager.startDeviceMotionUpdates(using: .xArbitraryZVertical,to: self.opQueue) { deviceMotion,error in
            guard let deviceMotion = deviceMotion else { return }
            print(deviceMotion)
        }
    }
}

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...