any one understand why Geo location won't show me where i am, also the permissions don't work over..... I'm baffled... laptop location is fine, also the app permissions are also set, also the Allow permissions tap, box for the user won't appear either
(iv explained this all above and it won't post unless i type more stuff in the box, but could some one explain why this code doesn't work norrr does it display no errors at all, i had also checked - DEBUG - locations... still nothing
import UIKit
import MapKit
import CoreLocation
class MapScreen: UIViewController {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
let regionInMeters: Double = 10000
override func viewDidLoad() {
super.viewDidLoad()
checkLocationServices()
}
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
// Show alert letting the user know they have to turn this on.
}
}
func checkLocationAuthorization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
mapView.showsUserLocation = true
centerViewOnUserLocation()
locationManager.startUpdatingLocation()
break
case .denied:
// Show alert instructing them how to turn on permissions
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
// Show an alert letting them know what's up
break
case .authorizedAlways:
break
}
}
}
extension MapScreen: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let region = MKCoordinateRegion.init(center: location.coordinate, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
}
Did you add the permission strings to your info.plist?
You need to add explanations for these otherwise the permission prompt won't appear, and no location updates will be send to your app.
NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription
You should also get an error for this in your console so check that as well.
Related
I want to send location details when a push notification receives from server. But macos application doesn't ask location permission in launching. Added all privacy items in info.plist. It ask for permission when it calls locationmanager.startUpdatingLocation().And didn't ask again if i cancel it.The code is given below.
class AppDelegate: NSObject, NSApplicationDelegate, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
func applicationDidFinishLaunching(_ aNotification: Notification) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func scanLocationRequest{
locationManager.startUpdatingLocation()
// Call this when a notification receives.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let currentLocation = locations.last
locationManager.stopUpdatingLocation()
sendLocationReport(currentLocation: currentLocation!)
}
}
To check if user have location access or not use following code:
var isPermissionAvailable: Bool {
let status = CLLocationManager.authorizationStatus()
switch status {
case .authorizedAlways, .authorizedWhenInUse:
return true
case .denied, .restricted, .notDetermined:
requestForLocation()
return false
}
}
func requestForLocation() {
// Edit
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
To show pop-up at App launch, you can use following code in applicationDidFinishLaunching(_ aNotification:) in AppDelegate class:
if isPermissionAvailable {
// Do your work on permission available
}
I am trying to access the users coordinates using:
import MapKit
import CoreLocation
override func viewDidLoad() {
super.viewDidLoad()
let locationManager = CLLocationManager()
let userCoordinates = (locationManager.location?.coordinate)!
}
However, it crashes upon the simulator loading. I set the simulator location to Apple, and input privacy keys into info.plist, but I am not sure why this is not grabbing the user location.
There are a few things you need to do first before you can start using a device's current geolocation safely and based on the code you provided I'm going to assume that you might be missing some so here is a common set up using a Google Map, which acts like any other basically:
class YourViewController: UIViewController, CLLocationManagerDelegate {
// properties
var locationManager = CLLocationManager()
var currentCoordinate: CLLocationCoordinate2D?
// load view
override func loadView() {
addLocationManager()
}
// add location manager
func addLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
// location manager delegate: did change authorization
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
print("LOCATION ACCESS RESTRICTED")
case .denied:
print("LOCATION ACCESS DENIED")
case .notDetermined:
print("LOCATION ACCESS NOT DETERMINED")
case .authorizedAlways:
fallthrough
case .authorizedWhenInUse:
print("LOCATION STATUS GRANTED")
}
}
// location manager delegate: did fail with error
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
print("LOCATION ACCESS ERROR: \(error)")
}
// location manager delegate: did update locations
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
// unhide map when current location is available
if mapView.isHidden {
mapView.camera = GMSCameraPosition.camera(withLatitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude, zoom: 18, bearing: 0, viewingAngle: 0)
mapView.isHidden = false
}
// update current location properties
currentCoordinate = lastLocation.coordinate
}
}
And no need to import CoreLocation if you've imported MapKit.
This is working:
geoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973),
forKey: "firebase-hq") { (error) in
if (error != nil) {
println("An error occured: \(error)")
} else {
println("Saved location successfully!")
}
}
But how do I send my current location coordinate to my Firebase? Like this? but currentLocation doesn't work.
geoFire!.setLocation(currentLocation, forKey: "firebase-hq") { (error) in
if (error != nil) {
print("An error occured: \(error)")
} else {
print("Saved location successfully!")
}
Unless it is completely necessary I would recommend not using GeoFire and instead use apple's inbuilt API. First, open your info.plist file as source code and add the following to the file
<key>NSLocationAlwaysUsageDescription</key>
<string>Will you allow this app to always know your location?
</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Do you allow this app to know your current location?</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Will you allow this app to always know your current location?
</string>
Then add this code to your new viewcontroller:
import UIKit
import CoreLocation
class SearchViewController: UIViewController, CLLocationManagerDelegate {
var locationManager:CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
determineMyCurrentLocation()
}
func determineMyCurrentLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
//locationManager.startUpdatingHeading()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
// Call stopUpdatingLocation() to stop listening for location updates,
// other wise this function will be called every time when user location changes.
// manager.stopUpdatingLocation()
print("user latitude = \(userLocation.coordinate.latitude)")
print("user longitude = \(userLocation.coordinate.longitude)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
{
print("Error \(error)")
}
}
This will print the your latitude and longitude as the default current location in your simulator as somewhere in San Francisco. To change this, go into you simulator and go into the debug menu and click location, current location and enter your preferred new values.
I have been surfing the web for methods to get a user's current location in Swift 2.0, Unfortunately none have work. Here is the code I have been working on, but it cannot work. I have been playing with the info.plist file but don't know what to add? Can anyone tell me what I am doing wrong?
import CoreLocation
class ViewController: UIViewController {
let locationManager = CLLocationManager()
override func viewDidLoad(){
super.viewDidLoad()
findMyLocation()
}
func findMyLocation() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("THIS IS THE LATTITUDE \(location.coordinate.latitude)")
}
locationManager.stopUpdatingLocation()
}
}
EDIT: in your didUpdateLocations function don't force stopUpdatingLocation. This function is called multiple times before your location is finalized to be shown on the map. Remove that line and you'll see that your console will print 3-5 times with your lat and long.
The recommended way to get the user location is to always check to make sure you have the permission so that if you don't you can alert the user and ask for said permission.
In your viewDidLoad()
locationManager?.requestAlwaysAuthorization()
// .AuthorizedInUse or .AuthorizedAlways depending on your app
if CLLocationManager.authorizationStatus() == .AuthorizedInUse {
locationManager?.distanceFilter = 5.0
locationManager?.requestLocation()
}
This ensures that you're requesting authorization if there is none and checking if they declined. In addition utilize this function in your CLLocationManagerDelegate
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus)
{
//Again this can be .AuthorizedAlways or .AuthorizedInUse depending
if status == .AuthorizedAlways {
locationManager?.startUpdatingLocation()
// ...
}
}
This allows the app to respond properly if they change the location permissions in the middle of using your location services after the viewDidLoad().
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
centerLocation = location
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
userLocationRegion = region
mainMapView.showAnnotations(mainMapView.annotations, animated: true)
self.mainMapView.setRegion(region, animated: true)
}
you need to add NSLocationWhenInUseUsageDescription or/and NSLocationAlwaysUsageDescription depends on your use case
I am new to app development and I have been trying to create an app which will use core location manager to find the users location and then display it with mapkit. Below is the code I came up with. I haven't been able to fix it, does anyone know what I'm doing wrong? Thanks.
//
// ViewController.swift
// MapKit Test
//
// Created by TMT on 7/11/15.
// Copyright (c) 2015 TMT Inc. All rights reserved.
//
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.showsUserLocation = true
mapView.showsPointsOfInterest = true
mapView.delegate = self
let locationManager = CLLocationManager()
// Ask for Authorisation from the User.
locationManager.requestAlwaysAuthorization()
// For use in foreground
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
#NSCopying var location: CLLocation! { get }
var span = MKCoordinateSpanMake(0.2
, 0.2)
var region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
var request = MKLocalSearchRequest()
request.naturalLanguageQuery = "library"
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You are not handling the delegate method for the location/map. Your code is setting up the map and location frameworks and delegate methods. You have initialized them and told the compiler you want to do something with mapkit/corelocation. So now you need to to handle the delegate methods MKMapViewDelegate, CLLocationManagerDelegate which you have included, and set to self
Place the delegate handling in addition to your code somewhere
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
//Get map location
let location = locations.last as! CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
//Get co ordinates
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
if (error != nil) {
println("Error: " + error.localizedDescription)
return
}
if placemarks.count > 0 {
let pm = placemarks[0] as! CLPlacemark
self.displayLocationInfo(pm)
} else {
println("Error with the data.")
}
})
}
func displayLocationInfo(placemark: CLPlacemark) {
//Remove observer
self.locationManager.stopUpdatingLocation()
println(placemark.locality)
println(placemark.postalCode)
println(placemark.administrativeArea)
println(placemark.country)
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Error: " + error.localizedDescription)
}