【问题标题】:Map not reading code first time in Swift2 iOS9在 Swift2 iOS9 中地图第一次没有读取代码
【发布时间】:2015-10-22 09:40:32
【问题描述】:

我正在尝试在我的地图中显示一些商店,它工作正常(用户第二次访问该 MapViewController,但第一次(当它要求用户许可位置时)它只显示用户位置和地图未在用户位置“放大”。

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

使用新代码更新(它仍然无法正常工作,并且“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.
}
}

我的问题是:为了在应用第一次请求许可并且用户选择“是”时显示放大的用户位置和我的商店条目,我必须进行哪些更改?

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

【问题讨论】:

    标签: swift mapkit swift2 ios9


    【解决方案1】:

    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 添加到标题

    import CoreLocation
    

    【讨论】:

    • 嗨@KosukeOgawa,我已经完成了所有更改,但我又遇到了同样的问题。它显示错误:“尝试在不提示位置授权的情况下启动 MapKit 位置更新。必须先调用 -[CLLocationManager requestWhenInUseAuthorization] 或 -[CLLocationManager requestAlwaysAuthorization]。”
    • @Jordi 在 vi​​ewDidLoad 中添加 locationManager.delegate = self
    • 检查设置 > 隐私 > 定位服务 > 您的应用。 While Using the App 正在显示? photos2.appleinsidercdn.com/gallery/…
    • 请更新您的帖子。我想看最新的代码。
    • 完成,再次感谢您的帮助
    【解决方案2】:

    requestWhenInUseAuthorization 的文档说

    当当前授权状态为 kCLAuthorizationStatusNotDetermined 时,该方法异步运行并提示用户授予应用使用位置服务的权限。

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

    if status == CLAuthorizationStatus.AuthorizedWhenInUse
    

    哪个失败了,at状态还没有确定。

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

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

    【讨论】:

    • 嗨@Mopt,我已经用更多新代码更新了第一条消息。为什么它仍然不起作用?谢谢。
    • 您必须将您的班级设置为位置经理的代表。您应该创建一个位置管理器的实例作为实例变量(如果您仅在 viewDidLoad 中创建一个实例,一旦您退出 viewDidLoad,它将被销毁)并将其委托属性设置为 self。您还必须将您的类声明为符合 CLLocationManagerDelegate 协议。我也可以帮助你,但如果你需要这方面的帮助,我强烈建议你阅读一下 Cocoa 中的委托模式。
    • 嗨@Mopt,我已经用我的 MapViewController 完整代码更新了第一篇文章。我的代码有什么问题?再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 2015-11-07
    • 2016-08-24
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多