View in English

  • 메뉴 열기 메뉴 닫기
  • Apple Developer
검색
검색 닫기
  • Apple Developer
  • 뉴스
  • 둘러보기
  • 디자인
  • 개발
  • 배포
  • 지원
  • 계정
페이지에서만 검색

빠른 링크

5 빠른 링크

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 주제
  • 전체 비디오
  • 소개

WWDC25 컬렉션으로 돌아가기

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • MapKit에 고급 기능 추가하기

    MapKit 및 MapKit JS의 최신 업데이트를 확인하세요. 새로운 유형의 방향인 순환 방식을 소개하고 웹에서 3D Look Around 이미지를 설정하는 방법을 보여드립니다. 새로운 Geocoding API가 좌표 및 주소 변환 기능을 지원하는 방법과 Address Representations API를 사용하여 한 지역에서 가장 적절한 주소를 찾는 방법을 학습하세요. 그런 다음 앱이 앱 인텐트와 원활하게 작동하도록 보장하는 새로운 장소 참조 방법을 소개하며 마무리하겠습니다.

    챕터

    • 0:00 - 서론
    • 0:45 - 장소 찾기
    • 9:34 - 장소 표시하기
    • 14:14 - 경로 찾기

    리소스

    • Adopting unified Maps URLs
    • Place ID Lookup
    • Searching, displaying, and navigating to places
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC24

    • MapKit으로 장소 정보를 효과적으로 활용하기

    WWDC23

    • SwiftUI용 MapKit 알아보기

    WWDC22

    • MapKit의 새로운 기능
  • 비디오 검색…

    안녕하세요, 저는 Alex입니다 MapKit 팀의 엔지니어로 일하고 있습니다 Apple 지도는 기기에서 전 세계의 장소를 둘러보고 길을 찾을 수 있도록 도와줍니다 유명한 랜드마크부터 아늑한 카페와 현지 상점, 훌륭한 등산 코스까지 다양한 장소를 찾을 수 있습니다 오늘은 MapKit과 MapKit JS의 업데이트에 대해 설명할게요 이 업데이트를 통해 앱과 웹사이트에 지도를 통합할 수 있죠 우선 장소를 찾고 참조하는 PlaceDescriptor를 소개할게요 다음으로 지오코딩과 이를 활용해 장소 관련 정보를 표시하는 방법을 설명하겠습니다 마지막으로 방향 안내와 Look Around API를 통해 사용자를 목적지로 안내하는 방법을 다루겠습니다 먼저 장소를 찾고 참조하는 방법으로 시작하겠습니다 작년에 Apple은 MapKit 프레임워크에서 지도 항목이나 MapKit JS에서 Place로 표현되는 장소를 참조하기 위해 사용할 수 있는 식별자를 도입했습니다 이 참조는 고유하므로 시간이 지나도 유효한 상태로 남죠 Maps 팀이 웹사이트 URL와 같은 장소의 정보를 업데이트해도 장소 ID를 사용하는 앱은 최신 정보를 표시할 수 있습니다 이러한 ID는 고유하므로 앱은 자체 데이터 구조에서 장소 ID를 키로 사용할 수 있죠 ID는 유지되고 공유될 수 있습니다 이 데이터는 Apple에서 추적하므로 언제든지 참조할 수 있습니다 MapKit으로 찾은 특정 장소에 대한 참조를 영속화하려는 경우 아직은 Place 식별자가 가장 효과적입니다 하지만 일부 경우에는 이 방법이 적절하지 않을 수 있죠 식별자가 없는 상황에서도 특정 장소에 대한 MapKit의 풍부한 데이터를 찾고 싶을 때가 있습니다 예를 들어, 소유하는 모든 비즈니스의 이름과 주소를 제공하는 웹 API나 CRM을 사용 중인 경우입니다 또는 특정 장소의 이름과 좌표를 알고 있는 경우도 있죠 이러한 경우 하나의 특정 장소를 찾아야 합니다 여러 결과를 반환하는 지역 검색처럼 작동하는 API는 적합하지 않습니다 소유하지 않은 코드 간에 장소 참조를 전달해야 하는 경우도 있습니다 예를 들어 프레임워크를 통해 장소를 제공하려는 경우입니다 또는 앱 인텐트를 사용할 때 장소를 인텐트 매개변수로 전달하거나 인텐트 결과로 장소를 반환하거나 앱 엔티티의 속성에 장소를 포함하려는 경우도 있죠 이때 MapKit을 전혀 사용하지 않는 다른 앱과 상호 작용할 수 있습니다 CLLocation과 같은 순수한 지리적 표현을 전달할 수는 있지만 MapKit 식별자를 사용할 때와 달리 풍부한 장소 정보를 찾는 데는 적합하지 않습니다 이러한 상황을 위해 새 유형이 도입되었죠 PlaceDescriptor입니다 새로운 프레임워크인 GeoToolbox에 포함되어 있습니다 PlaceDescriptor를 통해 장소를 구조화된 방식으로 설명하는 정보를 제공할 수 있습니다

    그러면 MapKit이나 다른 매핑 서비스 제공업체가 PlaceDescriptor로 해당 장소에 대한 풍부한 데이터를 찾을 수 있죠 PlaceDescriptor는 세 가지 최상위 정보를 포함합니다 우선 commonName이라는 문자열이 있습니다 PlaceDescriptor를 만들 때는 구겐하임 미술관이나 시드니 오페라 하우스처럼 잘 알려진 이름을 제공해야 합니다 이 필드는 ‘본가’와 같은 개인정보 데이터에는 부적절하며 포함해도 MapKit이 해당 장소를 찾을 때 도움이 되지 않습니다

    PlaceDescriptor는 표현의 배열도 포함합니다 이 표현은 지리적 정보를 다루는 모든 앱이나 프레임워크가 이해할 수 있는 일반적인 형식으로 되어 있습니다 세 가지의 PlaceRepresentation 유형 중에서 선택할 수 있습니다 첫째는 address 문자열로 우편물 보낼 때 쓰는 주소와 같죠 주소를 완전하게 제공할수록 MapKit이 위치를 찾을 가능성이 커집니다 두 번째는 알려진 랜드마크나 비즈니스처럼 특정 위치에 있는 객체를 위한 coordinate입니다 마지막은 CLLocation을 사용하는 deviceLocation으로 수신된 GPS 데이터와 함께 사용될 수 있으며 정확성, 타임스탬프, 제목, 속도 등 추가 값을 포함할 수 있습니다 표현 배열에는 최소한 1개의 표현이 포함되어야 하며 우선순위가 감소하는 순서로 정렬됩니다 예를 들어, PlaceDescriptor가 연락처 앱에서 온 경우 해당 장소의 주소에서 좌표가 파생될 수 있습니다 이 경우 주소가 정보의 원래 출처이므로 address가 먼저 표시되고 그다음 coordinate이 나타납니다 마지막으로, PlaceDescriptor에는 supportingRepresentations 배열이 있습니다 여기에는 일부 애플리케이션에서 사용할 수 없으며 필수적이지 않은 표현이 포함됩니다 supportingRepresentations 배열은 비워 둘 수 있습니다 supportingRepresentations에 포함될 수 있는 항목은 나중에 설명할게요 PlaceDescriptor와 새로 도입되는 다른 API를 설명하기 위해 예시로 제 애플리케이션을 살펴보겠습니다 이 애플리케이션은 전 세계의 먼 지역에 있는 분수를 찾는 분수 애호가를 위한 것입니다 먼저 방문하기 좋은 더블린의 분수를 수집하고 지도에 표시하는 것부터 시작하겠습니다

    SwiftUI용 MapKit이 도입된 이후로 좌표를 사용하여 지도 마커를 간단히 만들 수 있는데요 이번에는 앱에서 다른 모든 MapKit API와 함께 분수에 관한 풍부한 Apple 지도 데이터를 활용하고자 합니다 장소 ID가 없더라도요 PlaceDescriptor를 사용하기에 좋은 기회입니다 이 분수를 참조하기 위해 PlaceDescriptor를 만들어 볼게요 먼저 GeoToolbox를 가져옵니다 이 좌표에 분수가 있다는 것을 알고 있으므로 PlaceDescriptor를 만들 때 이 좌표에 대한 표현을 제공할 것입니다 이 분수의 이름이 Anna Livia Fountain이므로 이 또한 제공하겠습니다 유효한 PlaceDescriptor를 간단히 만들었습니다 이제 MapKit을 가져오고 PlaceDescriptor를 사용해 MapItem 요청을 생성할 수 있습니다 요청을 생성했으니 이를 실행하여 장소에 대한 MKMapItem을 얻을 수 있습니다 MapItem은 MapKit에서 장소의 기본 유형이며 모든 종류의 API와 함께 사용할 수 있습니다

    예를 들어, MapItem을 지도에 적용할 수 있습니다 마커를 통해 Apple 지도에서 해당 장소에 할당된 이름, 색상, 아이콘이 표시됩니다

    이제 지도에 두 번째 장소를 추가해 보겠습니다 이번에는 주소로 설명자를 만들게요 이 분수에 대한 가장 완전한 주소를 제공하면 됩니다 그러면 주소와 분수의 이름을 사용하여 PlaceDescriptor를 만들 수 있습니다 이전과 마찬가지로 MKMapItemRequest를 사용하여 다른 분수와 함께 지도에 추가합니다 간단하죠 PlaceDescriptor를 통해 이름이 있는 장소를 찾는 방법과 coordinate 및 address PlaceRepresentation에 대해 설명했습니다 그런데 사용할 수 있는 최상위 PlaceDescriptor 속성이 하나 더 있죠 SupportingRepresentation에는 serviceIdentifier라는 단일 유형이 있습니다 serviceIdentifier 표현은 딕셔너리로, 여기에서 키는 특정 매핑 서비스의 번들 식별자이며 값은 해당 매핑 서비스에서 장소를 나타내는 식별자입니다

    예를 들어, 특정 장소의 MapKit 장소 식별자를 알고 있으면 키가 com.apple.mapKit이고 값이 식별자인 딕셔너리를 만들 수 있죠 그런 다음 serviceIdentifiers 표현을 만들고 이를 PlaceDescriptor 이니셜라이저의 supportingRepresentations 매개변수로 전달합니다 다른 매핑 서비스 제공업체에서 사용하는 장소의 식별자를 알고 있다면 여기에서 제공할 수 있습니다 MapKit은 다른 식별자를 사용하지 않지만 앱 인텐트 등 다른 환경에서는 제공하는 것이 좋을 수 있습니다 MapKit을 사용하지 않는 다른 앱에 PlaceDescriptor를 제공할 수 있거든요 식별자는 원하는 대로 제공할 수 있습니다 MapKit API를 사용하는 경우 서비스 식별자는 항상 올바르게 처리됩니다 MapKit 식별자가 존재하면 MKMapItemRequest는 PlaceDescriptor에 있는 식별자를 사용하여 장소를 가져옵니다 MapKit 식별자가 없거나 제공된 식별자의 사용이 실패한 경우 PlaceDescriptor에 정의된 다른 표현을 사용하여 장소를 찾습니다 마찬가지로, 다른 방법으로 얻은 MapItem으로 PlaceDescriptor를 만드는 경우 식별자를 포함하여 필요한 모든 표현으로 PlaceDescriptor가 채워지게 됩니다 PlaceDescriptor와 MKMapItemRequest를 사용하여 다른 더블린 분수를 앱에 추가하겠습니다 PlaceDescriptor로 요청된 MapItem을 다른 MapKit API와 함께 사용하면 식별자나 MKLocalSearch로 가져온 경우처럼 풍부한 지도 데이터를 표시할 수 있습니다

    장소 카드를 예로 들 수 있습니다 PlaceDescriptor로 요청된 장소에 대해 장소 카드를 표시하면 운영 시간과 같은 최신 상태의 풍부한 데이터와 Apple 지도로 연결되는 링크를 제공할 수 있죠 단 한 줄의 코드로 사용자가 제 앱에서 분수를 선택할 때 장소 카드를 표시할 수 있습니다 장소 카드를 사용하면 앱에서 장소에 대한 여러 정보를 간편하게 제공할 수 있습니다 WWDC24의 ‘MapKit으로 장소 정보를 효과적으로 활용하기’에서 자세히 알아보세요

    장소 카드에 대해 말하자면 올해부터 MapKit JS의 장소 카드는 Apple 지도로 연결되는 범용 링크를 제공합니다 지도 앱이 설치된 기기에서는 링크가 지도에서 열립니다 지도 앱이 설치되지 않은 기기에서는 장소 카드 링크가 maps.apple.com으로 연결됩니다 이 기능은 작년 여름에 공개 베타로 출시되었습니다 이제 앱과 웹사이트가 Apple 지도에 연결되어 있으면 Apple 외 플랫폼에서도 웹에서 지도를 사용해 자세히 탐색할 수 있습니다 iOS 18.4가 출시됨에 따라 지도의 URL 처리 방식이 업데이트되면서 안정적으로 작동하는 유사한 범용 링크를 만들 수 있죠 예를 들어, 이 URL로 검색을 수행할 수 있습니다 매개변수가 더 일관되고 단순하고 읽기 쉽도록 개선했으며

    지도의 더 많은 기능에 연결할 수 있도록 여러 매개변수도 추가했습니다 이 비디오 리소스에 링크로 포함된 ‘통합된 지도 URL 채택하기’를 확인하여 앱에서 범용 지도 링크를 채택하세요

    좋습니다 장소를 찾았습니다 다음으로, 앱에서 장소에 대한 추가 정보를 표시하기 위해 지오코딩과 주소 표현을 사용하는 방법을 보여드리겠습니다

    혹시 익숙하지 않으시다면 순방향 지오코딩은 주소를 통해 해당 주소가 가리키는 좌표를 찾는 과정을 뜻합니다 예를 들어, 연락처 앱에서 주소를 탭하면 지도가 열립니다

    역방향 지오코딩은 이와 반대로 좌표를 제공하면 주소를 받게 됩니다 예를 들어, 사용자가 지도 앱에서 핀을 놓으면 해당 위치의 주소 정보가 표시되죠

    iOS 18 및 이전 버전에서는 지오코딩 작업을 위해 CoreLocation을 사용했습니다 올해 CLGeocoder가 지원 중단되고 CLPlacemark가 소프트 지원 중단되며 Geocoding이 MapKit에 도입됩니다

    발견 후 근사하게 촬영해 둔 분수를 제 앱을 통해 기록해 두고 싶습니다 이 사진에는 사진이 촬영된 위치의 좌표를 알려 주는 지오태그가 있지만 이름과 같은 추가 정보는 없습니다 즉, PlaceDescriptor를 사용하여 장소를 찾을 수 없습니다 제가 아는 건 좌표뿐입니다 따라서 MapKit의 역방향 지오코딩을 사용하여 사진과 함께 표시할 추가 정보를 찾겠습니다

    첫 분수 사진에 대해 역방향 지오코딩을 진행하겠습니다

    사진이 촬영된 좌표로 시작합니다 그런 다음 해당 위치에 대해 MKReverseGeocodingRequest를 만들겠습니다 앞서 보여드린 PlaceDescriptor의 MKMapItemRequest와 달리 MKReverseGeocodingRequests의 이니셜라이저는 옵셔널을 반환합니다 CLLocation에 유효하지 않은 좌표가 제공되면 MapKit은 요청을 처리할 수 없습니다 요청이 반환되면 지도 항목의 배열을 얻게 됩니다 대부분의 지오코딩 요청에서는 이 배열에 항목 1개만 포함됩니다 첫 번째 항목을 선택하겠습니다 참고로 이 지도 항목은 지오코딩 API로부터 받았으므로 관심 장소에 대한 풍부한 정보를 포함하지 않습니다 이 지도 항목에는 주소 지점에 대한 정보만 포함됩니다 이제 지도 항목을 얻었으니 주소를 표시할 수 있습니다

    MKReverseGeocoding 요청을 사용하여 나머지 사진에 대한 주소를 얻은 후 목록에 표시할게요 앱이 점차 완성되어 가네요 그런데 이 화면에 주소 전체를 표시할 필요는 없을 것 같습니다 주소를 다르게 표시할 방법을 찾아보죠 MKMapItem은 주소 정보 접근을 위해 선택 사항인 속성을 2개 제공하죠

    첫 번째는 MKAddress입니다 직접 MKMapItem을 만들 때 자체 MKAddress를 인스턴스화할 수 있습니다 또한 MapKit은 지오코딩이나 지역 검색, PlaceDescriptor 해결과 같은 API에서 MapItem을 반환할 때도 MKAddress를 제공합니다 두 번째는 MKAddressRepresentations로 이니셜라이저가 없습니다 주소 표현은 MapKit API에서 반환된 지도 항목에서만 사용할 수 있습니다

    먼저 MKAddress를 설명하겠습니다 MKAddress는 두 가지 문자열 속성인 fullAddress와 shortAddress를 보유합니다

    fullAddress는 우편 또는 행정 주소의 가장 완전한 버전이며 shortAddress는 가장 중요한 부분만 제공합니다

    상황에 따라 아주 간단한 주소를 제공할 수 있습니다 예를 들어, 바다 한가운데의 좌표에 대한 역방향 지오코딩 결과는 한 줄로 표시될 수 있습니다

    MapItem을 인스턴스화하면 주소 속성이 MapKit 장소 카드에 사용되므로 자체 주소 정보를 표시할 수 있습니다

    MKAddress는 주소의 간단한 버전을 제공하지만 MKAddressRepresentations는 앱에서 주소 정보를 표시하는 강력한 방법을 다양하게 제공합니다 예를 들어 전체 주소 목록을 표시하되 모든 주소가 같은 국가에 속한다면 앱 UI에서 지역을 생략하고 싶어 할 수 있습니다 이 경우 fullAddress에서 includingRegion에 대해 false를 지정하면 됩니다 또는 도시를 나열하고 각 도시가 어디에 있는지 추가 정보를 제공하고 싶어 할 수 있습니다 ‘로스앤젤레스, 캘리포니아’처럼 주나 지방을 표시하거나 ‘파리, 프랑스’와 같이 국가를 포함하고 싶을 수도 있죠 지도 항목을 요청하는 기기의 언어 및 지역 정보를 기반으로 주소에 적절한 형식을 자동으로 선택하는 MapKit으로 쉽게 구현할 수 있죠 앱에서 사용할 수 있는 여러 주소 표현에 대해 알아봤으니 cityWithContext로 사진과 함께 표시되는 주소 정보를 더 간결하게 만들겠습니다 이제 앱에 적절한 수준으로 주소가 표시되네요, 멋집니다

    순방향 지오코딩을 위한 API는 역방향 지오코딩과 유사합니다 MKGeocodingRequest를 사용하면 주소에 대한 MapItem이 반환됩니다 이를 통해 쉽게 좌표에 접근하거나 좌표를 지도에 추가할 수 있죠 또한 앞서 언급한 주소 정보 관련 옵션이 모두 포함되어 있으므로 지오코딩 요청을 만들기 전에 사용할 수 없었던 다양한 주소 표시 형식을 활용할 수 있습니다

    이제 위치를 찾고 관련 정보를 표시했으니 해당 위치로 이동하는 데 도움이 되는 MapKit API를 보여드릴게요 MapKit에는 도보, 운전 등 다양한 이동 수단을 통해 출발지와 목적지 사이를 이동하는 경로를 찾아주는 경로 API가 있습니다 경로는 시간 및 거리 추정치와 함께 경로에서 따라야 할 모든 단계에 관한 세부 정보도 표시합니다

    더블린의 지도 뷰로 돌아가서 제가 선별한 분수로 이동하는 경로를 계획해 보겠습니다 지도에서 선택을 활성화하기 위해 지도 이니셜라이저에 대해 지도 항목 바인딩을 제공할게요 이렇게 하면 선택된 항목이 변경될 때 경로를 계산할 수 있죠 WWDC23의 ‘SwiftUI용 MapKit 알아보기’에서 지도 선택을 처리하는 방법을 자세히 알아보세요 경로를 받으려면 먼저 경로 요청을 만듭니다 그런 다음 기기의 현재 위치를 source로 선택된 지도 항목을 destination으로 설정합니다 그 후 directions 객체를 만듭니다 마지막으로 경로를 계산하면 됩니다 오류를 완전히 처리한 다음 응답을 처리하겠습니다 그런데 경로 요청 응답에는 무엇이 포함될까요?

    일치한 경로에 대한 source와 destination이 반환됩니다 이러한 값은 요청에서 제공한 값과 약간 다를 수 있습니다 예를 들어, 운전 경로는 주차 상황을 고려할 수 있으며 도보 경로는 건물의 문까지 직접 안내할 수 있습니다

    또한 요청을 충족하는 하나 이상의 경로가 포함된 배열도 포함됩니다

    경로는 강력한 정보를 포함합니다 여기에는 경로 제목으로 사용할 수 있는 현지화된 이름 도로 폐쇄처럼 경로와 관련된 알림 배열 해당 경로에서 이동해야 하는 미터 단위의 거리 해당 경로 이동에 소요되는 시간 지도에 표시하기에 적합한 경로 지오메트리 등이 포함됩니다

    올해 MapKit에는 자전거 경로 안내 기능에 대한 지원이 추가되었습니다 더블린의 분수를 둘러보기에는 자전거가 가장 좋을 것 같습니다 앱의 경로 요청에서 속성 하나만 수정하면 됩니다 경로 안내에 자전거 경로를 표시하기 위해 응답에서 첫 번째 경로를 선택합니다 그리고 MapPolyline을 사용하여 지도에 추가합니다 경로를 표시하는 것이 이토록 간단합니다

    MapKit의 자전거 경로는 강력합니다 운전 시 사용할 수 없는 길과 도로를 활용하며 자전거에 적합하지 않은 도로는 제외합니다 MapKit JS로도 자전거 경로와 예상 도착 시간을 얻을 수 있죠 Swift에서와 마찬가지로 기존 경로 요청에 자전거를 이동 수단 유형으로 지정하기 위해 단 한 줄의 구성만 추가하면 됩니다

    또한 올해 처음 도입된 기능으로 이제 MapKit으로 watchOS에서 경로를 확인할 수 있습니다 최신 watchOS SDK가 도입되면서 20개 이상의 MapKit API가 Apple Watch에 추가되었습니다

    분수 투어에 적합한 자전거 경로를 확보했으니 출발 전에 경로를 미리 확인할 수 있다면 더 편안하게 이동할 수 있겠네요 지도의 주변보기 기능을 활성화하면 도시의 360도 대화형 거리 이미지를 보고 도로, 자전거 도로와 주차장 랜드마크를 쉽게 미리 확인할 수 있습니다

    주변보기는 iOS 16에서 MapKit 앱에 도입되었으며 특정 위치에 이미지가 있는지 보고 주변보기 이미지를 미리 확인하고 이미지를 전체 화면으로 표시하는 API도 이때 추가되었습니다 자세한 내용은 WWDC 2022의 ‘MapKit의 새로운 기능’ 세션에서 확인해 보세요

    올해 MapKit JS에 주변보기가 추가되었으므로 주변보기를 웹사이트나 웹 애플리케이션에서 구현할 수 있습니다 추가할 수 있는 주변보기 뷰는 두 종류가 있습니다

    첫 번째는 대화형 주변보기로 탐색 가능한 주변보기 뷰를 자체 UI에 삽입할 수 있습니다 두 번째는 주변보기 미리보기입니다 이 기능은 원하는 위치에서의 정적 이미지 스냅샷을 제공합니다 미리보기 이미지를 클릭하면 전체 화면 대화형 경험이 실행됩니다 웹사이트에 대화형 주변보기 뷰를 추가하려면 place 객체가 필요하죠 장소를 반환하는 MapKit JS API라면 모두 사용 가능합니다 예로 placeLookup, search 및 geocoding이 있죠 이번에는 식별자가 있으므로 placeLookup을 사용하겠습니다 그런 다음 포함된 DOM 요소를 전달하는 LookAround 객체와 place 객체, 마지막으로 options 딕셔너리를 만듭니다 LookAroundView는 세 가지 옵션을 지원합니다 첫 번째는 openDialog입니다 이 옵션이 true인 경우 LookAroundView가 전체 브라우저 윈도우를 덮습니다 두 번째는 showsDialogControl입니다 이 옵션이 true인 경우 전체 화면 경험을 시작하고 닫는 버튼이 LookAroundView에 표시됩니다 마지막은 showsCloseControl입니다 이 옵션이 true인 경우 LookAroundView를 닫는 버튼이 포함됩니다 MapKit JS는 LookAroundView와 관련된 다양한 이벤트를 발생시킵니다 이벤트 리스너를 통해 기본 동작에 응답하거나 이를 재정의할 수 있죠 예를 들어, 사용자가 닫기 버튼을 탭하면 close 이벤트가 전송됩니다 이 콜백을 사용하여 앱에서 필요한 애니메이션이나 상태 변경을 실행할 수 있습니다

    이 이벤트의 기본 동작을 취소하지 않으면 lookAround 뷰가 DOM에서 삭제됩니다 처리하면 좋은 다른 이벤트는 다음과 같습니다 우선 뷰가 완전히 로드되었을 때 발생하는 Load 이벤트가 있습니다 문제가 발생했을 때 발생하는 Error 이벤트도 있습니다 예를 들어, 이미지를 사용할 수 없거나 브라우저가 뷰를 표시할 수 없을 때 발생합니다 MapKit JS는 오류 UI를 제공하지만 자체 오류 또는 폴백 경험을 구현할 수 있습니다 마지막으로 lookAround는 readystatechange 이벤트를 발생시킵니다 뷰의 라이프사이클을 모니터링하기 위해 활용할 수 있죠 readyState는 뷰가 로드 중이거나 로드가 완료되었거나 오류가 발생했거나, 뷰가 DOM에서 제거되었을 때 변경됩니다 LookAroundView 외에도 Look Around Preview API로 간단한 경험을 구현할 수 있죠 주변보기 미리보기는 대화형으로 구현할 수 없습니다 사용자는 뷰를 이동할 수 없습니다 주변보기 미리보기를 클릭하면 전체 화면의 주변보기 경험이 실행됩니다 MapKit JS와 주변보기는 웹사이트를 개선하는 데 많은 도움이 될 것입니다 이상으로 세션을 마무리하겠습니다 많은 내용을 다루었습니다 MapKit과 MapKit JS로 장소를 찾고, 장소 정보를 표시하며 전 세계의 장소로 이동하는 방법을 보여드렸습니다

    세션을 마치기 전에 몇 가지 작업을 추천해 드릴게요 PlaceDescriptor를 사용하여 식별자 유무와 상관없이 장소를 찾고 다른 앱에 장소 참조를 전송하세요 Apple 지도 링크를 새로운 통합 URL 형식으로 업데이트하세요

    지오코딩을 위해 앱을 CoreLocation에서 MapKit API로 이전하고 우수한 주소 표현을 활용하세요 마지막으로, 앱에 자전거 경로 안내와 주변보기를 추가하여 사용자가 목적지로 이동할 수 있도록 지원하세요

    MapKit에 관한 이 세션을 시청해 주셔서 감사합니다

    • 4:49 - Putting Marker on the Map with a coordinate

      // Putting Marker on the Map with a coordinate
      
      let annaLiviaCoordinates = CLLocationCoordinate2D(
          latitude: 53.347673,
          longitude: -6.290198
      )
      var body: some View {
          Map {
             Marker(
                  "Anna Livia Fountain",
                  coordinate: annaLiviaCoordinates
              )
          }
      }
    • 5:07 - Creating and resolving a PlaceDescriptor with coordinate PlaceRepresentation

      // Creating and resolving a PlaceDescriptor with coordinate PlaceRepresentation
      
      import GeoToolbox
      import MapKit
      
      let annaLiviaCoordinates = CLLocationCoordinate2D(
          latitude: 53.347673,
          longitude: -6.290198
      )
      let annaLiviaDescriptor =  PlaceDescriptor(
          representations: [.coordinate(annaLiviaCoordinates)],
          commonName: "Anna Livia Fountain"
      )
      
      let request = MKMapItemRequest(placeDescriptor: annaLiviaDescriptor)
      do {
          annaLiviaMapItem = try await request.mapItem
      } catch {
          print("Error resolving placeDescriptor: \(error)")
      }
    • 5:56 - Creating and resolving a PlaceDescriptor with address PlaceRepresentation

      // Creating and resolving a PlaceDescriptor with address PlaceRepresentation
      
      import GeoToolbox
      import MapKit
      
      let address = "121-122 James's St, Dublin 8"
      let descriptor =  PlaceDescriptor(
          representations: [.address(address)],
          commonName: "Obelisk Fountain"
      )
      
      let request = MKMapItemRequest(placeDescriptor: descriptor)
      do {
          obeliskFountain = try await request.mapItem
      } catch {
          print("Error resolving placeDescriptor: \(error)")
      }
    • 6:45 - Creating a PlaceDescriptor with identifiers

      // Creating a PlaceDescriptor with identifiers
      
      import GeoToolbox
      
      let annaLiviaCoordinates = CLLocationCoordinate2D(
          latitude: 53.347673,
          longitude: -6.290198
      )
      let identifiers = ["com.apple.MapKit" : "ICBB5FD7684CE949"]
      let annaLiviaDescriptor =  PlaceDescriptor(
          representations: [.coordinate(annaLiviaCoordinates)],
          commonName: "Anna Livia Fountain",
          supportingRepresentations: [.serviceIdentifiers(identifiers)]
      )
    • 7:28 - Fetching a MapItem from a PlaceDescriptor

      // Fetching a MapItem from a PlaceDescriptor
      
      let request = MKMapItemRequest(placeDescriptor: descriptor)
      let mapitem = try await request.mapItem
    • 7:43 - Getting a PlaceDescriptor from a MapItem

      // Getting a PlaceDescriptor from a MapItem
      
      let descriptor = PlaceDescriptor(mapItem: mapitem)
    • 8:10 - Place Card

      // Place Card
      
      var body: some View {
          Map {
              ForEach(fountains, id:\.name) { fountain in
                  Marker(item: fountain)
                      .mapItemDetailSelectionAccessory(.callout)
              }
          }
      }
    • 10:45 - Reverse geocode with MapKit

      // Reverse geocode with MapKit
      
      import MapKit
      
      let millCreekCoordinates = CLLocation(latitude: 39.042617, longitude: -94.587526)
      if let request = MKReverseGeocodingRequest(location: millCreekCoordinates) {
          do {
              let mapItems = try await request.mapItems
              millCreekMapItem = mapItems.first
          } catch {
              print("Error reverse geocoding location: \(error)")
          }
      }
    • 13:50 - Forward geocoding with MapKit

      // Forward geocoding with MapKit
      
      var body: some View {
          Map {
              if let mapItem {
                  Marker(item: mapItem)
              }
          }
          .task {
              let request = MKGeocodingRequest(
                  addressString: "1 Ferry Building, San Francisco"
              )
              do {
                  mapItem = try await request?.mapItems.first
              } catch {
                  print("Error geocoding location: \(error)")
              }
          }
      }
    • 14:38 - Allowing Map Selection

      // Allowing Map Selection
      
      @State var selectedItem: MKMapItem?
      
      var body: some View {
          Map(selection: $selectedItem) {
             UserAnnotation()
             ForEach(fountains, id: \.self) { item in
                Marker(item: item)
             }
          }
          .onChange(of: selectedItem) {
             // Compute Route
          }
      }
    • 15:00 - Fetch a route

      // Fetch a route
      
      let request = MKDirections.Request()
      request.source = MKMapItem.forCurrentLocation()
      request.destination = selectedItem
      let directions = MKDirections(request: request)
      do {
          let response = try await directions.calculate()
          returnedRoutes = response.routes
      } catch {
          print("Error calculating directions: \(error)")
      }
    • 16:06 - Fetch a cycling route

      // Fetch a cycling route
      
      let request = MKDirections.Request()
      request.source = MKMapItem.forCurrentLocation()
      request.destination = selectedItem
      request.transportType = .cycling
      let directions = MKDirections(request: request)
      do {
          let response = try await directions.calculate()
          returnedRoutes = response.routes
      } catch {
          print("Error calculating directions: \(error)")
      }
    • 16:25 - Display a route on the Map

      // Display a route on the Map
      
      Map {
          if let mapRoute {
              UserAnnotation()
              MapPolyline(mapRoute)
                  .stroke(Color.blue, lineWidth: 5)
          }
      }
    • 16:40 - Cycling directions in MapKit JS

      // Cycling directions in MapKit JS
      
      let directions = new mapkit.Directions();
      directions.route ({
          origin: safariPlayground,
          destination: cherryHillFountain,
          transportType: mapkit.Directions.Transport.Cycling
      }, (error, { routes: [{ polyline }] }) => {
          polyline.style.lineWidth = 5;
          map.showItems([
              new mapkit.PlaceAnnotation(place),
              new mapkit.PlaceAnnotation(
                place2,
                { selected: true }
              ),
              polyline
          ]);
      });
    • 17:26 - Look Around

      // Look Around
      
      var body: some View {
          Map {
              ForEach(fountains, id:\.name) { fountain in
                  Marker(item: fountain)
             }
          }
          .overlay(alignment: .bottomLeading) {
              if (lookAroundScene != nil) {
                  LookAroundPreview(scene: $lookAroundScene)
                      .frame(width: 230, height: 140)
                      .cornerRadius(10)
                      .padding(8)
              }
          }
      }
    • 18:10 - Look Around View in MapKit JS

      // Look Around View in MapKit JS
      
      const placeLookup = new mapkit.PlaceLookup();
      const place = await new Promise(
          resolve => placeLookup.getPlace(
              "IBE1F65094A7A13B1",
              (error, result) => resolve(result)
          )
      );
      
      // Create an interactive look around view.
      const lookAround = new mapkit.LookAround(
          document.getElementById("container"),
          place,
          options
      );
    • 18:35 - Look Around Options

      // Look Around Options for MapKit JS
      
      const options = {
          // Enters a full window experience
          // immediately on load
          openDialog: true,
          
          // Provides a button to enter and
          // exit full window.
          showsDialogControl: true,
          
          // Provides a button to destroy
          // the look around view.
          showsCloseControl: true,
      };
    • 19:10 - Handle MapKit JS Look Around events

      // Handle MapKit JS Look Around events
      
      lookAround.addEventListener(
          "close",
          event => {
              app.closeView();
              event.preventDefault();
          }
      );
      
      lookAround.addEventListener(
          "load",
          event => app.fadeInView()
      );
      
      lookAround.addEventListener(
          "error",
          event => app.fadeOutView()
      );
      
      lookAround.addEventListener(
          "readystatechange",
          event => console.log(lookAround.readyState)
      );
    • 20:01 - MapKit JS Look Around Preview

      // MapKit JS Look Around Preview
      
      const lookAround = new mapkit.LookAroundPreview(
          document.getElementById("container"),
          place
      );
    • 0:00 - 서론
    • 사람들은 Apple 지도를 사용하여 랜드마크, 카페, 상점, 하이킹 코스 등 전 세계 위치를 탐색하고 살펴볼 수 있습니다. MapKit 및 MapKit JS 플랫폼을 사용하면 이러한 매핑 기능을 앱 및 웹사이트에 통합할 수 있습니다. 최근 업데이트에는 장소를 찾고 참조하기 위한 ‘PlaceDescriptor’, 장소 정보를 표시하기 위한 향상된 지오코딩, 길찾기 및 탐색 지원을 제공하기 위한 Look Around API가 포함됩니다.

    • 0:45 - 장소 찾기
    • 새로운 프레임워크인 GeoToolbox에 ‘PlaceDescriptor’ 유형이 포함되었습니다. ‘PlaceDescriptor’를 사용하면 일반적인 이름, 주소, 좌표 또는 기기 위치와 같이 구조화된 정보를 사용하여 장소를 표현할 수 있습니다. 이 기능은 외부 API 또는 CRM의 데이터로 작업하는 경우 또는 MapKit를 사용하지 않는 코드에 장소 참조를 전달하는 경우와 같이 위치에 고유한 MapKit Place ID가 없을 때 유용합니다. ‘PlaceDescriptor’를 사용하면 MapKit 또는 다른 지도 서비스 제공업체에서 지정된 장소에 대한 풍부한 데이터를 찾을 수 있습니다. ‘PlaceDescriptor’ 내 표현 배열은 우선순위가 감소하는 순서로 정렬되어 가장 정확한 정보가 먼저 표시되기 때문에 가장 정확한 위치 식별이 보장됩니다. 좌표, 주소 또는 서비스 식별자를 지정하는 등 다양한 방법을 사용하여 ‘PlaceDescriptor’를 생성합니다. 서비스 식별자는 번들 식별자를 특정 매핑 서비스의 고유한 장소 식별자에 매핑하는 사전입니다. 이를 통해 다양한 매핑 서비스 간의 유연성과 상호 운용성이 지원됩니다. ‘PlaceDescriptor’를 사용하여 ‘MKMapItemRequest’를 생성하는 경우, MapKit은 사용 가능한 경우 서비스 식별자의 MapKit 식별자를 우선적으로 사용합니다. 그렇지 않은 경우, 좌표 또는 주소와 같은 다른 표현을 사용하여 장소를 가져옵니다. ‘PlaceDescriptors’를 사용하면 지도에 장소를 쉽게 추가하고, 풍성한 정보가 담긴 장소 카드를 표시하며, Apple 지도에 대한 범용 링크를 생성해 다양한 기기 및 플랫폼 전반에서 원활한 사용자 경험을 제공할 수 있습니다.

    • 9:34 - 장소 표시하기
    • iOS 18에서는 지오코딩 프로세스가 MapKit에 통합되어 지원 중단된 CoreLocation 클래스인 ‘CLGeocoder’ 및 ‘CLPlacemark’를 대체합니다. 지오코딩에는 순방향 및 역방향의 두 가지 주요 프로세스가 포함됩니다. 순방향 지오코딩은 주소를 좌표로 변환하는 반면, 역방향 지오코딩은 반대로 좌표를 받아 주소를 제공합니다. 새로운 MapKit API를 사용하면 ‘MKReverseGeocodingRequest’를 사용하여 역방향 지오코딩 요청하여 일반적으로 특정 위치에 대한 항목을 하나만 포함하는 맵 항목 배열을 반환합니다. 주소 정보를 표시하려면 ‘MKAddress’ 및 ‘MKAddressRepresentations’를 사용하세요. ‘MKAddress’는 간단하게 전체 주소 문자열과 짧은 주소 문자열을 제공하는 반면, ‘MKAddressRepresentations’는 더 많은 유연성을 제공하여 로케일 및 앱의 특정 요구 사항과 같은 요소를 기반으로 주소 표시를 사용자 정의하여 위치 데이터를 보다 간결하고 사용자 친화적으로 표현할 수 있습니다.

    • 14:14 - 경로 찾기
    • MapKit은 사람들이 걷기, 운전하기 그리고 이제는 자전거 타기 등 다양한 교통수단을 이용하여 장소 간 경로를 찾을 수 있도록 지원하는 API 길찾기 서비스를 제공합니다. API는 시간과 거리 추정치, 단계별 지침, 지도에 그리기 위한 경로의 기하학 등 자세한 경로 정보를 제공합니다. 길찾기 요청을 생성하고, 출발지와 목적지를 설정하며, 경로를 계산할 수 있습니다. 응답에는 일치하는 출발지와 목적지 위치, 하나 이상의 경로, 도로 폐쇄와 같은 관련 공지가 포함됩니다. MapKit도 확장되어 watchOS 및 MapKit JS에서 자전거 경로 안내를 지원하여 사람들은 시계와 웹사이트에서 자전거 경로를 계획할 수 있습니다. 또한, 360도 거리 수준 이미지를 제공하는 Maps Look Around 기능이 iOS 16의 MapKit 앱에 추가되었고 이제 MapKit JS에서도 사용할 수 있어 인터랙티브형 거리 뷰로 앱의 기능을 향상시킬 수 있습니다.

Developer Footer

  • 비디오
  • WWDC25
  • MapKit에 고급 기능 추가하기
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드(영문)
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    Apple Developer 앱 받기
    Copyright © 2025 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침