第一次在 Swift2 中映射不读取代码 iOS9

Map not reading code first time in Swift2 iOS9

我正在尝试在我的地图中显示一些商店并且它工作正常(用户第二次访问该 MapViewController,但第一次(当它请求用户许可位置时)它只显示用户位置和地图不在用户位置 "zoomed"。

我要展示我的代码,它非常简单明了:

更新了新代码(它仍然无法正常工作,"didChangeAuthorizationStatus" 没有打印任何东西:

import UIKit
import MapKit

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

let LoadURL = "http://www.website.es/shops.json"

var coordinates = CLLocation()

@IBOutlet weak var mapView:MKMapView!

var farmacia = [Farmacia]()

let locationManager = CLLocationManager()

var currentLocation = CLLocation()

var latitudeValor = String()

var longitudeValor = String()

override func viewDidLoad() {

    super.viewDidLoad()

    locationManager.delegate = self

    // Request for a user's authorization for location services
    locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.startUpdatingLocation()
        requestLocation()
    }
}

func requestLocation () {

    let status = CLLocationManager.authorizationStatus()

    if status == CLAuthorizationStatus.AuthorizedWhenInUse || status == CLAuthorizationStatus.AuthorizedAlways {
        self.mapView.showsUserLocation = true

        var currentLocation = CLLocation()

        print(locationManager.location)

        if locationManager.location != nil
        {
            currentLocation = locationManager.location!
            let center = CLLocationCoordinate2D(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)
            let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))

            latitudeValor = String(currentLocation.coordinate.latitude)
            longitudeValor = String(currentLocation.coordinate.longitude)

            self.mapView.setRegion(region, animated: true)

            requestPost()

            mapView.delegate = self
        }
    }
}

func locationManager(locationManager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {

    switch status {

        case .NotDetermined:
            self.locationManager.requestWhenInUseAuthorization()
            break
        case .AuthorizedWhenInUse:
            self.locationManager.startUpdatingLocation()
            requestLocation()
            break
        case .AuthorizedAlways:
            self.locationManager.startUpdatingLocation()
            requestLocation()
            break
        case .Restricted:
            // restricted by e.g. parental controls. User can't enable Location Services
            break
        case .Denied:
            // user denied your app access to Location Services, but can grant access from Settings.app
            break
    }
}

/*
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

    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)

    requestPost()

    mapView.delegate = self
}
*/

func requestPost () {

    let myUrl = NSURL(string: "http://www.website.es/shops_by_position.php");

    let request = NSMutableURLRequest(URL:myUrl!);
    request.HTTPMethod = "POST"

    let postString = "latitude="+latitudeValor+"&longitude="+longitudeValor
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

        // JSON RESULTADO ENTERO
        //let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        //print("responseString = \(responseString)")

        if error != nil
        {
            //print("error=\(error)")
            return
        }
        else
        {
            self.farmacia = self.parseJsonData(data!)
        }
    }

    task.resume()
}

func parseJsonData(data: NSData) -> [Farmacia] {

    let farmacias = [Farmacia]()

    do {
        let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary

        // Parse JSON data
        let jsonProductos = jsonResult?["farmacias"] as! [AnyObject]

        //print(jsonProductos)

        for jsonProducto in jsonProductos {

            let farmacia = Farmacia()
            farmacia.id = jsonProducto["id"] as! String
            farmacia.nombre = jsonProducto["nombre"] as! String

            farmacia.latitude = jsonProducto["latitude"] as! String
            farmacia.longitude = jsonProducto["longitude"] as! String

            let stringLat = NSString(string: farmacia.latitude)
            let stringLon = NSString(string: farmacia.longitude)

            let latitude: CLLocationDegrees = stringLat.doubleValue
            let longitude: CLLocationDegrees = stringLon.doubleValue

            coordinates = CLLocation(latitude: latitude,longitude: longitude)

            let geoCoder = CLGeocoder()

            geoCoder.reverseGeocodeLocation(coordinates, completionHandler: { placemarks, error in

                if error != nil
                {
                    //print(error)
                    return
                }
                else
                {
                    if placemarks != nil && placemarks!.count > 0 {

                        let placemark = placemarks?[0]

                        // Add Annotation
                        let annotation = MKPointAnnotation()
                        annotation.title = farmacia.nombre
                        annotation.coordinate = placemark!.location!.coordinate

                        self.mapView.addAnnotation(annotation)
                    }

                }

            })
        }
    }
    catch let parseError {
        print(parseError)
    }

    return farmacias
}

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    let identifier = "MyPin"

    if annotation.isKindOfClass(MKUserLocation) {
        return nil
    }

    let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure)

    // Reuse the annotation if possible
    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

    if annotationView == nil
    {
        annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin")
        annotationView!.canShowCallout = true
        annotationView!.image = UIImage(named: "pin.png")
        annotationView!.rightCalloutAccessoryView = detailButton
    }
    else
    {
        annotationView!.annotation = annotation
    }

    return annotationView
}

func mapView(mapView: MKMapView, annotationView: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    if control == annotationView.rightCalloutAccessoryView {
        performSegueWithIdentifier("PinDetail2", sender: annotationView)
    }
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "PinDetail" {
        let destinationController = segue.destinationViewController as! FarmaciaDetailViewController
        destinationController.titulo_farmacia = (sender as! MKAnnotationView).annotation!.title!
    }
    if segue.identifier == "PinDetail2" {
        let destinationController = segue.destinationViewController as! FarmaciaWebDetailViewController
        destinationController.nombre_farmacia = (sender as! MKAnnotationView).annotation!.title!
    }
}

@IBAction func cancelToMap(segue:UIStoryboardSegue) {

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

我的问题是: 我必须更改什么才能在应用程序第一次请求许可并且用户选择时显示用户位置缩放和我的商店条目"Yes"?

这是我第一次使用 MapKit 框架,我有点迷茫,如果你能给我一些启发,我将不胜感激。

requestWhenInUseAuthorization 的文档说

When the current authorization status is kCLAuthorizationStatusNotDetermined, this method runs asynchronously and prompts the user to grant permission to the app to use location services.

所以在你的代码中,请求授权然后立即继续执行,最终到达

if status == CLAuthorizationStatus.AuthorizedWhenInUse

失败,状态还未确定。

CLLocationManagerDelegate 中有 locationManager:didChangeAuthorizationStatus: 回调,一旦用户允许或拒绝位置访问,就会调用该回调。

我建议您将 .AuthorizedWhenInUse 案例的逻辑移动到一个函数中,并在授权已授予的情况下从您的 viewDidLoad 方法调用它,或者在授权尚未授予时从回调中调用它。

1) 改变

class MapViewController: UIViewController, MKMapViewDelegate {

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

2) 改变

func locationManager(locationManager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {

switch status {

    case .NotDetermined:
        self.locationManager.requestAlwaysAuthorization()

        self.locationManager.requestWhenInUseAuthorization()

3) 将 NSLocationWhenInUseUsageDescription 添加到 Info.plist

编辑

4) 添加以下代码到viewDidLoad

locationManager.delegate = self

编辑 2

5) 添加 import 到 header

import CoreLocation