I am new to Swift
and i try with this one
How to set accuracy and distance filter when using MKMapView
Don't know why this code not working :
//start mehtod out of scope
lazy var locationManager: CLLocationManager! = {
let locationManager = CLLocationManager()
//configeration for user location access
//The delegate object to receive update events.
locationManager.delegate = self
//The receiver does its best to achieve the requested accuracy
//locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = 10.0
//Requests permission to use location services while the app is in the foreground
locationManager.requestWhenInUseAuthorization()
//allow update notification when apps stay on background
locationManager.allowsBackgroundLocationUpdates = true
return locationManager
}()
it is working fine when i seting :
locationManager.desiredAccuracy = kCLLocationAccuracyBest
So what am i want :
I want to get LAT and LONG after each 250 meter if user change her positioning then continuously 15 minutes call a method
pushLocation(lat:double,long:double)
Here's the code I'm using - all in Swift 3.0.
This setup of the locationManager will take care of the distance filtering and accuracy that you're after:
lazy var locationManager: CLLocationManager = {
[unowned self] in
var _locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.desiredAccuracy = [Your Value For trackingAccuracy - see below]
_locationManager.distanceFilter = [Your Value For the filter i.e., 250 for 250 meters]
_locationManager.allowsBackgroundLocationUpdates = true
_locationManager.pausesLocationUpdatesAutomatically = false
_locationManager.activityType = .fitness
return _locationManager
}()
The accuracy setting would be from the predefined set in location manager, e.g., kCLLocationAccuracyNearestTenMeters or kCLLocationAccuracyHundredMeters.
The option to allow background updates lets you get new points even if your app is not in the foreground. Turning off pauses automatically is necessary if the phone will stop moving from time to time - otherwise, it will automatically turn off capture if your user stops to rest for 5 minutes and won't turn it back on - you must reset these when you're done.
Authorization status should be dealt with in a separate check as follows so that you can request authorization if it's not already given:
if CLLocationManager.authorizationStatus() != .authorizedAlways // Check authorization for location tracking
{
locationManager.requestAlwaysAuthorization() // Will callbackdidChange... once user responds
} else {
locationManager.startUpdatingLocation()
}
Since there's a delay in getting authorization, if you have to make the request you'll need to wait to request it to start updating locations until you hear back from the locationManager, which you can do as follows:
@nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status
{
case .authorizedAlways:
locationManager.startUpdatingLocation()
default:
[Whatever you want to do - you can't get locations]
}
}
I need .authorizedAlways, you may be able to get away with .authorizedWhenInUse depending on your use case.
I add an additional filter for accuracy based on checking the accuracy fields in the positions passed back to me by the locationManager. Note that there's separate horizontal and vertical accuracy values (confidence distance in meters); if you want to use the elevation value you need to pay attention to the second accuracy value as elevation is inherently less accurate in an iPhone.
I also check that the new point was captured after the previous point - out of sequence values come through sometimes and indicate "troubled" values. I've read that you may get accuracy values less than 0 to indicate problems, so you may want to check for that before using the position, though I haven't seen that issue. Here's the code:
// Called back by location manager - passes arrays of new CLLocation points captured. With distanceFilter set to 250, this will get called for a change of 250M. You'll want to save the value for your timed pushLocation function.
// This function needs to be trim as it continues to be called when TrailHead is in the background and, if
// we take too long we'll get killed by iOS.
var savePosition: CLLocationCoordinate2D?
private var latestTimeProcessed = Date() // Initialize to ensure any point accepted received after initialization
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
for location in locations {
if latestTimeProcessed.compare(location.timeStamp) == .orderedAscending // Out of seq indicates a locationManager problem - discard
&& location.horizontalAccuracy < [Whatever accuracy limit you want to use] // Applying a user-selected quality filter
{
latestTimeProcessed = location.timeStamp // Used to discard any earlier timestamped points returned by the location manager
[PROCESS THE POSITION HERE - E.G.]
savePosition = locations.last
}
}
}
As far as doing the push updates, I'd add a timer
private var myTimer: Timer? = nil
private var longInterval = 900.0 // 900 seconds = 15 minutes
override func viewDidLoad()
{
....
myTimer = Timer(timeInterval: timerInterval, target: myself, selector: #selector(myself.pushLocation), userInfo: nil, repeats: true)
RunLoop.current.add(myTimer!, forMode: RunLoopMode.commonModes)
....
}
pushLocation(lat:double,long:double){
[Use savePosition.latitude, savePosition.longitude]
}
Hope this helps...
As per your question , you want to get LAT
and LONG
after each 250 meter ?
So for this Here is Objective C Code
: (Thanks to Link :https://stackoverflow.com/a/39996989/3400991)
First of All Call This method and store this New location and then you need to continuously find other lat and long when any (LAT , LONG) matches with this stored Location then it means you have travelled 250 meter :
Here is SWIFT3.0 Code :
func locationByMovingDistance(distanceMeters: Double, withBearing bearingDegrees: CLLocationDirection) -> CLLocation {
let distanceRadians: Double = distanceMeters / (6372797.6)
// earth radius in meters
let bearingRadians: Double = bearingDegrees * M_PI / 180
var lat1: Float = self.coordinate.latitude * M_PI / 180
var lon1: Float = self.coordinate.longitude * M_PI / 180
var lat2: Float = asin(sin(lat1) * cos(distanceRadians) + cos(lat1) * sin(distanceRadians) * cos(bearingRadians))
var lon2: Float = lon1 + atan2(sin(bearingRadians) * sin(distanceRadians) * cos(lat1), cos(distanceRadians) - sin(lat1) * sin(lat2))
return CLLocation(latitude: lat2 * 180 / M_PI, longitude: lon2 * 180 / M_PI)
}
Feel Free to post comment if you have any further issue. Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With