11

我的应用程序在后台报告并记录位置、高度、旋转和加速度计数据 (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 }

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

谢谢!

4

2 回答 2

10

也遇到过这个问题。

我们的解决方案是确保我们启用并运行另一种后台模式(在我们的情况下是位置更新 + 音频),并在切换背景/前景时重新启动核心运动更新。

代码示例:

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)
        }
    }
}
于 2017-09-28T08:00:46.063 回答
0

官方 11.1 版本修复了这个问题,我从 iPhone 8 用户那里听说原来的实现对他们有用。

11.2 beta 没有破坏任何东西。

于 2017-11-11T00:57:10.270 回答