2017-06-19 1 views
0

J'ai créé une application iOS en utilisant swift. J'ai mis en place l'emplacement de base et mapview dans mes applications. Pour la première fois, il pourrait fonctionner sans problème (sur simulateur ou iPhone).CLLocationManager plante toujours et retourne une valeur nulle

L'application pourrait fonctionner correctement et pourrait obtenir l'emplacement actuel de mon iPhone. Mais, tout change quand j'essaie d'ajouter l'emplacement GPX dans le Xcode (je veux essayer d'utiliser n'importe quel emplacement avec le fichier GPX). Après avoir ajouté le fichier GPX et l'avoir sélectionné comme emplacement du simulateur, mon application tombe toujours en panne et le CLLocationManager renvoie toujours une valeur nulle.

Je pense que le problème n'existe que pour le simulateur, mais je l'ai fait aussi sur mon iPhone. Le problème persiste même après avoir supprimé le fichier GPX.

Je reçois toujours un 'EXC_BAD_INSTRUCTION' chaque fois que je veux obtenir la valeur de la latitude et de la longitude.

ceci est mon code:

let corLoc = CLLocationManager() 

    //let corLoc2 = CLLocationManager() 


    corLoc.delegate = self 
    let statusLoc = CLLocationManager.authorizationStatus() 
    if statusLoc == .notDetermined{ 
     corLoc.requestWhenInUseAuthorization() 
    } 
    corLoc.desiredAccuracy = kCLLocationAccuracyBest 

    corLoc.startUpdatingLocation() 

    let lokasiAwal = CLLocationCoordinate2D(latitude: (corLoc.location?.coordinate.latitude)!, longitude: (corLoc.location?.coordinate.longitude)!) //<--- always return EXC_BAD_INSTRUCTION 


    let lokasiAkhir = CLLocationCoordinate2D(latitude: -7.299356, longitude: 112.676108) 

pour votre information, auparavant l'application fonctionnait correctement avec ce code

s'il vous plaît aidez-moi

PS: voici mon code complet

class LocationViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate { 


@IBOutlet weak var mapRoute: MKMapView! 
var lokasiAwal2 = CLLocation() 



func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    let userLocation:CLLocation = locations[0] as CLLocation 
    // manager.stopUpdatingLocation() 
    lokasiAwal2 = userLocation 

} 

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

    if status == CLAuthorizationStatus.authorizedWhenInUse || status == CLAuthorizationStatus.authorizedAlways { 

     manager.startUpdatingLocation() 

    } 
} 


