2016-08-08 4 views
1

위치를 역 지오 코딩하여 결과 문자열을 변수에 할당하는 함수를 작성하고 싶습니다. 난 그냥 이런 식으로 뭔가있어이 기능을 호출하는CLGeocoder에서 문자열을 반환 할 수 없습니다. reverseGeocodeLocation

extension CLLocation { 

    func reverseGeocodeLocation(completion: (answer: String?) -> Void) { 

     CLGeocoder().reverseGeocodeLocation(self) { 

      if let error = $1 { 
       print("[ERROR] \(error.localizedDescription)") 
       return 
      } 

      if let a = $0?.last { 
       guard let streetName = a.thoroughfare, 
        let postal = a.postalCode, 
        let city = a.locality else { return } 

       completion(answer: "[\(streetName), \(postal) \(city)]") 
      } 

     } 
    } 
} 

을 :

location.reverseGeocodeLocation { answer in 
    print(answer) 
} 

을하지만 그 대신 난에 answer의 문자열 값을 할당 할 내가 이런 식있어 this 게시물을 다음 변수와 나는 그 데이터를 클로저 밖으로 전달하는 방법을 모른다. 이런 식으로하는 가장 좋은 방법은 무엇입니까?

답변

3

문제는 비동기 적으로 실행되므로 값을 반환 할 수 없다는 것입니다. 당신은 몇 가지 속성이나 변수를 업데이트 할 경우, 해당 작업을 수행 할 수있는 권리 장소는 예를 들어, 당신은 방법을 제공하는 폐쇄에 있습니다

var geocodeString: String? 

location.reverseGeocodeLocation { answer in 
    geocodeString = answer 
    // and trigger whatever UI or model update you want here 
} 

// but not here 

폐쇄 completion 핸들러 패턴의 전체 목적은 그이 선호된다 비동기 적으로 검색된 데이터를 제공하는 방법.

+0

내가 작곡하는 동안 대답했다. 당신은 초의 merest에 의해 나를 때려 ... :) –

+0

Lol. 죄송합니다. 아마도 스택 오버플로는 누군가가 현재 Skype 또는 일부 채팅 플랫폼과 같은 종류의 대답을 입력하면 알 수있는 기능이 있어야합니다. – Rob

+0

감사합니다! 문제를 해결했습니다. ✌️ –

1

짧은 대답 : 할 수 없습니다. 그건 비동기 프로그래밍이 작동하는 방식이 아닙니다. reverseGeocodeLocation 함수는 대답을 받기 전에 즉시 반환됩니다. 미래의 어떤 시점에서 지오 코드 결과를 사용할 수있게되며, 그런 경우 클로저의 코드가 호출됩니다. 그 때 당신이 당신의 대답으로 무엇인가를 할 때입니다. 클로저를 작성하여 레이블에 응답을 설치하거나, ​​테이블보기를 업데이트하거나, 다른 동작을 수행 할 수 있습니다. (지오 코딩 메서드의 클로저가 기본 스레드 또는 백그라운드 스레드에서 호출되는지 기억하지 못합니다. 백그라운드 스레드에서 호출되면 dispatch_async(dispatch_get_main_queue())에 UI 호출을 래핑해야합니다.)

+0

FWIW는 많은 비동기식 API 메소드와는 달리,'reverseGeocodeLocation'을 사용하면 메인 큐에 무엇이든 파견하는 것에 대해 걱정할 필요가 없습니다. [docs] (https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLGeocoder_class/index.html#//apple_ref/occ/instm/CLGeocoder/reverseGeocodeLocation:completionHandler :)에서 " 완성 처리기 블록은 주 스레드에서 실행됩니다. " 그러나 완성 대기열에 대한 요점은 완료 핸들러가있는 다른 많은 비동기 메소드에 대한 우려이기 때문에 훌륭한 대기열입니다. – Rob

+1

@Rob, 명확히 해 주셔서 감사합니다. 나는 reverseGeocodeLocation이 클로저를 어떻게 다루 었는지 기억하지 못했고 내 대답을 올렸을 때 그것을 찾을 시간이 없었다. –