【问题标题】:My iOS application does not update the location in background我的 iOS 应用程序没有在后台更新位置
【发布时间】:2017-05-18 13:09:33
【问题描述】:

我有一个用 Swift 开发的 iOS 应用程序。我的应用目前在 Swift 2 中,但我将 Xcode 8 与 Swift 3 一起使用。该应用配置为使用旧版 Swift 语言版本。

直到最近,该应用程序才能正常运行。

应用程序要求始终使用该位置的正确权限,并且自动设置正确设置为始终。

我更新了生产应用程序的签名身份,该应用程序停止接收位置更新通知,但仍在开发模式下工作(从 xcode 启动)。

现在我撤销并更新了生产和开发证书,并且应用程序在后台时不会更新位置,而自动设置设置为始终。

应用程序已正确安装,所以我猜证书没问题,但我不明白为什么该位置没有在后台更新。

我在装有 IOS 10.2 的 iPhone 7 上运行该应用程序,xcode 会自动管理签名。

这是我的位置管理器配置:

public class LocationManager : NSObject, ModuleManager, CLLocationManagerDelegate {

    /// The core location manager
    let coreLocationManager: CLLocationManager

    public var datas: JSONable? {
        get {
            return LocationDatas(locations: self.locations)
        }

        set {
            self.locations = newValue == nil ? [Location]() : newValue as? [Location]
        }
    }

    /// The list of locations to send
    private var locations: [Location]?

    /// The last location
    public var lastLocation: Location? {
        return self.locations?.last
    }

    public override init() {

        self.coreLocationManager = CLLocationManager()
        if #available(iOS 9.0, *) {
            self.coreLocationManager.allowsBackgroundLocationUpdates = true
        }
        // The accuracy of the location data.
        self.coreLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
        // The minimum distance (measured in meters) a device must move horizontally before an update event is generated.
        self.coreLocationManager.distanceFilter = 500; // meters
        self.locations = [Location]()

        super.init()
        self.coreLocationManager.delegate = self
        self.locationManager(self.coreLocationManager, didChangeAuthorizationStatus: CLLocationManager.authorizationStatus())

    }

    // MARK: - CLLocationManager Delegate

    public func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        NSLog("location update")
        guard locations.count > 0 else {
            NSLog("Module Location -- no location available")
            return
        }

        // Add all location waiting in the list to send
        self.locations?.appendContentsOf(locations.map { Location(cllocation: $0) })
        SDKManager.manager?.sendHeartbeat()
    }

    public func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch CLLocationManager.authorizationStatus() {
            case .NotDetermined:
                if #available(iOS 8.0, *) {
                    self.coreLocationManager.requestAlwaysAuthorization()
                } else {
                    self.coreLocationManager.startUpdatingLocation()
                }

            case .Denied, .Restricted:
                NSLog("Module Location -- access denied to use the location")

            case .AuthorizedAlways:
                NSLog("AuthorizedAlways")
                self.coreLocationManager.startUpdatingLocation()
                //self.coreLocationManager.startMonitoringSignificantLocationChanges()

            default:
                break
        }
    }

    public func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        NSLog("Module Location -- error : \(error)")
    }
}

locationManager 函数不在后台调用。

这是我的 info.plist:

这是手机上的授权:

位置小箭头始终存在,但没有记录位置更新。

【问题讨论】:

  • 您是否每次都设法调用 startUpdatingLocation()?
  • 是的,始终记录 AuthorizedAlways。
  • 您收到“允许位置”警报了吗?
  • 是的,我收到了警报,我说是的。

标签: ios swift swift3 cllocationmanager


【解决方案1】:

我检查了你的代码,它似乎很好,如果你完成了这些必要的设置,请修改

  1. 在后台模式下启用位置更新
  2. 在您的info.plist 中添加NSLocationAlwaysUsageDescription

如果您没有执行第 1 点,您的应用程序将会崩溃,但如果没有执行第 2 点,您的代码将会通过,但您将永远无法获得更新。

更新:

您的 LocationManager 对象似乎已在 ARC 中发布。您可以尝试通过添加将您的LocationManager 类更改为Singleton

static let sharedInstance = LocationManager()

并像这样在您的代码中访问LocationManager

LocationManager.sharedInstance

【讨论】:

  • 是的,我用手机上的 info.plist 和应用授权的截图更新了原始问题。我的假设是它与证书有关。
  • 我刚看到答案,目前正在尝试。
  • 我更新了代码,启动了,我会在30分钟后查看新位置是否已发送。
  • 唯一的更新已经完成,这要归功于后台获取,但没有位置更新。
  • 同样的问题
【解决方案2】:

您不需要仅在后台更新位置时使用 App 后台刷新。 (充电时可用于其他维护工作,如数据库清理、上传、下载等)

在初始化coreLocationManager时,同时设置以下属性

// It will allow app running location updates in background state
coreLocationManager.allowsBackgroundLocationUpdates = true 

// It will not pause location automatically, you can set it true if you require it. 
coreLocationManager.pausesLocationUpdatesAutomatically = false 

【讨论】:

    猜你喜欢
    • 2019-04-18
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    相关资源
    最近更新 更多