1

I want to ;

Get User Location Every 5 minutes with background modes in Swift 3

But my codes don't any action. I need to get and send server ,longitude , latitude , and altitude values every 5 minutes

My codes under below.

AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    sleep(2)


    BackgroundLocationManager.instance.start()


    return true
}

BackgroundLocationManager - Class

import Foundation
import CoreLocation
import UIKit

class BackgroundLocationManager :NSObject, CLLocationManagerDelegate {

    static let instance = BackgroundLocationManager()
    static let BACKGROUND_TIMER = 15.0 // restart location manager every 150 seconds
    static let UPDATE_SERVER_INTERVAL = 60 * 5 // 5 minutes server send

    let locationManager = CLLocationManager()
    var timer:Timer?
    var currentBgTaskId : UIBackgroundTaskIdentifier?
    var lastLocationDate : NSDate = NSDate()

    private override init(){
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
        locationManager.activityType = .other;
        locationManager.distanceFilter = kCLDistanceFilterNone;
        if #available(iOS 9, *){
            locationManager.allowsBackgroundLocationUpdates = true
        }

        NotificationCenter.default.addObserver(self, selector: #selector(self.applicationEnterBackground), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
    }

    func applicationEnterBackground(){
     //   FileLogger.log("applicationEnterBackground")
        start()
    }

    func start(){
        if(CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways){
            if #available(iOS 9, *){
                locationManager.requestLocation()
            } else {
                locationManager.startUpdatingLocation()
            }
        } else {
            locationManager.requestAlwaysAuthorization()
        }
    }
    func restart (){
        timer?.invalidate()
        timer = nil
        start()
    }

    private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case CLAuthorizationStatus.restricted: break
        //log("Restricted Access to location")
        case CLAuthorizationStatus.denied: break
        //log("User denied access to location")
        case CLAuthorizationStatus.notDetermined: break
        //log("Status not determined")
        default:
            //log("startUpdatintLocation")
            if #available(iOS 9, *){
                locationManager.requestLocation()
            } else {
                locationManager.startUpdatingLocation()
            }
        }
    }
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        if(timer==nil){
            // The locations array is sorted in chronologically ascending order, so the
            // last element is the most recent
            guard locations.last != nil else {return}

            beginNewBackgroundTask()
            locationManager.stopUpdatingLocation()
            let now = NSDate()
            if(isItTime(now: now)){
                //TODO: Every n minutes do whatever you want with the new location. Like for example sendLocationToServer(location, now:now)
            }
        }
    }


    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
      print(error)

        beginNewBackgroundTask()
        locationManager.stopUpdatingLocation()
    }

    func isItTime(now:NSDate) -> Bool {
        let timePast = now.timeIntervalSince(lastLocationDate as Date)
        let intervalExceeded = Int(timePast) > BackgroundLocationManager.UPDATE_SERVER_INTERVAL
        return intervalExceeded;
    }

    func sendLocationToServer(location:CLLocation, now:NSDate){
        //TODO
    }

    func beginNewBackgroundTask(){
        var previousTaskId = currentBgTaskId;
        currentBgTaskId = UIApplication.shared.beginBackgroundTask(expirationHandler: {
           // FileLogger.log("task expired: ")
        })
        if let taskId = previousTaskId{
            UIApplication.shared.endBackgroundTask(taskId)
            previousTaskId = UIBackgroundTaskInvalid
        }

        timer = Timer.scheduledTimer(timeInterval: BackgroundLocationManager.BACKGROUND_TIMER, target: self, selector: #selector(self.restart),userInfo: nil, repeats: false)
    }
}
SwiftDeveloper
  • 7,244
  • 14
  • 56
  • 85
  • see this http://stackoverflow.com/questions/10235203/getting-user-location-every-n-minutes-after-app-goes-to-background – Anbu.Karthik Jan 30 '17 at 09:12
  • Timer's don't run in the background. – Paulw11 Jan 30 '17 at 09:54
  • @Paulw11 how can fix it Poul ? ty. – SwiftDeveloper Jan 30 '17 at 09:55
  • You can call `startUpdatingLocation` in the foreground and you will get continuous location updates if you have been granted permission by the user. Using "best" location in the background continuously will drain the battery. Since you are only using "kilometer" accuracy, you can probably just leave the updates running without too much impact. If you only want to report the location every 5 minutes, just keep a variable with the last time you updated the server and only update it again if 5 minutes have passed – Paulw11 Jan 30 '17 at 09:57
  • @Paulw11 ty but can you give me answer for this if it possible ? I didnt do that. – SwiftDeveloper Jan 30 '17 at 10:34

0 Answers0