I am adding a mapKit for my app, and I setting the middle of the map to be the persons current location, in lat and lng. I am able to get it working, however, it keeps updating every so often. I only want it to update once when the app is loaded, then not update anymore. Maybe update every 2 minutes. Here is my code:
func locationManager(manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!)
{
var latestLocation = locations.last as! CLLocation
let location = CLLocationCoordinate2D(latitude: latestLocation.coordinate.latitude, longitude: latestLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.015, 0.015)
//Let our point be the center of our span
//region holds value of span and location
let region = MKCoordinateRegion(center: location, span: span)
//set up region on mapView
mapView.setRegion(region, animated: true)
//MKPointAnnotation defines a concrete annotation
let annotation = MKPointAnnotation()
}
If you are targeting only iOS 9, look at the new requestLocation() method. It addresses your problem. If you need to target older versions of iOS, you could add stopMonitoringLocation() to the
func locationManager(
manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!
)
This will stop the monitoring once you get one reading...
I'm not sure what your starting you location manager with, but I think you might want to look at using:
startMonitoringSignificantLocationChanges()
to start your location manager. Here is apple's documentation on the subject: https://developer.apple.com/library/prerelease/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/occ/instm/CLLocationManager/startMonitoringSignificantLocationChanges
Related
I am working on MapKit and core location to display my current GPS location.
The code is working ok but with some problems.
The problem is as follows:
I turn on my app in an open area like on the roadside. The app is able to get my current GPS location and display it on the Map.
I walk into a building with the app on. When inside, I launch the page to show the GPS location. It shows my previous GPS location. As I know, when I am inside the building, the Mapkit and Corelocation should not be able to get GPS. But in this case, it shows my previous GPS data!
I walk out of the building with the app on. In the open space I launch the page to show my current GPS location but the app is unable to get my new GPS location but displays the previous GPS data. In this case the app should fetch a new GPS location. I have to try a few times to launch the page (Navigate from GPS-VC to home-VC, from home click a button to launch the GPS-VC to get GPS).
Why is the GPS so slow even though I am in the open space with good signal strength?
Is there a difference to call these methods:
LocationManager.startUpdatingLocation()
LocationManager.requestLocation()
Here the code:
#IBOutlet weak var Map: MKMapView!
var locationMgr : CLLocationManager!
override func viewDidload(){
if(CLLocationManager.locationServicesEnabled() )
{
locationMgr = CLLocationManager()
locationMgr.delegate = self
locationMgr.desriedAccuracy = kCLLocationAccuracyBest
locationMgr.requestWhenInuseAuthorization()
locationMgr.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLoction: CLLocation = locations[0]
let latitude = userLoction.coordinate.latitude
let longitude = userLoction.coordinate.longitude
let latDelta: CLLocationDegrees = 0.05
let lonDelta: CLLocationDegrees = 0.05
let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(location, span)
let dropin = MKPointAnnotation()
dropin.coordinate = location
droping.title = "Here"
self.Map.setRegion(region, animated: true)
self.Map.addAnnotation(dropin)
self.Map.showsUserLocation = true
}
I'm not sure this will solve all 3 of your issues but I spotted the following issues in your delegate method:
the locations array is sorted in ascending time order so locations.last will contain the most recent location.
This method might be called with old cached values so you need to check the timestamp of the location to decide if it's worth using.
I am making an app with a function as shown here:
func RMC(_ manager: CLLocationManager, locations: [CLLocation]) {
let manager = CLLocationManager()
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.001, 0.001)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
let annotation = MKPointAnnotation()
annotation.coordinate = location.coordinate
mapView.setRegion(region, animated: true)
self.mapView.addAnnotation(annotation)
annotation.title = "My Car"
And I want to activate it in a #IBA function with this code:
RMC(CLLocationManager, locations: [CLLocation])
It comes up with this error:
Cannot convert value of type 'CLLocationManager.Type' to expected argument type 'CLLocationManager'
Please help!
You need to instantiate a CLLocationManager object and pass it in. At your call site right now, you're just referring to the type CLLocationManager instead of passing in an instance of CLLocationManager. You're doing the same in the array of CLLocations, but you generally don't instantiate those yourself. You'll have to change the call to:
RMC(CLLocationManager(), locations: [])
Also, the first line line in your function where you create a new CLLocationManager is redundant and should be removed, as it makes it impossible to use the CLLocationManater object that was passed in (it may be a compiler error, but I haven't tested to make sure)
I'm trying to make an uber-like location picker from a small MKMapView in my class. My problem is the following :
Since I want to have the initial region to be centered at the user current location, I set the initial region inside the location manager function like this:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = (locations.last?.coordinate)!
let latDelta = 0.005
let lonDelta = 0.005
let span:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
let region:MKCoordinateRegion = MKCoordinateRegionMake(locValue, span)
self.locationMap.setRegion(region, animated: false)
}
The problem with this is that every time that the user tries to drag the map region to pick a location, obviously since the location is being always updated and the function is being called at everytime the location is updates, the map region goes back to its initial point as the function above states.
Another thing is that if I try to extract the locValue variable and assign it to a instance variable of the class within the function adding a line like this :
self.userLocation = locValue
self.userLocation won't change. If you have any suggestion on how to get a single location without updating it or how to fix either one of these problems it would be really appreciated if you could let me know.
Thanks.
I am trying to make a app where everyone can see everyones location at the same map. I can't find any tutorials on how to retrieve ALL users location on the same map.
I have manage to make a script which uploads the users location into Parse with this script:
PFGeoPoint.geoPointForCurrentLocationInBackground {
(geoPoint: PFGeoPoint?, Error : NSError?) -> Void in
if let geoPoint = geoPoint{
PFUser.currentUser()? ["location"] = geoPoint
PFUser.currentUser()?.saveInBackground()
I have also manage to get the location of the current user.
Any one know how i can display everyones location, not just mine?
Thank you for your time and help. I am very new to Swift so let me know if i need to provide more information.
Here is my display code.
PFGeoPoint.geoPointForCurrentLocationInBackground {
(geoPoint: PFGeoPoint?, Error : NSError?) -> Void in
if let geoPoint = geoPoint{
PFUser.currentUser()? ["location"] = geoPoint
PFUser.currentUser()?.saveInBackground()
self.MapView?.showsUserLocation = true
self.MapView?.delegate = self
MapViewLocationManager.delegate = self
MapViewLocationManager.startUpdatingLocation()
self.MapView?.setUserTrackingMode(MKUserTrackingMode.Follow, animated: false)
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled(){
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocationManager]){
var locValue:CLLocationCoordinate2D = (manager.location?.coordinate)!
print("locations = \(locValue.latitude) \(locValue.longitude)")
Outside ViewWDidLoad
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
self.MapView?.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
To get all users location is not so simple as you think. The most time regular app is working in the background. In the background app can be in background or suspended or terminated state ( about states). And you have to get location from any of these states. How is it possible: you should enable Background Mode for location tracking for your app. To do it simpler - use significant location tracking for all users, but accuracy will be about 500m. To get more accuracy (but more difficult implementation) you can send silent push notification to users (about silent push), it wakes up app from terminated or suspended states to background state, and now you can get and send users current location to your server.
Using the following code, my currentLat and currentLong are not updating beyond the first location. locations never has more than 1 item, and it's always exactly the same.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let loc: CLLocation = locations[locations.count - 1]
currentLat = loc.coordinate.latitude
currentLong = loc.coordinate.longitude
}
All the searching I've been doing has only shown how to get it to work if it doesn't work at all, but this DOES work, but only once.
The way I expect this to work is to continuously update the GPS coordinates and fire this delegate off whenever the location is updated. Does the location keep updating the entire time? I thought it would due to the terminology of "startUpdatingLocation()" and there being a "stopUpdatingLocation()." Am I trying to use this incorrectly?
Like I said, it works for the first time, so it's loaded and started just fine, the permissions are allowed, the info.plist has the necessary entries.
When you want to update your location, you should stop existing update once it got new location. You can use stopUpdatingLocation() in your didUpdateLocations: method to do so.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// This should match your CLLocationManager()
locManager.stopUpdatingLocation()
let loc: CLLocation = locations[locations.count - 1]
currentLat = loc.coordinate.latitude
currentLong = loc.coordinate.longitude
}
Then call your locManager.startUpdatingLocation() when you need new location.