Xcode warning when using MapKit and CoreLocation
You are calling requestWhenInUseAuthorization
, that is true. But are you waiting until you get authorization? No, you are not. You (as the user) are tapping Allow, but that's happening too late: your code has already continued, going straight on to tell the map view to start tracking the user's location.
Just look at the docs on requestWhenInUseAuthorization
:
When the current authorization status is kCLAuthorizationStatusNotDetermined, this method runs asynchronously
Get that? Runs asynchronously. That means that asking for permission happens in the background on another thread.
And the docs go on to say:
After the status is determined, the location manager delivers the results to the delegate’s
locationManager:didChangeAuthorizationStatus:
method
So, implement that method. If you have just obtained permission, that is the signal that you can start using the location manager.
Also, you are missing an important step: you are not checking what the status actually is. You should only be asking for authorization if the status is undetermined. If the status is restricted or denied, you must not use the location manager at all; and if the status is granted, there is no point asking for authorization again.
So, just to sum up, your logical flowchart should be:
Check status.
Is the status Restricted or Denied? Stop. You cannot use get location updates or do location on a map.
Is the status Granted? Proceed to get location updates or do location on a map.
Is the status Undetermined? Request authorization and stop. Treat
locationManager:didChangeAuthorizationStatus:
as the completion handler for your authorization request. At that point, go back to start of the flowchart!
CoreLocation Swift
First,make sure you have this key in plist
Second,request location service in viewDidLoad
,I test with these code
import UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
var manager:CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
manager = CLLocationManager()
manager.delegate = self
if(NSString(string:UIDevice.currentDevice().systemVersion).doubleValue >= 8.0){
manager.requestWhenInUseAuthorization()
}
// Do any additional setup after loading the view, typically from a nib.
}
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus){
print("The authorization status of location " +
"services is changed to: ")
switch CLLocationManager.authorizationStatus(){
case .Denied:
println("Denied")
case .NotDetermined:
println("Not determined")
case .Restricted:
println("Restricted")
default:
println("Authorized")
}
}
And get output
You have to run this on device and if you can not get alert,try uninstall the app,then run again
Problems drawing poly Line in Map Kit
the problem is not set Map delegate object, also I made some changes to add polyline overlay. Simple but it is working. Good luck.
Maps.delegate = self
Code file:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate,MKMapViewDelegate {
@IBOutlet var Maps: MKMapView!
var locationManager = CLLocationManager()
var coordenadas = CLLocationCoordinate2D()
var startPoint = MKDirections.Request()
var ArrayDeCoordenadas: [CLLocationCoordinate2D] = []
var tap: Int = 0
var journeyPolyline: MKPolyline?
func getDirections(){
let request = MKDirections.Request()
request.source = MKMapItem.forCurrentLocation()
request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
directions.calculate { (response, error) in
if error != nil {
print("Error \(error)")
} else {
//self.dispLayRout(response)
var overlays = self.Maps.overlays
self.Maps.removeOverlays(overlays)
for route in response!.routes as! [MKRoute] {
self.Maps.addOverlay(route.polyline,
level: MKOverlayLevel.aboveRoads)
var instructionNumber = 0
for next in route.steps {
instructionNumber += 1
print(next.instructions)
}
}
}
}
}
func alertLocation(title: String, Message:String){
let alert = UIAlertController(title: title, message: Message, preferredStyle: .alert)
let actionAlert = UIAlertAction(title: "Acept", style: .default, handler: nil)
alert.addAction(actionAlert)
self.present(alert, animated: true,completion: nil)
}
func LocalizationInit(){
let autorization = CLLocationManager.authorizationStatus()
switch autorization{
case .notDetermined, .restricted:
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
break;
case .restricted, .denied:
alertLocation(title: "We have a Error", Message: "You have your localization restricted.")
case .authorizedAlways,.authorizedWhenInUse:
locationManager.startUpdatingLocation()
break;
default:
break;
}
}
@IBAction func Share(_ sender: UIButton) {
let compartir = UIActivityViewController(activityItems: ["Share baby" as Any],
applicationActivities: nil)
compartir.popoverPresentationController?.sourceView = self.view
present(compartir,animated: true,completion: nil)
}
@IBAction func recordButton(_ sender: UIButton) {
if sender.isSelected != true {
tap += 1
print("tap -> :\(tap)")
if tap == 1{
let annotation = MKPointAnnotation()
annotation.title = "My route"
annotation.subtitle = "I Hoppe"
annotation.coordinate = coordenadas
let annotation2 = MKPointAnnotation()
annotation2.title = "My ride"
annotation2.subtitle = "I Hoppe"
annotation.coordinate = locationManager.location?.coordinate as! CLLocationCoordinate2D
self.Maps.addAnnotation(annotation)
}else if tap == 2 {
tap = 0
locationManager.stopMonitoringSignificantLocationChanges()
}
}
}
@IBAction func mapOptions(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex{
case 0:
Maps.mapType = MKMapType.standard
break;
case 1:
Maps.mapType = MKMapType.satellite
break;
case 2:
Maps.mapType = MKMapType.hybrid
break;
default:
break;
}
}
override func viewDidLoad() {
super.viewDidLoad()
LocalizationInit()
// let polyLineMake = MKPolyline(coordinates: ArrayDeCoordenadas, count: ArrayDeCoordenadas.count)
// self.Maps.addOverlay(polyLineMake, level: .aboveRoads)
Maps.showsUserLocation = true
Maps.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
coordenadas = locations.first!.coordinate as! CLLocationCoordinate2D
ArrayDeCoordenadas.append(locations.last!.coordinate)
print("Array de coordenadas : -> \(ArrayDeCoordenadas)")
let region = MKCoordinateRegion(center: locations.last!.coordinate, latitudinalMeters: 200,
longitudinalMeters: 200)
self.Maps.setRegion(region, animated: false)
let distancia = locations.distance(from: Int(manager.location!.coordinate.latitude), to:
Int((locations.last?.coordinate.latitude)!))
print("distancia \(distancia)")
let polyline = MKPolyline(coordinates: ArrayDeCoordenadas, count: ArrayDeCoordenadas.count)
Maps.addOverlay(polyline)
//remove old polyline
if let oldPolyline = journeyPolyline {
Maps.removeOverlay(oldPolyline)
}
journeyPolyline = polyline
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation{
return nil
}
let pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "My personal pin")
pin.pinTintColor = UIColor.green
return pin
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline{
let polyline = overlay
let polyLineRender = MKPolylineRenderer(overlay: polyline)
print(" se esta generando \(polyline)")
polyLineRender.strokeColor = UIColor.red
polyLineRender.lineWidth = 6.0
return polyLineRender
}
print(" no se esta generando")
return MKPolylineRenderer()
}
}
User location in mapView doesn't show on several simulator devices (MapKit)
I ended up solving my own question.
I just added this line of code in viewDidLoad:
[self.locationManager requestWhenInUseAuthorization];
This was very helpful: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
Related Topics
Nsgenericexception Reason Collection <Nsconcretemaptable: Xxx>
Uiimagejpegrepresentation Received Memory Warning
iPhone Storage in Tmp Directory
Simple Low-Latency Audio Playback in iOS Swift
What Is the Swift Equivalent of Makeobjectsperformselector
Setting Image for Uibarbuttonitem - Image Stretched
How to Pass Information Between Storyboard Segues
How to Scroll to a Particluar Index in Collection View in Swift
Error Itms-90086 Submitting App
Nsnotificationcenter Swift 3.0 on Keyboard Show and Hide
Perform a Deeplink from Swiftui Widget on Tap
How to Disable iPhone 6 Native Resolution
Swift iOS9 New Contacts Framework - How to Retrieve Only Cncontact That Has a Valid Email Address
Deferredlocationupdatesavailable Returns No in iOS 10
Uisearchdisplaycontroller Without Dimming
No Suitable Records Were Found Verify Your Bundle Identifier Is Correct