簡體   English   中英

在后台 Swift 中發送用戶的位置

[英]Send Location of User in Background Swift

我正在構建一個應用程序,用戶點擊一個按鈕,然后我們通過將他們的位置上傳到服務器來跟蹤他們 60 分鍾(或任何時間)。 目前我們正在使用“Did Update Locations”功能將用戶位置實時發送到 Firebase。

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

}

該系統可以工作,但它會向服務器發送垃圾郵件,每秒鍾向服務器發送一次用戶的位置。

這是太多的數據,我們只需要每 10-30 秒將用戶位置發送到服務器一次。

我們可以做些什么每 10-30 秒發送一次用戶位置?

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 var 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.

    }
}
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() 中的注釋,因為一旦應用程序進入活動狀態,后台進程就必須停止。

應用程序在移至后台后通常會暫停(不再獲得 CPU 時間)。 您可以要求額外的后台時間,但系統只給您 3 分鍾。

只有非常有限的一類應用程序被允許在后台運行更長的時間。 地圖/GPS 應用程序是這些類別之一。 但是,您的應用程序不是地圖/GPS 應用程序,因此我懷疑 Apple 是否會批准它。

底線:我認為您運行位置查詢超過 3 分鍾可能不走運。

編輯:

正如 Paulw11 指出的那樣,當設備移動很遠的距離時,您可以使用重要的位置更改服務來獲取位置更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM