2017-05-09 4 views
0

앱 위임에 현재 위치를 가져 오는 기능을 설정하려고하지만 하단에 print(city)이 있으면 "hello"라는 전역 변수에 원래 초기화 된 값이 반환됩니다. CLGeocoder에서 값을 업데이트했지만 가 완료되기 전에명세서가 전역 변수를 신속하게 변경하지 못한다면

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] 
    } 

답변

1

지오 코딩이 비동기 적으로 수행되므로 지오 코딩이 완료되기 전에 print(city)이 실행 중이기 때문입니다. 그래서 나는 당신이 이것을하는 것이 좋습니다.

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") 
     } 
    }) 
} 

그래서 그 대신 다른 대답처럼 getLocation() 전화

getLocation { (location) in 

    print(location) 
} 
0

reverseGeocodeLocation 작품 비동기, 그래서 print 문은 실제로 일어나고있다. 결과에 의존하는 로직이 있다면 완료 핸들러 클로저에 넣어야 할 것입니다.

0

를 호출은 reverseGeocodeLocation 말한다 당신은 같은 폐쇄 내부의 print(city)를 이동할 수 있도록, 비동기 적으로 작동

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

클로저 안에 인쇄물 (도시)을 이동하면 올바른 응답이 인쇄되지만 클로저 안에서는 함수를 반환 할 수 없으므로 작동하지 않습니다. –

1

여기에서 문제는 새 위치 값이 할당되기 전에 값을 가져 오는 것입니다. 업데이트 된 가치를 얻으려면 조금만 기다려야합니다.