override func viewDidLoad() { 
    super.viewDidLoad() 
    mapRoute.delegate = self 

    let corLoc = CLLocationManager() 

    //let corLoc2 = CLLocationManager() 


    corLoc.delegate = self 
    let statusLoc = CLLocationManager.authorizationStatus() 
    if statusLoc == .notDetermined{ 
     corLoc.requestWhenInUseAuthorization() 
    } 
    corLoc.desiredAccuracy = kCLLocationAccuracyBest 

    corLoc.startUpdatingLocation() 

    //let lokasiAwal = CLLocationCoordinate2D(latitude: (corLoc.location?.coordinate.latitude)!, longitude: (corLoc.location?.coordinate.longitude)!) 

    let lokasiAwal = CLLocationCoordinate2D(latitude: lokasiAwal2.coordinate.latitude, longitude: lokasiAwal2.coordinate.longitude) 


    //let lokasiAwal = CLLocationCoordinate2D(latitude: -7.263056, longitude: 112.740317) 

    let lokasiAkhir = CLLocationCoordinate2D(latitude: -7.299356, longitude: 112.676108) 
    //-7.299356, 112.676108 NH 
    //-7.289182, 112.676104 PTC 
    //-7.282713, 112.687633 bandar jakarta 
    //-7.263056, 112.740317 TP 

    //placemark 
    let awalPlaceMark = MKPlacemark(coordinate: lokasiAwal, addressDictionary: nil) 
    let akhirPlaceMark = MKPlacemark(coordinate: lokasiAkhir, addressDictionary: nil) 

    let awalMap = MKMapItem(placemark: awalPlaceMark) 
    let akhirMap = MKMapItem(placemark: akhirPlaceMark) 


    //anotasi 
    let awalAnotasi = MKPointAnnotation() 
    awalAnotasi.title = "Your Location" 


    //let awalPin = MKPinAnnotationView.init(annotation: awalAnotasi, reuseIdentifier: "Your Location") 
    //awalPin.pinTintColor = UIColor.blue 


    if let locationAwal = awalPlaceMark.location { 
     awalAnotasi.coordinate = locationAwal.coordinate 
    } 

    let akhirAnotasi = MKPointAnnotation() 
    akhirAnotasi.title = "National Hospital" 

    if let locationAkhir = akhirPlaceMark.location { 
     akhirAnotasi.coordinate = locationAkhir.coordinate 
    } 

    let awalPin = MyPointAnnotation() 
    awalPin.coordinate = awalAnotasi.coordinate 
    awalPin.pinTintColor = .green 
    awalPin.title = awalAnotasi.title 

    let akhirPin = MyPointAnnotation() 
    akhirPin.coordinate = akhirAnotasi.coordinate 
    akhirPin.pinTintColor = .blue 
    akhirPin.title = akhirAnotasi.title 

    //titik marker 
    self.mapRoute.showAnnotations([awalPin, akhirPin], animated: true) 


    //menambahkan route 
    let directionRequest = MKDirectionsRequest() 
    directionRequest.source = awalMap 
    directionRequest.destination = akhirMap 
    directionRequest.transportType = .automobile 

    let directions = MKDirections(request: directionRequest) 
    directions.calculate 
     { 
      (response, error) -> Void in 

      guard let response = response else 
      { 
       if let error = error { 
        print("Error : \(error)") 
       } 
       return 
      } 

      let route = response.routes[0] 


      self.mapRoute.add((route.polyline), level: MKOverlayLevel.aboveRoads) 

      let rect = route.polyline.boundingMapRect 
      self.mapRoute.setRegion(MKCoordinateRegionForMapRect(rect), animated: true) 
      self.mapRoute.delegate = self 

    } 
    // Do any additional setup after loading the view. 
} 

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 
    let renderer = MKPolylineRenderer(overlay: overlay) 
    renderer.lineWidth = 1.0 
    renderer.strokeColor = UIColor.red 

    return renderer 
} 

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

    var annotView = mapView.dequeueReusableAnnotationView(withIdentifier: "myAnnotation") as? MKPinAnnotationView 
    if annotView == nil { 
     annotView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myAnnotation") 
    } 
    else { 
     annotView?.annotation = annotation 
    } 
    if let annotation = annotation as? MyPointAnnotation { 
     annotView?.pinTintColor = annotation.pinTintColor 
     annotView?.canShowCallout = true 
    } 

    return annotView 
} 



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


/* 
// MARK: - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    // Get the new view controller using segue.destinationViewController. 
    // Pass the selected object to the new view controller. 
} 
*/ 

}

ceci est mon point classe d'annotations

class MyPointAnnotation : MKPointAnnotation { 
var pinTintColor: UIColor? 

}

+0

Pourquoi ne reconnaissent pas la '' didUpdateLocations' CLLocationManagerDelegate'method? –

+0

auparavant, il peut fonctionner correctement sans didUpdateLocations – christ2702

+0

J'implémente déjà les didupdatelocations, mais j'obtiens toujours une erreur – christ2702

Répondre

0

Comme je l'ai dit dans mes commentaires: Votre problème est que peut-être CLLocationManager de ne pas avoir toutes les positions encore, vous obligez les valeurs Déballer qui sont peut-être nul, en didUpdateLocations cela ne se produira plus, parce que cette méthode est appelée lorsque CLLocationManager ont défini la position

Le principal changement dans votre code est

extension LocationViewController : CLLocationManagerDelegate 
    { 
     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

      if let location = locations.last 
      { 
       if((location.horizontalAccuracy) < CLLocationAccuracy(0)) 
       { 
        return 
       } 

       lokasiAwal2 = location 

       //Calling the method when we are sure that a position is getted 
       self.updateUIAndGetDirection() 
       self.corLoc.stopUpdatingLocation() //avoiding continue direction changes 
      } 
     } 
    } 

Complete C ode

import UIKit 
import CoreLocation 
import MapKit 

class LocationViewController: UIViewController { 


    @IBOutlet weak var mapRoute: MKMapView! 
    var lokasiAwal2 = CLLocation() 
    var corLoc = CLLocationManager() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     mapRoute.delegate = self 

     //let corLoc2 = CLLocationManager() 


     corLoc.delegate = self 
     let statusLoc = CLLocationManager.authorizationStatus() 
     if statusLoc == .notDetermined{ 
      corLoc.requestWhenInUseAuthorization() 
     } 
     corLoc.desiredAccuracy = kCLLocationAccuracyBest 

     corLoc.startUpdatingLocation() 


     // Do any additional setup after loading the view. 
    } 


    func updateUIAndGetDirection() 
    { 
     //let lokasiAwal = CLLocationCoordinate2D(latitude: (corLoc.location?.coordinate.latitude)!, longitude: (corLoc.location?.coordinate.longitude)!) 

     let lokasiAwal = CLLocationCoordinate2D(latitude: lokasiAwal2.coordinate.latitude, longitude: lokasiAwal2.coordinate.longitude) 


     //let lokasiAwal = CLLocationCoordinate2D(latitude: -7.263056, longitude: 112.740317) 

     let lokasiAkhir = CLLocationCoordinate2D(latitude: -7.299356, longitude: 112.676108) 
     //-7.299356, 112.676108 NH 
     //-7.289182, 112.676104 PTC 
     //-7.282713, 112.687633 bandar jakarta 
     //-7.263056, 112.740317 TP 

     //placemark 
     let awalPlaceMark = MKPlacemark(coordinate: lokasiAwal, addressDictionary: nil) 
     let akhirPlaceMark = MKPlacemark(coordinate: lokasiAkhir, addressDictionary: nil) 

     let awalMap = MKMapItem(placemark: awalPlaceMark) 
     let akhirMap = MKMapItem(placemark: akhirPlaceMark) 


     //anotasi 
     let awalAnotasi = MKPointAnnotation() 
     awalAnotasi.title = "Your Location" 


     //let awalPin = MKPinAnnotationView.init(annotation: awalAnotasi, reuseIdentifier: "Your Location") 
     //awalPin.pinTintColor = UIColor.blue 


     if let locationAwal = awalPlaceMark.location { 
      awalAnotasi.coordinate = locationAwal.coordinate 
     } 

     let akhirAnotasi = MKPointAnnotation() 
     akhirAnotasi.title = "National Hospital" 

     if let locationAkhir = akhirPlaceMark.location { 
      akhirAnotasi.coordinate = locationAkhir.coordinate 
     } 

     let awalPin = MyPointAnnotation() 
     awalPin.coordinate = awalAnotasi.coordinate 
     awalPin.pinTintColor = .green 
     awalPin.title = awalAnotasi.title 

     let akhirPin = MyPointAnnotation() 
     akhirPin.coordinate = akhirAnotasi.coordinate 
     akhirPin.pinTintColor = .blue 
     akhirPin.title = akhirAnotasi.title 

     //titik marker 
     self.mapRoute.showAnnotations([awalPin, akhirPin], animated: true) 


     //menambahkan route 
     let directionRequest = MKDirectionsRequest() 
     directionRequest.source = awalMap 
     directionRequest.destination = akhirMap 
     directionRequest.transportType = .automobile 

     let directions = MKDirections(request: directionRequest) 
     directions.calculate 
      { 
       (response, error) -> Void in 

       guard let response = response else 
       { 
        if let error = error { 
         print("Error : \(error)") 
        } 
        return 
       } 

       let route = response.routes[0] 


       self.mapRoute.add((route.polyline), level: MKOverlayLevel.aboveRoads) 

       let rect = route.polyline.boundingMapRect 
       self.mapRoute.setRegion(MKCoordinateRegionForMapRect(rect), animated: true) 
       self.mapRoute.delegate = self 

     } 
    } 


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


    /* 
    // MARK: - Navigation 

    // In a storyboard-based application, you will often want to do a little preparation before navigation 
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    // Get the new view controller using segue.destinationViewController. 
    // Pass the selected object to the new view controller. 
    } 
    */ 
} 

