2014년 4월 24일 목요일

[iOS] CLGeocoder를 이용해 현재 위치의 주소 얻기

위도/경도 등의 위치 좌표를 이용해 현재 위치의 주소를 얻는 것을 Reverse Geocode 라고 부른다. 현재 iOS SDK 에서는 CLGeocoder 를 이용해 리버스 지오코딩을 할 수 있다.

참고로, 기존에는 MKReverseGeocoder 라는 Mapkit에 부속된 클래스가 있었는데 지금은 Deprecated 된 상태이다. 그냥 CLGeocoder 를 이용하자.

CLGeocoder를 이용해 주소를 얻기 위해서는 우선 위치를 저장하고 있는 CLLocation 객체가 필요하다. 이 객체는 'CoreLocation을 이용한 현재 위치 찾기' 포스팅에서 CLLocationManagerDelegate 를 통해 얻을 수 있으므로 참고하자.

우선 위치를 찾을 때와 동일하게 CoreLocation.framework 그리고 AddressBook.framework 가 필요하므로 프로젝트에 추가해야 한다. 물론 요즘은 자동으로 빌드 때 추가가 되니 그냥 헤더만 명시해도 된다.

헤더는 CoreLocation과 함께 주소 추출 시 필요한 AddressBook의 헤더가 필요하다.
#import <CoreLocation/CoreLocation.h>
#import <AddressBook/AddressBook.h>

이제 실제로 CLGeocoder를 이용할 차례이다. 참고로 location 이라는 심볼은 앞서 이야기한 현재 위치를 담고 있는 CLLocation 객체이다.
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
    if (error) {
        NSLog(@"Failed to reverse-geocode: %@", [error localizedDescription]);
        return;
    }

    for (CLPlacemark *placemark in placemarks) {
        // 큰분류(시 혹은 도) (STATE in U.S.A)
        NSString *city = [placemark.addressDictionary objectForKey:(NSString *)kABPersonAddressStateKey];
        // 중분류(구 혹은 시) Name (CITY in U.S.A)
        NSString *regionName = [placemark.addressDictionary objectForKey:(NSString *)kABPersonAddressCityKey];
        ...
    }
}];
reverseGeocodeLocation:completionHandler: 메서드를 이용해 주소를 구할 수 있는데, 실제로 리버스 지오코딩은 서버를 거쳐서 동작하기 때문에 즉시 결과가 오는 것이 아니다. 따라서 위에서는 블럭 코딩(completionHandler)을 이용해 서버로 부터 결과가 오면 이를 받아서 처리하는 식으로 구성되어 있다.

주소는 CLPlacemark 라는 객체에 포장되어 있다. CLPlacemark 에는 지명이나 주소를 표현하기 위해 필요한 다양한 데이터가 들어있다. 여기서 필요한 것은 addressDictionary 라 불리우는 주소가 저장되어 있는 사전이다. 이 사전(NSDictionary)는 아래와 같은 키로 구성되어 있다.
kABPersonAddressStreetKey
kABPersonAddressCityKey
kABPersonAddressStateKey
kABPersonAddressZIPKey
kABPersonAddressCountryKey
kABPersonAddressCountryCodeKey
영문 주소에 맞게 키 이름이 배정되어 있는데, 위의 예제 코드에서 '서울시 강남구' 일 경우 state는 '서울', 그리고 city는 '강남구' 가 들어있다. 영어권에 맞게 처리한다면 그대로 쓰면 되겠지만 한국 환경에 맞게 쓰려면 실제 addressDictionary 내용을 분석해서 필요한 키를 사용해야 한다.

그리고 위 키는 CFStrinfRef 타입이기 때문에 컴파일 경고를 보고 싶지 않다면 NSString 객체 포인터로 변환해서 써야 한다. 실제로 위 예제에서는 NSString *으로 형변환 하는 것을 확인 할 수 있다.

CLGeocoder 는 iOS의 시스템 로케일에 따라 응답하는 결과가 다르다. 즉 영문 모드의 아이폰에서 테스트 해 보면 영어로 된 주소가 날아온다. 한국어로 되어 있다면 당연히 한글로 결과를 얻을 수 있다. 이 부분을 주의하자.

관련포스트: [iOS] CoreLocation Framework를 이용한 현재 위치 찾기

댓글 없음 :