如何在后台模式下获取当前位置以及如何在后台模式下将该位置发送到服务器

时间:2019-07-02 10:18:06

标签: ios swift

当应用程序处于后台时,我可以将用户的当前位置发送到服务器吗?例如:在我的应用程序中,我想每2分钟存储一次用户的当前位置,然后将其当前位置发送到服务器。该应用程序在后台运行时可以执行此操作吗?我可以在后台模式下向服务器发送位置更新吗?

2 个答案:

答案 0 :(得分:2)

您可以编辑距离或精度,请确保已检查背景模式中功能的位置。该代码在应用关闭时起作用。如果只需要后台模式,则可以设置计时器并使用UIBackgroundTask发送发帖请求,如以下代码所示。

import UIKit
import Foundation
import CoreLocation

final class LocationManager: NSObject {
    static let shared = LocationManager()

    private var backgroundTask = UIBackgroundTaskIdentifier.invalid
    private let manager = CLLocationManager()    

    func startMonitoring() {
        manager.delegate = self
        manager.pausesLocationUpdatesAutomatically = false        
        manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
        manager.distanceFilter = 1000.0
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
    }

}
extension LocationManager: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) {
        print("LocationManager didStartMonitoringFor")
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("LocationManager \(error)")
    }

    func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
        print("LocationManager \(error)")
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        postLocation(location: locations.first)
    }
}
extension LocationManager {
    private func postLocation(location: CLLocation?) {
        guard let location = location else { return }

        if UIApplication.shared.applicationState == .background {

            backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "test_Location", expirationHandler: {
                UIApplication.shared.endBackgroundTask(self.backgroundTask)
                self.backgroundTask = UIBackgroundTaskIdentifier.invalid
            })

            DispatchQueue.global(qos: .background).async {
                self.postRequest(location: location) { [weak self] in
                    guard let self = self else { return }
                    UIApplication.shared.endBackgroundTask(self.backgroundTask)
                    self.backgroundTask = UIBackgroundTaskIdentifier.invalid
                }
            }
        } else {
            postRequest(location: location)
        }

    }

    private func postRequest(location: CLLocation, completion: (() -> Void)? = nil) {
       // TODO Send Post
    }
}

答案 1 :(得分:0)

您不能保证获得位置的频率
重大更改位置服务和监控位置不会每次都唤醒您的应用程序

如果您需要不时获取用户位置信息,则可以使用(Apple建议的)重要更改位置服务-https://developer.apple.com/documentation/corelocation/getting_the_user_s_location/using_the_significant-change_location_service

使用UIBackgroundTask-发送位置,如果您的位置不变或变化不大,则不要发送位置

本文还可以为您提供帮助
https://badootech.badoo.com/ios-location-tracking-aac4e2323629

P.S。
请勿在Simulator中进行检查。就我而言,在Simulator中,所有功能均表现出色,但在实际设备中,我完全无法唤醒应用程序的频率。
用于调试某些日志文件,使日志尽可能清晰。