4: Create a function in MapViewController class for build and add button to MKViewMap, this have an UIView parameter, this is intended for be as a reference for our magical button
Thanks for the solution. I had trouble creating the button. For the button action I don’t know why mapView.showsUserLocation does not fire the delegate function every time. This worked for me instead.
I’ve tried thousands of times. My code is right but nothing happens when I press the button. When I write the code for the first time and run the simulator, it asks me the request (but after that the button does nothing). When I run simulator again, it even doesn’t show the message. I’m totally mad because I have checked anything including adding CoreLibrary framework, and text in info.plist. Does anybody have any ideas what can be wrong?
Hi friends,
I am stuck on this Silver challenge.
I got the following error and I am not sure why. I tried adding “var” in front of locationManager = CLLocationManager(), but nothing works.
dicarlomagnus, Just out of curiosity , what crumb trail did you follow to figure out a info.plist key was needed for this challenge?
Well, think I answered this on my own trying to do it without having an info.plist entry.
I have this in the console, which is the beginning of a bread crumb trail for me:
2017-03-31 11:38:32.121700-0400 WorldTrotter[2293:623583] This app has attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSLocationWhenInUseUsageDescription key with a string value explaining to the user how the app uses this data
Weird I’ve added the Info.plist entry “Privacy - Location When In Use Usage Description”, with a string value describing that I’m showing the user’s location, but the app compiles and still gives the same error even after saving the plist file and deleting the app off my phone prior to trying it.
2017-03-31 13:05:04.244882-0400 WorldTrotter[2372:648856] This app has attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSLocationWhenInUseUsageDescription key with a string value explaining to the user how the app uses this data
Is there some other step that clears this besides adding the key/value string to Info.plist?
note: pasting in a key name as “NSLocationWhenInUseUsageDescription” just converts immediately to the text indicated below for the key name.
I’m having the same issue as others, where nothing happens when I press the Localization button. Any help would be much appreciated. My code is as follows:
import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
var mapView: MKMapView!
var locationManager: CLLocationManager?
override func loadView() {
// Create a map view
mapView = MKMapView()
mapView.delegate = self
locationManager = CLLocationManager()
locationManager!.delegate = self
// Set it as *the* view of this view controller
view = mapView
let segmentedControl = UISegmentedControl(items: ["Standard", "Hybrid", "Satellite"])
segmentedControl.backgroundColor = UIColor.white.withAlphaComponent(0.5)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: #selector(MapViewController.mapTypeChanged(_:)), for: .valueChanged)
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(segmentedControl)
let topConstraint = segmentedControl.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8)
let margins = view.layoutMarginsGuide
let leadingConstraint = segmentedControl.leadingAnchor.constraint(equalTo: margins.leadingAnchor)
let trailingConstraint = segmentedControl.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
topConstraint.isActive = true
leadingConstraint.isActive = true
trailingConstraint.isActive = true
initLocalizationButton(segmentedControl)
}
override func viewDidLoad() {
super.viewDidLoad()
print("MapViewController loaded its view.")
}
func mapTypeChanged(_ segControl: UISegmentedControl) {
switch segControl.selectedSegmentIndex {
case 0:
mapView.mapType = .standard
case 1:
mapView.mapType = .hybrid
case 2:
mapView.mapType = .satellite
default:
break
}
}
func initLocalizationButton(_ anyView: UIView!){
let localizationButton = UIButton.init(type: .system)
localizationButton.setTitle("Localization", for: .normal)
localizationButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(localizationButton)
//Constraints
let topConstraint = localizationButton.topAnchor.constraint(equalTo:anyView
.topAnchor, constant: 32 )
let leadingConstraint = localizationButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor)
let trailingConstraint = localizationButton.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor)
topConstraint.isActive = true
leadingConstraint.isActive = true
trailingConstraint.isActive = true
localizationButton.addTarget(self, action: #selector(MapViewController.showLocalization(sender:)), for: .touchUpInside)
}
func showLocalization(sender: UIButton!){
locationManager!.requestWhenInUseAuthorization()//se agrega permiso en info.plist
mapView.showsUserLocation = true //fire up the method mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation)
mapView.userTrackingMode = .follow
}
// func showLocalization(sender: UIButton!) {
// locationManager?.requestWhenInUseAuthorization()
// self.mapView(mapView, didUpdate: location)
// }
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//This is a method from MKMapViewDelegate, fires up when the user`s location changes
let zoomedInCurrentLocation = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 500, 500)
mapView.setRegion(zoomedInCurrentLocation, animated: true)
}
}
I figured out my problem, hopefully this may help others as well: you have to set what the location of the simulator actually is. You do this by editing the scheme and selecting a location, similarly to how you change the language and international number formatting.
Same problem happened to me. It seems that mapView.showUserLocation = true is not triggering the given method. I recommend use mapView.userTrackingMode = .follow it works great
I figured out my problem, hopefully this may help others as well: you have to set what the location of the simulator actually is. You do this by editing the scheme and selecting a location, similarly to how you change the language and international number formatting.
Hmm, what screen should I be looking at for this option?
So under the default settings/conditions of the project, only a few major cities can be selected right? When I click localization, it will go to the default location that I selected: Sydney, Australia; San Francisco, CA, etc. so I don’t see it zoom on my current location.
I see an option to add a GPX file to the project for additional cities.
Finally called this method that exists in MKMapViewDelegate
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
let latitude = userLocation.coordinate.latitude
let longitude = userLocation.coordinate.longitude
let center = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
let region = MKCoordinateRegion(center: center, span: span)
mapView.setRegion(region, animated: true)
}