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)
Related
I have a simple goal of my app that is get the current coordinate, and use them to add an annotation on the mapview.
I have been tried lots of solution from google results, but its still not working....
The debug area never shows "locationManager did UpdateLocation", the message what I print in function....
It's seems like the app never run "did UpdateLocation" function, even startUpdatingLocation() has been called?
Add location privacy string in info.plist : Done.
Turn on the GPS on my Mac Pro : Done.
Xcode version : 10.1
MacOS : 10.13.6 (High Sierra)
let cloaction = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
MapView.delegate = self
MapView.showsScale = true
MapView.showsPointsOfInterest = true
MapView.showsUserLocation = true
cloaction.requestAlwaysAuthorization()
cloaction.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
print("IN")
cloaction.delegate = self
cloaction.desiredAccuracy = kCLLocationAccuracyBest
cloaction.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locationManager did UpdateLocation")
let location = CLLocationCoordinate2D(latitude: (locations.first?.coordinate.latitude)!, longitude: (locations.first?.coordinate.longitude)!)
currentLat = (locations.first?.coordinate.latitude)!
currentLon = (locations.first?.coordinate.longitude)!
let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
MapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2DMake(currentLat,currentLon), span: span), animated: true)
MapView.showsUserLocation = true
print(locations.first?.coordinate.latitude)
print(locations.first?.coordinate.longitude)
}
Actually the reason is very simple: You call the didUpdateLocation mehthod wich is only called when you change your location. Your Mac is on certain place and dont move so thats why it is not working.
Have you import CoreLocation?
Start with making a variable let myLocation = CLLocation()
Instead of have so much in viewDidLoad you can make a function and call the mLocation in viewDidLoad instead :
func mLocation(){
cloaction.delegate = self
cloaction.desiredAccuracy = kCLLocationAccuracyBest
cloaction.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled(){
cloaction.startUpdatingLocation()
}
}
And thats all you need for the clocation
LocationManager could also be updated
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:[CLLocation]){
let newLocation = locations[0]
print("\(myLocation.coordinate.latitude)")
print("\(myLocation.coordinate.longitude)")
}
Yes! finally... thank your answering, it's really need to run on device, thanks Kosuke Ogawa's suggestion, and every one's guide, I am a new to learn swift, and first time ask question here, it's fun, thank you every one.
(But I don't know how to accept a answer if the answer is a comment? Someone teach me how do that?)
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'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.
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