在iOS 11中,后台运行的DeviceMotion停止工作。

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 }

我找不到任何有关动态背景模式更改的信息,但似乎必须有一种方法,否则 RunKeeper、Strava 将会崩溃。在 iOS11 发布之前,有人能帮我让这个正常工作吗?

谢谢!


@doovers 正确。CoreLocation正在使用,并且以前支持运动所需的后台模式。令人沮丧的是,WatchKit具有锻炼模式,允许在后台访问运动。 - Nicholas K
似乎我们在这个问题上不是孤单的...请查看主题。你在哪些设备上看到了这个问题?我尝试了 6 和 7,只有 7 不工作。 - doovers
我已经关注那个线程几天了。我向苹果提出了一个支持请求,自从周日以来一直开着。如果发生什么事情,我会回复的。请你也这样做。 - Nicholas K
感謝您,夥伴,我會確定讓您知道如果我找到了任何東西!希望我們能盡快解決這個問題! - doovers
1
大家好。我昨天收到了苹果的一封电子邮件,说问题可能已经在11.1 Beta 2中得到解决。昨晚安装了它,应用程序看起来很好。我在使用Xcode Beta时遇到了不同的编译问题,还没有能够在控制台中验证事情,但请查看11.1 Beta 2。 - Nicholas K
显示剩余15条评论
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)
        }
    }
}

1
谢谢你,Mani。我一直在旅行,没有机会尝试这个。昨天苹果发布了11.1 Beta 2,初步结果很好。我需要做更多的测试,但想感谢你的分享。 - Nicholas K
1
我正在使用iOS 11.4.1版本,但当应用程序进入后台时,核心运动更新会停止。我已经启用了Core Location后台模式,但没有成功。 - Praveen Kondapalli
谢谢。首先,感谢您。我已经为这个问题苦苦挣扎了几天。然而,这个答案在最新的iPhone(X,Xs,8等)和最新的操作系统版本(iOS 12.1.2)上仍然可行吗?另外,您跳过了通知处理程序的实现。它们是做什么的?调用“restartMotionUpdates()”?将“shouldRestartMotionUpdates”设置为true?谁会将其设置为false(当我们不需要它时)。 - Motti Shneor
我们在你发布方案几天后使用了它,一段时间内它表现得很好。现在它对我们来说停止工作了。也许是构建最新的iOS SDK导致它崩溃了?也许你的生产应用程序是针对较旧的SDK构建的?我已经没有什么招数了 :( - Motti Shneor
1
@RawMean 如果您没有任何正在进行的后台活动,运动检测器将会暂停。您的应用程序需要一些后台功能才能继续接收运动更新。如果可以这样做,启动静音音频或后台位置更新或健康包锻炼。 - mani
显示剩余5条评论

0

官方的11.1版本修复了这个问题,我听说iPhone 8用户表示原始实现对他们有效。

11.2测试版没有破坏任何东西。


2
我现在有多个报告称,在11.1版本中仍然无法正常工作。但这是使用.xMagneticNorthZVertical设置的情况。我已经要求苹果重新开放这个错误报告。 - fishinear
在iOS 12.3.1上仍然存在相同的问题,只有使用.xArbitraryZVertical设置才能正常工作,这个问题在早期版本中解决了吗? - Reham M Samir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接