In IOS 11, DeviceMotion in background stopped working

依然范特西╮ 提交于 2019-11-30 13:33:06
mani

Also came across this problem.

Our solution was to ensure we have another background mode enabled and running (in our case location updates + audio) and restart core motion updates when switching background/foreground.

Code sample:

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,
                                                  name: .UIApplicationDidEnterBackground,
                                                  object: nil)
        NotificationCenter.default.removeObserver(self,
                                                  name: .UIApplicationDidBecomeActive,
                                                  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)
        }
    }
}

The official 11.1 release fixed the issue and I've heard from iPhone 8 users that the original implementation is working for them.

The 11.2 beta has not broken anything.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!