스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
SwiftUI용 MapKit 알아보기
SwiftUI의 확장된 MapKit 지원으로 앱에 지도를 결합하는 작업이 더욱 간편해졌습니다. SwiftUI를 사용해 지도에 주석과 오버레이를 추가하고, 카메라를 조작하는 방법 등을 소개합니다.
리소스
관련 비디오
WWDC23
WWDC22
-
다운로드
♪ ♪
안녕하세요, 제프입니다 저는 MapKit 팀 엔지니어이고 오늘 여러분께 SwiftUI용 Mapkit을 소개해 드리겠습니다 확장된 SwiftUI API를 통해 어떤 플랫폼에서든 앱에 더욱 손쉽게 지도를 결합할 수 있게 되었습니다 사용자들에게 강력한 지도 활용 경험을 제공할 수 있는 SwiftUI용 Mapkit이 여러분도 마음에 드실 겁니다 얼마나 쉬운지 알 수 있게 완벽하게 작동하는 여행 플래너를 처음부터 제작해 볼게요 단계별로 전부 보여 드릴 텐데 세션이 종료되기 전에 끝날 겁니다 제 가족이 이번 주말에 고향인 뉴잉글랜드로 돌아가는데 토요일에 아름다운 보스턴에서 시간을 보내려고 해요 아침에 도시를 산책하며 풍경을 감상하고 역사가 깊은 노스엔드에서 점심을 먹을 겁니다 디저트로 카놀리도 먹을까 합니다 날씨가 정말 좋을 거라고 하니 오후에는 해변으로 가서 모래사장을 걸을 생각이에요 정말 즐거울 것 같습니다 그날 계획을 도와줄 앱을 제작해 볼게요 지도상의 장소를 마크할 수 있게 주석을 사용하고 각 마커를 탭하면 해당 장소의 정보가 표시되도록 선택 기능을 활성화겠습니다 가 볼 만한 곳을 둘러볼 수 있게 주변보기 기능을 결합하고 해변까지의 운전 경로를 보여 주는 오버레이도 추가하겠습니다 다양한 지역과 장소를 지도에 시각적으로 표시할 겁니다 사실적 고도 묘사로 지도를 3D로 볼 수 있게 하거나 위성 이미지와 항공 이미지를 표시하는 법도 보여 드릴게요 사용자 위치 버튼과 같은 조작 버튼을 추가해 현재 위치도 파악할 수 있게 하겠습니다 알아볼 것이 많으니 바로 시작해 볼겠습니다 최신 SwiftUI 프로젝트에서 시작하도록 하죠 Mapkit을 사용할 겁니다 Map도 추가하고요 좋아요 상호작용이 가능한 지도가 코드 한 줄로 나타났습니다 저희는 걸어 다닐 예정이라 보스턴까지 간 다음 차를 주차할 거예요 차를 대기 좋은 곳이 보스턴 근처에 있다던데 전 코먼 공원 아래에 있는 주차장을 이용하도록 할게요 코먼 공원은 보스턴 중심에 위치한 아름다운 공원입니다 도보 여행의 출발지로 딱 좋을 것 같아요 우선 주차장을 마크할 수 있도록 지도에 콘텐츠를 추가할게요 주차장으로 진입하는 경사로 위를 마크해 두려고 합니다 근처 엘리베이터를 타고 올라가 여행을 시작할 거예요 Marker와 Annotation을 사용해 지도상의 특정 좌표에 콘텐츠를 표시하는 법을 알려드리겠습니다 그럼 차를 주차해 두고 산책을 시작해 보죠 MapContentBuilder 클로저로 지도에 Marker를 추가할게요 좋습니다 SwiftUI에 익숙하면 아시겠지만 지도에 Marker를 추가하는 건 List에 View를 넣는 것과 비슷해요 Marker를 표시하기 위해 자동으로 지도가 확대되면서 콘텐츠를 화면에 잡아 줍니다 그런데 Marker가 뭘까요? MapContentBuilder를 사용해 다른 콘텐츠도 표시할 수 있을까요? Marker는 지도상의 특정 좌표에 콘텐츠를 표시하는 데 쓰입니다 여러분도 익숙할 풍선 모양이죠 모든 플랫폼의 지도 앱과 App Store의 다양한 앱에서 Marker가 사용되고 있습니다 Annotation도 마찬가지로 특정 좌표에 콘텐츠를 표시하죠 Marker는 풍선 모양인 반면 이건 SwiftUI의 View를 표시합니다 MapContentBuilder는 오버레이 콘텐츠도 표시할 수 있죠 나중에 다시 소개해 드릴게요 지금은 우선 MapContentBuilder 클로저로 지도에 콘텐츠를 추가하는 법을 익혀 둡시다 주차장에 사용자 지정 SwiftUI View를 표시하고 싶으니 Annotation을 사용해 마크해 볼게요 여기서 ZStack을 사용해 도형과 이미지를 만들 거예요 작성한 SwiftUI View는 지도의 주차장 좌표 중앙에 표시됩니다 좌표 위쪽에 표시하고 싶다면 Annotation의 앵커 매개변수를 사용하세요 앵커 값을 'bottom'으로 특정하면 Annotaion 좌표 아래에 View가 표시될 겁니다 좋아요 앱에 여행 출발지가 마크되었습니다 MapContentBuilder를 사용해 지도에 주석 콘텐츠를 표시했어요 이제 앱으로 지도상의 장소에 공간감을 구현하려고 합니다 그러니 mapStyle을 사용해서 사실적 지형 고도를 활성화할게요 mapStyle을 사용해 위성 이미지와 항공 이미지도 표시해 보겠습니다
mapStyle 수정자를 사용하면 지도의 형식을 지정할 수 있습니다
이건 standard mapStyle입니다 기본적으로는 실물 종이 지도처럼 평평한 화면을 표시하죠
강을 가로지르는 다리가 있어 건너편으로 걸어갈 수 있겠네요 하지만 평평한 지도이다 보니 일부분 상상에 맡겨야 하죠 realistic elevation을 활성화해 지도에 차원을 하나 더 추가할게요
realistic elevation을 활성화하니 지도가 더욱 생생해 보입니다 이렇게 강을 보니 여름날에 백조 모양 배를 타고 유유히 여행하는 모습이 그려지네요 배가 다리 밑을 지나는 장면도 상상되고요 imagery mapStyle 또한 사용자가 공간감을 느끼기에 좋은 방법입니다 imagery mapStyle은 위성 이미지나 항공 이미지로 렌더링된 지도를 표시합니다 hybrid mapStyle은 이미지에 도로와 레이블을 결합하죠 정리하자면, standard mapStyle로 사실적 고도를 활성화했습니다 그리고 몇 가지 다른 mapStyle을 소개해 드렸고요 이제 방문하려는 곳을 앱으로 검색할 수 있게 할게요 아이들과 함께 보스턴을 산책할 거라 아이들도 즐거운 시간을 보냈으면 해요 어른들은 역사적인 곳이 흥미로울 테지만 어린아이들은 그네나 미끄럼틀 구름사다리를 좋아하겠죠 놀이터와 해변을 검색하는 버튼을 추가해 볼게요 각각의 검색 결과에 따라 앱이 Marker를 추가할 겁니다 Marker를 조금 더 알아보고 검색 결과를 가리지 않으면서 본인의 UI를 표시하는 법도 알아보도록 하죠 BeantownButtons View를 사전에 만들어 두었습니다 버튼을 탭하면 검색 기능과 단순 쿼리를 불러옵니다 놀이터나 해변 같은 것들이요 검색 기능은 MKLocalSearch로 공원 주차장 인근 놀이터를 찾고 바인딩으로 결과를 출력합니다
앱의 메인 ContentView로 돌아가 볼게요 State를 추가해서 검색 결과를 추적하겠습니다 BeantownButtons UI가 검색을 실행하면 바인딩을 사용해 State로 결과를 반환하죠 지도 위 화면 하단에 버튼을 추가할게요 safeAreaInset를 사용하면 제가 추가한 콘텐츠나 지도 앱 로고, 법적 고지 링크처럼 화면에 뜨는 시스템 컨트롤을 앱의 UI가 가리지 않습니다 그럼 MapContentBuilder로 검색 결과 Marker를 추가해 볼게요 ForEach로 각각의 검색 결과마다 Marker를 추가합니다
버튼을 시험해 보죠 놀이터를 찾아봅시다 보세요, 놀이터가 나오네요 한눈에 볼 수 있도록 지도가 자동으로 축소되면서 모든 결과를 화면에 잡아 줍니다 해변을 검색해 볼까요? 검색 결과는 MKLocalSearch와 같은 MapKit API가 장소를 표시할 때 사용하는 MKMapItem입니다 여기서 Marker에 MKMapItem 이니셜라이저를 쓸게요 이렇게 생성한 Marker는 MKMapItem 이름을 명칭으로 쓰며 MKMapItem의 정보를 사용해 해당 장소를 나타내는 아이콘과 색상을 표시합니다 검색 결과 대부분이 담청색 파라솔 Marker로 나타나죠 MKMapItem으로 작업하면 Marker가 콘텐츠와 형식을 자동으로 지원해 무척 유용합니다 MKMapItem을 사용하지 않더라도 Marker의 외형을 조정할 수 있습니다 기본적으로 Marker는 보시는 대로 풍선 모양의 핀 아이콘입니다 imageAsset이나 systemImage로 다른 아이콘을 사용할 수 있어요 monogram을 사용하면 문자도 세 개까지 표시할 수 있죠 tint 수정자를 사용하면 마커의 색상을 변경할 수 있습니다 정리하자면, safeAreaInset로 검색 결과 Marker를 가리지 않고 지도 위에 버튼을 표시할 수 있어요 이제 지도에 표시되는 화면을 앱에서 제어하도록 할 겁니다 지금까지 지도에 콘텐츠를 추가했는데 매번 지도가 자동으로 콘텐츠를 화면에 잡아 주었죠 이 편리한 기능을 필요시에 활성화하는 법을 보여 드릴게요 보스턴 지역의 북부 해안선과 같은 다른 종류의 화면을 표시하는 법도 알아볼 겁니다 지금은 해변이 표시되어 있습니다
화면을 이동해 놀이터를 검색해 볼게요 더 이상 지도가 공원 주차장 인근 놀이터를 자동으로 표시하지 않습니다 사용자가 지도와 상호작용한 뒤에 검색 결과를 표시하려면 지도가 Marker를 화면에 잡을 수 있도록 지도의 카메라 위치 상태를 초기화해야 합니다
State를 추가해 카메라 위치를 추적할게요 지도에 추가한 콘텐츠를 화면에 잡아 주는 기본 automatic 위치를 사용할게요
이제 지도의 이니셜라이저에 바인딩을 넘겨줍니다
onChange 수정자를 사용해 검색 결과가 업데이트되는지 확인하죠 결과가 업데이트되면 카메라 위치만 automatic으로 돌려 화면에 보이게 하겠습니다
한번 해 보죠 해변을 검색한 다음 결과를 확인하고 놀이터를 검색하기 전에 화면을 이동할게요
좋아요 이제 검색을 실행하면 로드아일랜드까지 화면을 옮겨도 결과가 화면에 표시됩니다 위치 상태를 사용해 다른 것들도 구현해 보죠 보스턴에서 즐겁게 아침을 보낸 다음 저희는 차를 타고 북부로 이동해 해변에서 오후를 보낼 거예요 앞으로 갈 곳이 어디인지 더 잘 파악하기 위해 앱으로 북부 해안선을 간편하게 볼 수 있게 할 겁니다 위치 상태를 사용해서 말이죠
MKCoordinateRegion으로 도시와 해안 좌표를 추가할게요 BeantownButtons UI로 교체해 위치 상태에 바인딩을 추가하겠습니다
그리고 버튼을 두 개 추가해 region에 카메라 위치를 설정하죠
도시 버튼을 누르면 지도에 보스턴이 표시됩니다 파도 버튼을 누르면 지도에 북부 해안선이 표시될 거예요
ContentView로 돌아와 위치 바인딩을 버튼 UI로 넘깁니다
한번 해 보죠 파도 버튼을 탭하자 북부 해안 지역이 표시되도록 지도 위치가 업데이트됩니다 도시 버튼을 탭하면 보스턴이 나오도록 업데이트되죠 지도 앱에서 표시되는 것들은 결국 MapCamera가 관리합니다 카메라는 특정한 거리를 둔 채 좌표를 바라보는데 카메라의 방향이 지도에 보이는 것을 결정하죠 제가 제작하고 있는 앱은 카메라를 만들거나 구성하는 대신 MapCameraPosition을 사용해 표시해야 할 것만을 특정해 줬어요 Mapkit이 그에 따라 카메라를 조정하죠 앱은 automatic 카메라 위치로 검색 결과 등의 콘텐츠를 표시해요 region 위치를 사용해 보스턴과 북부 해안을 보여 주죠 다른 것을 화면에 잡도록 카메라 위치를 특정할 수도 있어요 rect는 region처럼 지역을 표시하는 데 사용됩니다 MKCoordinateRegion 대신 해당 지역의 MKMapRect를 사용하죠 item, camera, userLocation 카메라 위치를 자세히 살펴봅시다 MKMapItem을 사용하면 특정한 장소를 표시할 수 있죠 이는 모든 종류의 지도 항목에 적용됩니다 지도 항목이 케이프코드만을 표시하고 있다면 MapKit에서 화면에 맞도록 자동으로 지도를 축소합니다 노스엔드의 특정 공원을 표시하고 싶다면 카메라가 화면을 확대해 주변을 표시하고 공간감을 전달합니다 간단히 MapCamera를 적용해 원하는 방식으로 조정할 수도 있죠 MapCamera로 경사각을 설정하면 3D 화면을 표현하기 좋습니다 혹은 사용자가 찰스강을 따라 걷고 있을 때 카메라가 사용자 위치를 따라가게 할 수도 있죠 위치 권한을 허용하지 않았거나 기기가 위치 정보를 수신 중이어서 사용자의 위치를 알 수 없을 때는 fallback 위치를 적용하면 사용자의 위치를 따라갑니다 카메라 위치 상태에 바인딩을 보내면 카메라 위치가 변경될 때 Mapkit이 업데이트해 줍니다 사용자 위치의 카메라 위치입니다 followsUserLocation 값이 true죠 사용자가 화면을 이동하면 카메라는 더 이상 따라오지 않아요 사용자가 지도와 상호작용하면 카메라 위치 상태는 positionedByUser가 됩니다 앱이 카메라 위치 상태를 userLocation으로 되돌리면 카메라가 사용자 위치를 따라갑니다 앱이 카메라 위치 상태를 정하면 positionedByUser는 비활성화되죠 사용자는 어떤 카메라 위치를 설정하였든 지도와 상호작용해 카메라를 조정할 수 있습니다 좋아요, 이제 화면의 내용을 앱이 제어하고 있습니다 사용자가 상호작용한 이후에도 검색 결과를 볼 수 있도록 automatic 카메라 위치를 사용했죠 보스턴과 노스엔드를 표시하는 데 region 카메라 위치를 사용했고요 다음으로 보스턴 코먼 공원 인근만 검색하는 대신에 가 볼 만한 곳을 찾아 지도를 옮긴 후 거기서 검색해 볼게요 카메라가 바뀔 때 해당 지역을 표시하는 법을 보여 드릴 겁니다 화면에 표시되는 지역을 추적하는 State를 추가하겠습니다 onMapCameraChange 수정자로 업데이트 콘텍스트에서 visibleRegion 정보를 가져와 State에 보관합니다 기본적으로 onMapCameraChange에 적용되는 클로저는 사용자가 지도와 상호작용을 마쳤을 때 호출됩니다 사용자가 상호작용하는 중에도 클로저를 호출하고 싶다면 주기 매개변수를 전달해 지속적인 업데이트를 요청하세요 콘텍스트는 여기서 사용한 region 프로퍼티뿐 아니라 표시되는 MKMapRect와 카메라 자체의 프로퍼티도 포함하고 있습니다 필요하다면 그것도 사용할 수 있죠 BeantownButtons를 업데이트해 사용자에게 표시되는 지역에서 검색을 수행하겠습니다 BeantownButtons에 visibleRegion을 추가할게요
이걸 검색 요청에서 사용해 봅시다 ContentView에서 visibleRegion을 BeantownButtons UI에 넘깁니다
북부 해안 지역의 해변을 검색해 볼게요 북부 해안 지역이 나왔네요 해변을 찾아봅시다 잘 작동하네요 로드아일랜드는 어떨까요?
좋아요, 로드아일랜드 해변도 검색할 수 있습니다 표시되는 화면이 바뀌었을 때 이를 알려 주는 onMapCameraChange로 구현한 기능이었습니다 이제 어떤 해변으로 갈지 더 쉽게 정할 수 있도록 해 봅시다 선택지가 많기는 하네요 우선 검색 결과를 선택할 수 있게 해 보죠 지금은 검색 결과 마커를 탭해도 아무 일도 일어나지 않아요 selection State가 없기 때문에 마커를 선택할 수 없죠
마커를 선택할 수 있게 하려면 selection 바인딩만 넣으면 됩니다
이제 검색 결과를 탭하면 어떻게 되는지 보죠
마커가 선택되었다고 알려 주는 애니메이션이 나옵니다 선택 형식으로 MKMapItem을 사용했기 때문에 지도 항목을 나타내는 모든 마커를 이제 선택할 수 있습니다 주차장 Annotaion은 지도 항목을 나타내지 않으므로 선택할 수 없습니다 마커와 주석의 형식이 다를 때에도 모두 선택할 수 있게 하려면 둘을 tag 하면 됩니다 Picker와 List 선택을 관리할 때와 동일한 방식으로 작동해요 selectedTag State는 여기서 Int입니다 모든 마커를 Int로 tag 했으니 바인딩에 따라 둘 다 선택할 수 있게 됩니다 tag로 선택 기능을 활성화할 때는 해시 가능한 형식도 selection State로 사용할 수 있죠 지금까지 MKMapItem 선택 바인딩을 지도에 추가했고 검색 결과 마커에 선택 기능을 활성화했습니다 이제 앱에서 선택한 검색 결과에 추가 정보가 표시되게 해 봅시다 해변을 미리 둘러볼 수 있게 LookAroundPreview를 추가하고 해변의 이름과 이동 시간도 표시하겠습니다 오늘 BeantownButtons View를 미리 작성했다고 말씀드렸죠 그때 ItemInfoView도 함께 작성했습니다 명칭, 예상되는 travelTime 그리고 LookAroundPreview를 표시하도록 만들었어요 LookAroundPreview로 선택한 해변의 모습을 볼 수 있죠 주변보기 이미지를 표시하는 기능이에요 MKLookAroundSceneRequest로 지도 항목의 Scene을 요청합니다 이미지가 화면에 표시될 때 Scene을 불러오게 되고 다른 검색 결과를 선택할 때마다 다시 불러오게 되죠 그리고 DateComponentsFormatter로 MKRoute의 예상 travelTime을 구성하는 프로퍼티가 있습니다 ContentView로 전환해 이 ItemInfoView를 추가할게요 그 전에 먼저 주차장에서 선택한 검색 결과까지 route 정보를 구할게요 route를 추적하는 State를 추가하고 MKDirections를 사용해 route를 구하는 기능을 추가합니다 완성이에요
onChange 수정자를 새로 추가해 선택한 대상이 바뀔 때 이 기능을 호출하도록 만듭시다
selectedResult가 있을 때 ItemInfoView가 표시될 거예요
하는 김에 검색 결과의 Marker 명칭도 숨겨서 지도 화면을 조금 더 단정하게 만듭시다 대신 ItemInfoView가 선택된 곳의 이름을 표시할 겁니다 좋아요, 이제 확인해 볼게요
이 근처에 놀이터도 있다고 하더라고요
괜찮은데요
이쪽에는 뭐가 있나 볼까요?
좋아요, 해변 바로 옆에 놀이터가 있네요 바쁜 하루가 되겠군요 보스턴 코먼 공원에서 약 30분 거리네요 적절할 것 같아요 정리하자면 LookAroundPreview를 추가해 선택한 마커의 주변보기 이미지를 표시했습니다 MKRoute로 예상 이동 시간도 표시했으니 저희가 해변을 정하는 데 큰 도움이 되겠어요 그럼 이동 시간을 표시할 route를 추가했으니 route를 온전히 활용해 보스턴 코먼 공원에서 선택한 검색 결과까지 이동 경로를 표시해 봅시다 MapPolyline 오버레이를 추가해 경로를 표시하고 다른 오버레이 콘텐츠도 몇 가지 소개해 드릴게요 route를 사용할 수 있으니 MapPolyline을 더하고 blue로 stroke 하겠습니다 지도에서 확인해 보죠
즐거운 여행이 될 것 같네요 MapPolyline과 MKRoute는 함께 사용하기 무척 편합니다 MapPolyline을 사용해 현재 위치 정보도 표시할 수 있죠 StrokeStyle을 사용하면 점선이나 그라디언트 같은 멋진 효과도 표현할 수 있습니다 지역을 하이라이트 하려면 MapPolygon이나 MapCircle을 사용해 보세요 여기서는 MapPolygon으로 두 공원을 마크했습니다 여기서는 MapCircle로 공원을 마크했죠 보시듯이 mapOverlayLevel이 각각 적용되어 있습니다 분홍색 원은 기본적인 aboveRoads level을 적용해 지도의 레이블이 원 위에 표시되도록 했죠 파란색 원은 aboveLabels를 적용했습니다 앱이 점점 완성되어 가네요 MapPolyline을 추가해 해변까지 이동 경로를 표시했고 몇 가지 다른 오버레이 형식도 소개해 드렸습니다 이제 현재 위치를 간편하게 알 수 있게 해 봅시다 보스턴에서 산책하다 보면 아마도 길을 잃어버릴 것 같아요 UserAnnotation을 추가해 현재 위치를 표시하고 MapUserLocationButton으로 현재 위치 버튼을 만들어 봅시다 그 밖의 몇 가지 mapControls를 파악하실 수 있을 거예요 저는 현재 위치를 찾을 때 일단 지도에서 파란 점을 찾아요 지도 콘텐츠에 UserAnnotation을 추가해서 제 위치를 지도에 표시해 보죠 전 어디 있을까요? 여기 있네요 이제까지 살펴봤던 놀이터와 해변과는 무척 먼 곳이죠
Apple Park를 찾느라 화면을 많이 조작해야 하네요 MapUserLocationButton을 쓰면 이 작업이 간편해집니다
이제 버튼만 탭하면 제 위치가 표시되죠 제가 이동하면 지도의 카메라도 따라옵니다 MapCompass와 MapScaleView도 추가했어요
기본 mapControls 설정은 지도를 회전하면 나침반을 띄우고 화면을 확대하거나 축소하면 축척을 표시합니다 이 앱도 그렇게 작동하도록 MapUserLocationButton과 함께 기본 mapControls 설정을 지정해 놓았습니다 전부 mapControls 수정자를 사용했기 때문에 지도가 기본 위치에서 자동으로 나침반과 축척을 표시할 거예요 macOS의 MapZoomStepper나 MapPitchSlider와 같은 전 플랫폼의 조작 버튼을 지원하죠 이런 조작 버튼의 위치를 직접 설정하고 싶다면 직접 UI를 구성해 나타낼 수 있습니다 mapControls는 View이므로 mapControls 수정자를 사용하지 말고 다른 View와 같은 방식으로 추가하면 됩니다 추가한 조작 버튼이 특정 시야에서 작동하게 하려면 mapScope 수정자를 사용해야 해요 세션이 거의 끝나갑니다 오늘 알아본 것을 요약해 보죠 SwiftUI용 MapKit은 앱에 지도를 결합해 주는 강력하고 편리한 API입니다 Marker와 Annotation 오버레이를 사용해 지도에 콘텐츠를 나타낼 수 있고 MapCamera와 mapControls로 지도를 필요에 따라 맞출 수 있죠 마지막으로 mapStyle과 주변보기로 공간감을 제공할 수 있습니다 SwiftUI용 MapKit의 기능은 이뿐만이 아닙니다 더 많은 사항을 살펴보려면 개발자 문서를 참고해 주세요 SwiftUI로 구성한 지도인 만큼 모든 플랫폼에서 잘 표시될 거예요 세션을 요약하며 알려드릴 사항이 있습니다 Apple Maps Server API가 확장되어 Autocomplete와 Directions를 이제 지원하고 있으니 사용법을 살펴보려면 작년 세션인 'Apple Maps Server API 알아보기'를 참고해 주세요 저희는 늘 여러분의 피드백을 기다리고 있습니다 '피드백 지원'을 사용해 여러분의 생각을 남겨 주세요 마지막으로 강조할 것이 있어요 올해 추가된 SwiftUI 기능을 꼭 살펴보셨으면 합니다 애니메이션 플랜을 사용하면 지도에 애니메이션을 넣기 좋아요 아래 세션에서 살펴보세요 마무리하죠 시청해 주셔서 감사합니다 해변에서 만나요 ♪ ♪
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.