My simple map project doesn't get & show my location in simulator - ios

I am using XCode v7.2.1, Simulator v9.2 .
I have a UIViewController which shows a map & is supposed to get my location & show it on map:
import UIKit
import MapKit
class LocationVC: UIViewController, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
}
override func viewDidAppear(animated: Bool) {
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
map.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
}
I have added the NSLocationWhenInUseUsageDescription in info.plist as shown below:
I have also selected the Debug -> Location -> Custom Location ... and set the longitude & latitude of Helsinki, Finland as shown below:
When I run my app, the map is shown, however it doesn't get my location. Why? (I mean I don't see the blue point in anywhere of the map).
===== UPDATE ====
I also tried this when my app is running, however it doesn't help either.

you are requesting the user's location, but not actually doing anything with the response. become the delegate of the location manager and respond to the authorization change.
this code works for me on 7.2.1 (after selecting "Apple" in Debug -> Location):
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
map.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
guard status == .AuthorizedWhenInUse else { print("not enabled"); return }
map.showsUserLocation = true
}
}

I agree with #Casey 's answer,but sometimes you need to do a little more with CLLocationManagerDelegate method.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
//reset mapView's center in case your custom location was wrong.
map.centerCoordinate = location.coordinate
//mannual call show annotations to avoid some bugs
map.showAnnotations(map.annotations, animated: true)
}
}

you just have to add
locationManager.delegate = self
mapView.showsUserLocation = true

Related

Declaration is only valid at file scope how to fix?

I have a Problem in my swift file.
Im trying to follow a tutorial on Youtube and he doesn't get the error.
Here is the code:
class ViewController: UIViewController, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
private var currentLocation: CLLocationCoordinate2D?
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
configerLocationServices()
}
private func configerLocationServices() {
locationManager.delegate = self
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined {
locationManager.requestWhenInUseAuthorization()
} else if status == .authorizedAlways || status == .authorizedWhenInUse {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
extension ViewController: CLLocationManagerDelegate { //Error: Declaration is only valid at file scope
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Did get latest Lcation")
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print("The Status changed")
}
}
}
I don't know what im doing wrong, has anyone a solution?
Thank you in advance.
Thats because you have declared an extension inside your class. Move it outside the class and compiler will stop complaining
class ViewController: UIViewController {
private let locationManager = CLLocationManager()
private var currentLocation: CLLocationCoordinate2D?
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
configerLocationServices()
}
private func configerLocationServices() {
locationManager.delegate = self
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined {
locationManager.requestWhenInUseAuthorization()
} else if status == .authorizedAlways || status == .authorizedWhenInUse {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Did get latest Lcation")
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print("The Status changed")
}
}
You have clearly confirmed to CLLocationManagerDelegate in your ViewController extension so you dont need to confirm it in class declaration (this will result in compiler giving you a warning that duplicate confirmation to protocol) so change class ViewController: UIViewController, CLLocationManagerDelegate to class ViewController: UIViewController
Remove CLLocationManagerDelegate declaration in class ViewController: UIViewController, CLLocationManagerDelegate line. Also, make sure that you set all pairs of curly braces correctly, I mean open and close in proper places

locationManager.location returns nil

i am using swift4.2 and Xcode 10 and i am trying to make iOS app uses location service and it gives me exception: Fatal error: Unexpectedly found nil while unwrapping an Optional value
so i tried to check if location returns nil so i copy my code and print location and it returns null , i simulated location in Xcode from product>scheme>edit scheme>default location and checked location in debug area and it simulated to location i choose any one know the problem?
import CoreLocation
class LocationVC: UIViewController,CLLocationManagerDelegate {
let locationManager = CLLocationManager()
var currentlocation:CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startMonitoringSignificantLocationChanges()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
authorizelocationstates()
}
func authorizelocationstates(){
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentlocation = locationManager.location
print(currentlocation)
}
else{
locationManager.requestWhenInUseAuthorization()
authorizelocationstates()
}
}
I have run your code and I just added missing key Privacy - Location When In Use Usage Description in info.plist file.
And I have made some changes in your code and get nil value because method getting called multiple time and when user give permission and method again called and going to print location detail but the fact is stilllocationManager variable has not user location data yet.
get location details in locationManager when delegate didUpdateLocations called
I have done some changes in your code:
import UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var currentlocation:CLLocation!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// authorizelocationstates()
}
func authorizelocationstates(){
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentlocation = locationManager.location
print(currentlocation)
}
else{
// Note : This function is overlap permission
// locationManager.requestWhenInUseAuthorization()
// authorizelocationstates()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locationManager = manager
// Only called when variable have location data
authorizelocationstates()
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Get Location Permission one time only
locationManager.requestWhenInUseAuthorization()
// Need to update location and get location data in locationManager object with delegate
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
}
}
Hope it will help you.

Making an app using swift that gets user's location

I ran my code for getting the user's location and this is the error I get. Can someone please help me figure it out?
My code is as follows:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var citybtn: UIButton!
#IBOutlet weak var citylbl: UILabel!
let locationManager = CLLocationManager()
var currentLocation : CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Used to start getting the users location
//let locationManager = CLLocationManager()
// For use when the app is open
//locationManager.requestAlwaysAuthorization()
// If location services is enabled get the users location
//if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest // You can change the locaiton accuary here.
locationManager.requestWhenInUseAuthorization()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
locationAuthStatus()
}
func locationAuthStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentLocation = locationManager.location
print(currentLocation.coordinate.latitude)
print(currentLocation.coordinate.longitude)
} else {
locationManager.requestWhenInUseAuthorization()
locationAuthStatus()
}
}
#IBAction func buttonpresses(_ sender: Any) {
}
}
sounds like you did not enable the location update capability of your target:
choose target
select capabilities
in Background Modes, tick Location updates

CLLocation manager not working iOS 8

I'm trying to follow this Google Maps tutorial: http://www.raywenderlich.com/81103/introduction-google-maps-ios-sdk-swift
Like many others I have hit a roadblock where CLLocationManager does not seem to fire startUpdatingLocation().
I have updated the pList with NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription in accordance with Location Services not working in iOS 8, but still no location being fired.
Code below - any help is appreciated!
import UIKit
class MapViewController: UIViewController, TypesTableViewControllerDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: GMSMapView!
#IBOutlet weak var mapCenterPinImage: UIImageView!
#IBOutlet weak var pinImageVerticalConstraint: NSLayoutConstraint!
var searchedTypes = ["bakery", "bar", "cafe", "grocery_or_supermarket", "restaurant"]
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Types Segue" {
let navigationController = segue.destinationViewController as UINavigationController
let controller = segue.destinationViewController.topViewController as TypesTableViewController
controller.selectedTypes = searchedTypes
controller.delegate = self
}
}
// MARK: - Types Controller Delegate
func typesController(controller: TypesTableViewController, didSelectTypes types: [String]) {
searchedTypes = sorted(controller.selectedTypes)
dismissViewControllerAnimated(true, completion: nil)
}
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .AuthorizedWhenInUse {
println("success") // Works
locationManager.startUpdatingLocation() // Does not seem to fire
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
println("test") // Does not work
println(locations.count) // Does not work
if let location = locations.first as? CLLocation {
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
locationManager.stopUpdatingLocation()
}
}
}
Unbelievable. After a day of testing I found the solution.. Code is fine. Simulation requires that you change the location
Steps:
In Xcode Simulator --> Debug --> Location --> Apple (or whatever..)
Re-run simulation
Google Map will now be centered on where you chose
in your simulation settings (Xcode --> Edit Scheme --> Allow
Simulation + Default Location = New York)
Hope this helps someone else!
The code seems okay also you have mentioned that you have updated info.plist. Can you check with "requestAlwaysAuthorization" instead of "requestWhenInUseAuthorization". Hope it may solve your problem.
You can also refer this link - http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

Google Map SDK, iOS , cannot get myLocation

I'd like to show my location on iOS app by using Google Maps SDK. However, it cannot get my location. I referred the following documents, document1, document2
This is my code. It only shows the map of United Kingdom.
Please help me to solve the problem.
import UIKit
class SearchVC: UIViewController,CLLocationManagerDelegate{
///Google Map
#IBOutlet weak var mapView:GMSMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager:CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus){
if status == .AuthorizedWhenInUse{
locationManager.startUpdatingLocation()
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
func locationManager(manager:CLLocationManager!, didUpdateLocations locations:[AnyObject]!){
if let location = locations.first as? CLLocation{
mapView.camera = GMSCameraPosition(target:location.coordinate, zoom:15,bearing:0, viewingAngle:0)
locationManager.stopUpdatingLocation()
}
}
}
Heres some code to parse your location... I think your just having an issue extracting the location info for the map view to load
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
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
pm.location.coordinate;
mapView.camera = GMSCameraPosition(target:pm.location.coordinate, zoom:15,bearing:0, viewingAngle:0)
locationManager.stopUpdatingLocation()
}else {
println("Error with data")
}
}
I haven't compiled this code and I'm not swift savvy but hopefully this helps
To change your location go to Edit Scheme...
Then select whatever location you want to simulate
The problem:
func locationManager(manager:CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus)
This function is only truly called when the authorization status changes. For instance when you first run the app, it will ask to enable location services. Once you hit yes, this function will run. Next time you run the app, the authorization status won't change, because it was previously enabled.
The fix:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.startUpdatingLocation()
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
Now everytime the view loads, it will start updating location as opposed to when the authorization status changes. Make sure that you also add the key: value pair into info.plist (NSLocationWhenInUseUsageDescription: {authorizatinon message string}).

Resources