2017-05-09 4 views
0

Ich versuche, eine Funktion einzurichten, um meine aktuelle Position in der Anwendung zu erhalten Delegat, aber wenn ich print(city) an der Unterseite gibt es den ursprünglichen initialisierten Wert in der globalen Variablen, die "Hallo" ist, obwohl ich den Wert unter dem CLGeocoder aktualisiert habe.If Anweisung ändert sich nicht globale Variable swift

AppDelegate:

import UIKit 
    import CoreData 
    import CoreLocation 

    let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate 

    var country = "hello" 
    var city = "hello" 

func setupLocationManager(){ 
     let locationManager = CLLocationManager() 
     locationManager.requestAlwaysAuthorization() 
     locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters 
     locationManager.startUpdatingLocation() 
    } 

    // Below method will provide you current location. 
    func getLocation() -> [String]{ 
     let manager = CLLocationManager() 
     manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters 
     manager.requestAlwaysAuthorization() 
     manager.startUpdatingLocation() 

     manager.desiredAccuracy = kCLLocationAccuracyBest 
     manager.requestAlwaysAuthorization() 
     manager.startUpdatingLocation() 

     let selflocation = manager.location 

     let latitude: Double = selflocation!.coordinate.latitude 
     let longitude: Double = selflocation!.coordinate.longitude 


     print("current latitude :: \(latitude)") 
     print("current longitude :: \(longitude)") 

     let location = CLLocation(latitude: latitude, longitude: longitude) //changed!!!    

     CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in 
      print(location) 

      if error != nil { 
       print("Reverse geocoder failed with error" + (error?.localizedDescription)!) 
      } 

      let pm = placemarks![0] 
      let speed = (selflocation?.speed)! 
      city = pm.addressDictionary!["City"]! as! String 
      country = pm.addressDictionary!["Country"]! as! String 

      if (placemarks?.count)! > 0 { 
      } 
      else { 
       print("Problem with the data received from geocoder") 
      } 
     }) 

     print(city) 
     return [city as! String, country as! String] 
    } 

Antwort

1

Dies liegt daran, dass die Geocodierung asynchron erfolgt, so dass die print(city) ausgeführt wird, bevor die Geocodierung abgeschlossen ist. Also schlage ich vor, dass Sie das tun.

func getLocation(completion: @escaping (Array<String>)->()){ 

    let manager = CLLocationManager() 

    manager.desiredAccuracy = kCLLocationAccuracyBest 

    manager.requestAlwaysAuthorization() 

    manager.startUpdatingLocation() 

    let selflocation = manager.location 

    let latitude: Double = selflocation!.coordinate.latitude 

    let longitude: Double = selflocation!.coordinate.longitude 

    let location = CLLocation(latitude: latitude, longitude: longitude) 

    CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in 

     if let error = error { 

      print(error.localizedDescription) 

      return 
     } 

     if let placemark = placemarks?.first { 

      if let country = placemark.country, let city = placemark.locality { 

       completion([city, country]) 

       return 

      } else { 

       print("country or city was nil.") 
      } 
     } else { 

      print("Problem with the data received from geocoder") 
     } 
    }) 
} 

Also statt getLocation() Anruf

getLocation { (location) in 

    print(location) 
} 
0

reverseGeocodeLocation arbeitet asynchron, so dass die print Anweisung tatsächlich passiert, bevor es fertig ist. Wenn Sie eine Logik haben, die von den Ergebnissen abhängt, müssen Sie sie wahrscheinlich in den Beendigungshandler-Abschluss einfügen.

0

Wie die andere Antwort Aufruf sagt, reverseGeocodeLocation arbeitet asynchron, so dass Sie die print(city) innerhalb des Verschlusses, wie nach

else { 
    print("Problem with the data received from geocoder") 
} 
bewegen möchten
+0

Wenn Sie den Druck (Stadt) innerhalb des Verschlusses verschieben, wird die korrekte Antwort ausgedruckt. Sie können jedoch keine Funktion innerhalb eines Verschlusses zurückgeben, so dass dies nicht funktioniert. –

1

Das Problem hier ist, dass Sie den Wert erhalten, bevor ihm ein neuer Standortwert zugewiesen wird. Sie müssen ein wenig warten, um den aktualisierten Wert zu erhalten.