extension LocationViewController : MKMapViewDelegate 
{ 
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 
     let renderer = MKPolylineRenderer(overlay: overlay) 
     renderer.lineWidth = 1.0 
     renderer.strokeColor = UIColor.red 

     return renderer 
    } 

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

     var annotView = mapView.dequeueReusableAnnotationView(withIdentifier: "myAnnotation") as? MKPinAnnotationView 
     if annotView == nil { 
      annotView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myAnnotation") 
     } 
     else { 
      annotView?.annotation = annotation 
     } 
     if let annotation = annotation as? MyPointAnnotation { 
      annotView?.pinTintColor = annotation.pinTintColor 
      annotView?.canShowCallout = true 
     } 

     return annotView 
    } 

} 

extension LocationViewController : CLLocationManagerDelegate 
{ 
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

     if let location = locations.last 
     { 
      if((location.horizontalAccuracy) < CLLocationAccuracy(0)) 
      { 
       return 
      } 

      lokasiAwal2 = location 

      self.updateUIAndGetDirection() 
      self.corLoc.stopUpdatingLocation() //avoiding continue direction changes 
     } 
    } 

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

     if status == CLAuthorizationStatus.authorizedWhenInUse || status == CLAuthorizationStatus.authorizedAlways { 

      manager.startUpdatingLocation() 

     } 
    } 
} 

Hope this helps

+0

toujours donner le résultat nul – christ2702

+0

Je pense qu'il ya quelque chose de mal dans l'ensemble de simuler les emplacements que j'ai mentionnés auparavant. parce que, précédemment mon application peut fonctionner correctement – christ2702

+0

@ christ2702 ma réponse a été mise à jour avec votre code fixe, j'espère que cela vous aide –

0

utilisation délégué CoreLocation dans viewdidload & get coordonnées dans didUpdateLocations

import UIKit 
import CoreLocation 

class ViewController: UIViewController,CLLocationManagerDelegate { 

    let corLoc = CLLocationManager() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     corLoc.delegate = self 
     let statusLoc = CLLocationManager.authorizationStatus() 
     if statusLoc == .notDetermined{ 
      corLoc.requestWhenInUseAuthorization() 
     } 
     corLoc.desiredAccuracy = kCLLocationAccuracyBest 
     corLoc.startUpdatingLocation() 

    } 
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
     print((corLoc.location?.coordinate.latitude) ?? "No values") 
     let lokasiAwal = CLLocationCoordinate2D(latitude: (corLoc.location?.coordinate.latitude)!, longitude: (corLoc.location?.coordinate.longitude)!) // 
     let lokasiAkhir = CLLocationCoordinate2D(latitude: -7.299356, longitude: 112.676108) 
    } 

} 
+0

toujours le même résultat – christ2702

+0

comme je l'ai mentionné avant, je pense que le problème est sur l'emplacement de simulation – christ2702

+0

Mec, j'ai essayé & Son fonctionne bien. Si vous êtes sur simulateur, sélectionnez l'emplacement manuellement. – Jack

0

Votre problème est que CLLocationManager de ne pas peut-être encore de la position . La méthode déléguée didUpdateLocations est appelée lorsque les données sont prêtes.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    let userLocation:CLLocation = locations[0] as CLLocation 
    // manager.stopUpdatingLocation() 
    lokasiAwal = userLocation 
} 
+0

il donne encore le résultat nul – christ2702