---
# System prepended metadata

title: '날씨 앱 [STEP 2-2] Blu, Jenna'

---

# 날씨 앱 [STEP 2-2] Blu, Jenna

>안녕하세요! 코리(@corykim0829)🐶!
🌙**TEAM LuNna**🌙 의 Blu, Jenna입니다!
>
>STEP 2-2에서는 위도와 경도를 주소로 변환하는 로직 구현 및 HTTP GET 명시적 호출을 구현에 대해 학습하고 적용해 보았어요!
>STEP을 세분화하여 부분적으로 학습을 진행하고 코드를 작성하게 되니까 해당 부분에 대해 조금 더 많이 찾아보고 이해할 수 있어서 좋은 시간이었습니다!
>
>이번 리뷰도 잘 부탁드려요! 감사합니다! 🙇🏻🙇🏻

<br>

# 🧑🏼‍💻 작업 목록
## 위도와 경도를 주소로 변환하기
- [x] CL LocationManagerDelegate의 `locationManager(_:didUpdateLocations:)`의 매개변수 locations로 현재 위도, 경도를 포함한 CLLocation 타입 가져오기
- [x] CLGeocoder에 위에서 가져온 타입을 활용하여 현재 위치의 장소 정보 가져오기
    - [x] 가져온 장소 정보를 활용하여 주소로 변환하기
    ↳ 장소 정보의 형태에 관한 고민이 있어 구체적인 구현은 보류, 추후 상황에 따라 별도의 타입으로 분리하고자 함

## HTTP GET 메서드를 명시적으로 호출하기
- [x] `URLRequest`의 `httpMethod` 변수값을 "GET"으로 명시적 호출

<br>

# 📚 학습 키워드 및 학습 내용
## 1. HTTP Method
> 🖇️　참고한 공식문서: 
> - [URLRequest](https://developer.apple.com/documentation/foundation/urlrequest)
> - [NSURLRequest](https://developer.apple.com/documentation/foundation/nsurlrequest#1776617)
> - [httpMethod](https://developer.apple.com/documentation/foundation/urlrequest/2011415-httpmethod)

- **학습 내용**
    - httpMethod
    - URLRequest & NSURLRequest
        - 로드 요청에 대한 두 가지 필수 속성을 캡술화함
            - 로드할 URL
            - 사용되는 정책
        - HTTP/HTTPS 요청의 경우 HTTP method(GET, POST...)와 헤더를 포함
        - HTTP method를 지정하기 위한 `httpMethod` 프로퍼티는 `NSURLRequest` 클래스의 프로퍼티임
        - Foundation 프레임워크는 `URLRequest`클래스와 해당 가변 클래스인 `NSMutableURLRequest`에 연결된 `URLRequest` 구조체를 제공함,    
**즉, `NSURLRequest`에 있는 component들을 `URLRequest`에서 사용할 수 있음!**
        - httpMethod의 기본 HTTP method는 GET
- **적용 과정**
    - 문서에 따르면 `"GET"`이 default값
        ```Swift
        The default HTTP method is “GET”.
        ```
    - 'HTTP GET 메서드 명시적 호출'이 요구사항이라 아래와 같이 set해주는 코드를 추가해주긴 했지만, 아래 아쉬운 점과 더불어 '명시적 호출'을 제대로 구현한 게 맞는가에 대한 의문이 듦
       ```Swift
       request.httpMethod = "GET"
       ```
    
- **아쉬운 점**
    - 문서에서 알 수 있다시피 String? 타입이라 String("GET") 리터럴값을 직접 넣어줘야 했음
    - 휴먼에러가 발생하기 쉬운 부분이라고 생각되는데 원래 이렇게 사용하는 게 맞는 건지, 놓친 부분이 있는지 궁금함

<br>

## 2. CLGeocoder

> 🖇️　참고한 공식문서: 
> - [CLGeocoder](https://developer.apple.com/documentation/corelocation/clgeocoder)
> - [CLPlacemark](https://developer.apple.com/documentation/corelocation/clplacemark)
    
- **학습 내용**
    - CLGeocoder
        - Core Location 프레임워크 내부의 클래스
        - 위도와 경도로 이루어진 좌표와 사용자 친화적인 주소 표현 사이의 변환 서비스를 제공하는 클래스
        - 일반적으로 거리, 도시, 주, 국가 및 지역정보를 포함함
        - forward geocoding method  (**순방향**)
            - 사용자가 읽을 수 있는 주소로 위도와 경도를 찾음
            - 관심 지점이나 해당 위치의 건물과 같은 지정 위치에 대한 추가정보를 반환할 수 있음
            - 제공된 정보가 여러 위치를 산출할 경우 여러 개의 placemark가 반환될 수 있음
        - reverse geocoding method (**역방향**) ✅
            - 위도와 경도를 가지고 사용자가 읽을 수 있는 주소를 찾음
            - `reverseGeocodeLocation` 사용
        - forward / reverse 모두 `CLPlacemark` 형태로 반환
    - CLPlacemark
        - 장소의 이름, 주소 및 기타 관련 정보를 포함하는 좌표에 대한 **사용자 친화적인 설명**
        - 지정된 위/경도에 대한 placemark 데이터를 저장
        - 좌표, 국가, 지역, 주, 도시 및 거리 주소와 같은 정보 포함
        - 관심지점 및 지리적인 데이터가 포함될 수 있음
        - reverse geocoding을 하는 경우 CLPlacemark 개체를 반환받음
        - Detail properties
            |프로퍼티명|설명|
            |:---|:---|
            |`throughfare`|The street address associated with the placemark.<br>**거리 주소(도로명주소의 ~로)**|
            |`subThroughfare`|Additional street-level information for the placemark.<br>**추가 거리수준 정보(상세주소)**|
            |`locality`|The city associated with the placemark.<br>**도시('시'로 끝나는 행정구역)**|
            |`subLocality`|Additional city-level information for the placemark.<br>**추가 도시수준 정보(동/면/~로)**|
            |`adminstrativeArea`|The state or province associated with the placemark.<br>**주 혹은 지방 정보(행정구역 중 가장 넓은 범위, 도/특별시/광역시)**|
            |`subAdminstrativeArea`|Additional administrative area information for the placemark.<br>**추가 행정구역 정보(행정구역 중 군)**|
            |`postalCode`|The postal code associated with the placemark.<br>**우편번호**|
            |`country`|The name of the country or region associated with the placemark.<br>**국가명**|
            |`name`|The name of the placemark.<br>**placemark의 이름(보통 throughfare + subThroughfare)**|
- **적용 과정**
    - CLLocationManager으로 가져온 CLLocation 타입의 location으로 reverse geocoding 을 진행
- **문제와 해결**
    |문제와 해결|내용|
    |:---:|:---|
    |문제|기존에 Coustom Location으로 지정한 좌표(37.53, 126.96)를 기준으로 주소를 가져오는 경우 '구'에 해당하는 '용산구'를 불러오는 프로퍼티가 없음|
    |해결|***해결중!!*** 외부 라이브러리가 제약된 상황이라 출력된 정보를 가지고 가공해야 하는지 방법을 찾아보는 중|
    
<br>

# 🙋🏻 질문 거리
## 1. Geocoder 사용 시 주소체계의 차이에 따른 문제점
- Core Location의 좌표를 통해 CLGeocoder로 reverse geocoding한 결과로 반환된 CLPlacemark상에는 `대한민국 서울특별시 용산구 한강로3가 40-1030`으로 주소가 잘 담겨있으나, '구'에 해당하는 주소를 가져오는 프로퍼티를 찾지 못했습니다.
- LLDB를 통하여 공식문서 내부에 존재하는 프로퍼티를 모두 호출해 보았지만 구에 해당하는 프로퍼티가 없었습니다.
    ![CLGeocoder LLDB로그](https://user-images.githubusercontent.com/71758542/230761744-bf9f5d39-622e-46c1-afd7-ee1d2e5a3e4d.png)
- 주소체계마다 다른 것인지를 알아보기 위해 시뮬레이터의 Custom Location을 변경하여 진행해 본 결과, 도/시 체계를 가지고 있는 경우(예: 경기도, 전라남도)는 `administrativeArea`에 도에 해당하는 값이, `locality`는 시에 해당하는 값이 나오지만, 시/구 체계를 가지고 있는 경우(예: 서울시, 광주광역시)는 `administrativeArea`와 `locality`가 시에 해당하는 값으로 동일하게 나왔습니다.    
또한, 도/시 체계와 도/군 체계에서도 호출해야 하는 프로퍼티에 차이가 있다는 점을 알게 되었어요. 
![경기도 하남시 LLDB로그](https://user-images.githubusercontent.com/71758542/230761678-326ef711-e10f-467e-a824-f32a00a9721e.png)
<br>![전라도 강진군 LLDB로그](https://user-images.githubusercontent.com/71758542/230761679-48bb6a01-efd5-4f89-89e9-507134daa285.png)
- 주소체계에 따라 존재하는 값과 존재하지 않는 값이 있고, `administrativeArea`와 `locality`가 동일한 문제가 발생하였고 이를 해결하기 위해 다른 방법을 찾아보았지만, 만족스러운 방법은 아니었습니다!
- 전체 주소(`대한민국 서울특별시 용산구 한강로3가 40-1030`)를 가지고 올 수 있다면, 해당 주소를 공백문자 `' '` 기준으로 분할하고, 구에 해당되는 index 번호를 가져올까 시도해 보았습니다.
    - 이를 위해 전체 주소를 가져올 수 있는 프로퍼티에 대해 찾아보고 있던 중 `addressDictionary`를 발견하였고, lldb 로그로 조회해 본 결과 "FormattedAddressLines" key를 사용하면 전체 주소와 우편번호가 담긴 배열에 접근할 수 있다는 사실을 알게 되었습니다. 해당 부분을 학습하기 위해 공식문서를 찾아본 결과 Deprecated된 프로퍼티였습니다.
    ![addressDictionary LLDB로그](https://user-images.githubusercontent.com/71758542/230761683-3a67bc51-6cbe-43a6-9d4d-a17d3ea0fd34.png)
    - 전체 주소를 가져올 수 있는 프로퍼티가 없으므로, 현재는 `.description.components(separatedBy: ", ")`으로 리턴된 `CLPlacemark`를 분리시킨 후, 전체 주소에 해당하는 값만 가져오는 방식으로 구현해 두었어요! 하지만 이 경우 index로 접근하게 되면서 발생할 에러에 대한 위험성이 있겠다 판단했습니다. 더 좋은 방법을 찾아보려 하였으나 아직 찾지 못했어요...! 🥲
    ![현재 address 출력 로그](https://user-images.githubusercontent.com/71758542/230761685-dedb2d51-d49d-4b5d-b097-4ae26185d343.png)
- 외부 라이브러리나 API를 사용하지 않고, CLGeocoder만 활용해서 적절한 형태의 주소(가공이 크게 필요하지 않은 데이터)를 불러올 수 있는 방법이 없을까요?
- 주소를 사용자에게 보여주는 많은 어플들이 주소체계와 상관없이 시/구/동에 해당하는 주소가 명확히 나오는 것 같아요 👀 현업에서는 CLGeocoder만 사용하는지, 아니면 다른 방식을 사용 중인지 궁금합니다!