본문 바로가기
#모바일 [Mobile]/iOS

[iOS] Kakao 로컬(Local) API를 사용하여 좌표로 주소 변환하기

by cy_mos 2022. 1. 1.
반응형
카테고리 (Category) 작성 날짜 (Write Date) 최근 수정 날자 (Recent Write Date) 작성자 (Writer)
iOS 2022.01.01. 23:55 2022.01.02. 00:17 Dev.Yang


[REST API 활용하기 1탄] 좌표 정보의 지번 주소와 도로명 주소 정보를 반환하는 API입니다.

 

개발 환경은 아래와 같습니다.

 

  • Xcode Version 13.1 (13A1030d)
  • Swift Version 5.5.1
  • Alamofire Version 5.5.0

🛠 JSON Response

요청 성공 시 응답은 documents 하위에 지번 주소 또는 도로명 주소 상세 정보를 포함합니다. 더 세부적인 정보는 아래의 API 문서를 참조해주시길 바랍니다.

 

🗂 Meta

Name Type Description
total_count Integer 변환된 지번 주소 및 도로명 주소 의 개수, 0 또는 1

🗂 Documents

Name Type Description
address Address 지번 주소 상세 정보, 아래 Address 참고
road_address RoadAddress 도로명 주소 상세 정보, 아래 RoadAddress 참고

🗂 Address

Name Type Description
address_name String 전체 지번 주소
region_1depth_name String 지역 1Depth명, 시도 단위
region_2depth_name String 지역 2Depth명, 구 단위
region_3depth_name String 지역 3Depth명, 동 단위
mountain_yn String 산 여부, Y 또는 N
main_address_no String 지번 주 번지
sub_address_no String 지번 부 번지, 없을 경우 빈 문자열("") 반환

🗂 RoadAddress

Name Type Description
address_name String 전체 도로명 주소
region_1depth_name String 지역 1Depth, 시도 단위
region_2depth_name String 지역 2Depth, 구 단위
region_3depth_name String 지역 3Depth, 면 단위
road_name String 도로명
underground_yn String 지하 여부, Y 또는 N
main_building_no String 건물 본번
sub_building_no String 건물 부번, 없을 경우 빈 문자열("") 반환
building_name String 건물 이름
zone_no String 우편번호(5자리)

📄 [Swift] 좌표로 주소 변환하기

/*
 * Copyright (c) 2021 양창엽. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import Alamofire
import Foundation
import CoreLocation

/**
    - Date: `2022.01.01. 22:32:05`
    - Version: `[Lasted] 1.0.1.0`
 
    - NOTE: `GetRoadAddress`
    - Authors: `ChangYeop-Yang`
    - Copyright: `[GPLv3] Copyright (c) 2021 양창엽. All rights reserved.`
*/
class GetRoadAddress: NSObject {

    // MARK: - Enum
    internal enum CoordinateType: String, CaseIterable {
        case WGS84 = "WGS84"
        case WCONGNAMUL = "WCONGNAMUL"
        case CONGNAMUL = "CONGNAMUL"
        case WTM = "WTM"
        case TM = "TM"
    }

    // MARK: - Struct
    internal struct KakaoRoadAddress: Decodable {
        internal let meta: Meta
        internal let documents: [Documents]

        // MARK: Struct
        internal struct Meta: Decodable {
            // MARK: Integer
            internal let total: Int

            // MARK: CodingKeys
            private enum CodingKeys: String, CodingKey {
                case total = "total_count"
            }
        }

        internal struct Documents: Decodable {
            // MARK: Struct
            internal let address: Address
            internal let roadAddress: RoadAddress

            // MARK: CodingKeys
            private enum CodingKeys: String, CodingKey {
                case address
                case roadAddress = "road_address"
            }
        }

        internal struct Address: Decodable {
            // MARK: String
            internal let addressName: String
            internal let regionFirstDepthName: String
            internal let regionTwoDepthName: String
            internal let regionThreeDepthName: String
            internal let isMountain: String
            internal let mainAddress: String
            internal let subAddress: String

            // MARK: CodingKeys
            private enum CodingKeys: String, CodingKey {
                case addressName = "address_name"
                case regionFirstDepthName = "region_1depth_name"
                case regionTwoDepthName = "region_2depth_name"
                case regionThreeDepthName = "region_3depth_name"
                case isMountain = "mountain_yn"
                case mainAddress = "main_address_no"
                case subAddress = "sub_address_no"
            }
        }

        internal struct RoadAddress: Decodable {
            // MARK: String
            internal let addressName: String
            internal let regionFirstDepthName: String
            internal let regionTwoDepthName: String
            internal let regionThreeDepthName: String
            internal let roadName: String
            internal let isUnderground: String
            internal let mainBuildingNo: String
            internal let subBuildingNo: String
            internal let buildingName: String
            internal let zoneNo: String

            // MARK: CodingKeys
            private enum CodingKeys: String, CodingKey {
                case addressName = "address_name"
                case regionFirstDepthName = "region_1depth_name"
                case regionTwoDepthName = "region_2depth_name"
                case regionThreeDepthName = "region_3depth_name"
                case roadName = "road_name"
                case isUnderground = "underground_yn"
                case mainBuildingNo = "main_building_no"
                case subBuildingNo = "sub_building_no"
                case buildingName = "building_name"
                case zoneNo = "zone_no"
            }
        }
    }

    // MARK: - Object Properties
    internal static let shared = GetRoadAddress()
}

// MARK: - Private Extension GetRoadAddress
private extension GetRoadAddress {

    func makeHeader() -> HTTPHeaders {

        let strAuth = String(format: "KakaoAK %@", APIKeys.REST_API_KAKAO.key)
        let authorization = HTTPHeader.authorization(strAuth)

        let contentType = HTTPHeader.contentType("application/json;charset=UTF-8")

        var header = HTTPHeaders()
        header.add(authorization)
        header.add(contentType)

        return header
    }

    func makeParameter(coordinate: CLLocationCoordinate2D, type: CoordinateType) -> Parameters {

        let result: Parameters = ["x": coordinate.longitude, "y": coordinate.latitude,
                                  "input_coord": type.rawValue]
        return result
    }
}

// MARK: - Internal Extension GetRoadAddress
internal extension GetRoadAddress {

    func getRoadAddress(url: String = "https://dapi.kakao.com/v2/local/geo/coord2address.json",
                        coordinate: CLLocationCoordinate2D, type: CoordinateType) {

        let headers: HTTPHeaders = makeHeader()
        let parameters: Parameters = makeParameter(coordinate: coordinate, type: type)

        AF.request(url, method: .get, parameters: parameters, headers: headers)
            .responseDecodable(of: KakaoRoadAddress.self) { response in
                print(response.result)
        }
    }
}

🚀 REFERENCE

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

GitHub - Alamofire/Alamofire: Elegant HTTP Networking in Swift

Elegant HTTP Networking in Swift. Contribute to Alamofire/Alamofire development by creating an account on GitHub.

github.com

반응형

댓글