在后台Swift中发送用户的位置

时间:2017-04-05 21:42:46

标签: ios swift firebase firebase-realtime-database core-location

我正在构建一个用户单击按钮的应用程序,并且我们通过将其位置上传到服务器来跟踪它们60分钟(或任何时间)。目前,我们正在使用“更新位置”和“#39;用于将用户位置实时发送到firebase。

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

}

此系统可以正常工作,但它会每秒向服务器发送一次将用户位置发送到服务器的服务器。

这是太多的数据,我们只需要每10-30秒就将用户位置发送到服务器一次。

我们可以做什么,每10-30秒发送一次用户位置?

3 个答案:

答案 0 :(得分:4)

class ViewController: UIViewController, CLLocationManagerDelegate {
    private var locman = CLLocationManager()
    private var startTime: Date? //An instance variable, will be used as a previous location time.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    guard let loc = locations.last else { return }

    let time = loc.timestamp

    guard let startTime = startTime else {
        self.startTime = time // Saving time of first location, so we could use it to compare later with second location time.
        return //Returning from this function, as at this moment we don't have second location. 
    }

    let elapsed = time.timeIntervalSince(startTime) // Calculating time interval between first and second (previously saved) locations timestamps.

    if elapsed > 30 { //If time interval is more than 30 seconds
        print("Upload updated location to server")
        updateUser(location: loc) //user function which uploads user location or coordinate to server.

        startTime = time //Changing our timestamp of previous location to timestamp of location we already uploaded.

    }
}

答案 1 :(得分:0)

应用程序通常会在移动到后台后暂停(不再获得CPU时间)。你可以要求额外的背景时间,但系统只给你3分钟。

只允许非常有限的一类应用程序在后台运行更长时间。地图/ GPS应用程序是这些类别之一。但是,您的应用程序不是地图/ GPS应用程序,因此我怀疑Apple是否会批准它。

结论:我认为运行您的位置查询可能会超过3分钟。

答案 2 :(得分:0)

import UIKit
import CoreLocation
@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate,CLLocationManagerDelegate {
var window: UIWindow?
var locationManager = CLLocationManager()
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var bgtimer = Timer()
var latitude: Double = 0.0
var longitude: Double = 0.0
var current_time = NSDate().timeIntervalSince1970
var timer = Timer()
var f = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.doBackgroundTask()
    return true
}


func applicationWillResignActive(_ application: UIApplication) {
}

func applicationWillEnterForeground(_ application: UIApplication) {
    print("Entering foreBackground")
}

func applicationDidBecomeActive(_ application: UIApplication) {
}

func applicationWillTerminate(_ application: UIApplication) {
}

func applicationDidEnterBackground(_ application: UIApplication) {
    print("Entering Background")
   // self.doBackgroundTask()
}

func doBackgroundTask() {

    DispatchQueue.main.async {

        self.beginBackgroundUpdateTask()

        self.StartupdateLocation()


        self.bgtimer = Timer.scheduledTimer(timeInterval:-1, target: self, selector: #selector(AppDelegate.bgtimer(_:)), userInfo: nil, repeats: true)
        RunLoop.current.add(self.bgtimer, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        self.endBackgroundUpdateTask()

    }
}

func beginBackgroundUpdateTask() {
    self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

func StartupdateLocation() {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = kCLDistanceFilterNone
    locationManager.requestAlwaysAuthorization()
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("Error while requesting new coordinates")
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let locValue:CLLocationCoordinate2D = manager.location!.coordinate

    self.latitude = locValue.latitude
    self.longitude = locValue.longitude
    f+=1
    print("New Coordinates: \(f) ")
    print(self.latitude)
    print(self.longitude)
}

@objc func bgtimer(_ timer:Timer!){
    sleep(2)
  /*  if UIApplication.shared.applicationState == .active {
         timer.invalidate()
    }*/
    self.updateLocation()
}

func updateLocation() {
    self.locationManager.startUpdatingLocation()
    self.locationManager.stopUpdatingLocation()
}}

我添加了睡眠功能以延迟调用该位置并将信息发送到服务器

由于此操作正在运行,因此应用程序处于活动状态并转到后台。如果只需要后台进程,请从didFinishLaunchingWithOptions中删除或注释函数self.doBackgroundTask(),并在applicationdidEnterBackground中删除self.doBackgroundTask()的注释。然后删除函数bgtimer()中的注释,因为一旦应用程序进入活动状态,后台进程就必须停止。