简体   繁体   English

我的 iOS 应用程序不会在后台更新位置

[英]My iOS application does not update the location in background

I have an iOS application developed in Swift.我有一个用 Swift 开发的 iOS 应用程序。 My app is currently in Swift 2 but I am using Xcode 8 with Swift 3. The app is configured to use the legacy swift language version.我的应用程序目前使用 Swift 2,但我使用 Xcode 8 和 Swift 3。该应用程序配置为使用旧版 swift 语言版本。

Until recently the app was working correctly.直到最近,该应用程序才能正常工作。

The app asks for the correct rights for always use the location and the autorisation is correctly set to always.该应用程序要求始终使用该位置的正确权限,并且自动设置正确设置为始终。

I renewed the signing identity for the production app and the app stopped to be notified on a location update but was still working in development mode (launched from xcode).我更新了生产应用程序的签名标识,应用程序停止接收位置更新通知,但仍在开发模式下工作(从 xcode 启动)。

Now I revoked and renew the production and development certificate and the app does not update the location while in background whereas the autorisation is set to always.现在我撤销并更新了生产和开发证书,应用程序不会在后台更新位置,而自动设置为始终。

The app is correctly installed so I guess that the certificates are okay but I don't understand why the location is not updated in background.该应用程序已正确安装,所以我猜证书没问题,但我不明白为什么该位置未在后台更新。

I run the app on an iPhone 7 with IOS 10.2 and xcode automatically manage signing.我在带有 IOS 10.2 和 xcode 自动管理签名的 iPhone 7 上运行该应用程序。

Here is my location manager configuration:这是我的位置管理器配置:

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)")
    }
}

The locationManager function is not called in background. locationManager函数不在后台调用。

Here is my info.plist:这是我的 info.plist:

在此处输入图片说明

Here is the authorization on the phone:这是手机上的授权:

在此处输入图片说明

The little location arrow is always there but no location update is logged.小位置箭头始终存在,但没有记录位置更新。

I checked your code and it seems to be fine, revise if you have done these required settings我检查了您的代码,似乎没问题,如果您已完成这些必需的设置,请修改

  1. Enable location updates in Background mode在后台模式下启用位置更新
  2. Add NSLocationAlwaysUsageDescription in your info.plistinfo.plist添加NSLocationAlwaysUsageDescription

If you did not do 1st point you app would have crashed but if did not do 2nd point your code will go through but you will never get updates.如果您没有执行第 1 点,您的应用程序就会崩溃,但如果没有执行第 2 点,您的代码将通过,但您将永远不会获得更新。

Update:更新:

It seems your LocationManager object is released in ARC.看来您的LocationManager对象是在 ARC 中发布的。 Can you try changing your LocationManager class to Singleton by added您可以尝试通过添加将LocationManager类更改为Singleton

static let sharedInstance = LocationManager()

And accessing LocationManager in your code like this并像这样在您的代码中访问LocationManager

LocationManager.sharedInstance

You don't need to use App background Refresh just for Location update in Background.您不需要使用应用程序后台刷新仅用于后台位置更新。 (It can be used for other maintenance work like DB cleaning, uploading, downloading, etc. while charging) (充电时可用于其他维护工作,如DB清理、上传、下载等)

While initializing coreLocationManager , set the following properties as well在初始化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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM