티스토리 뷰
안녕하세요 Diana 입니다.
오늘은 SwiftUI를 통해 KakaoMapsSDK v.2를 사용해본 경험을 기록해보고자 합니다.
생각보다 UIKit + KakaoMapsSDK v.2 또는 SwiftUI + KakaoMapsSDK v.1 조합의 글은 많이 보이는데 SwiftUI + KakaoMapsSDK v.2는 안보이더라구요.
버전 2가 나온지 얼마 안되기도 했구요!
이 글이 어제의 저처럼 헤매고 있을 누군가에게 도움이 되었으면 좋겠네요!
그럼 시작하겠습니다~
✅ 프로젝트 생성 및 설정
우선 KakaoMapsSDK를 사용할 프로젝트를 생성해줍니다.
이름은 DianaMap_Demo 로 하였어요.
처음 프로젝트를 생성하면 위와 같이 파일이 생성됩니다.
파일 생성 이후 KakaoMapsSDK를 사용하기 위해서는 Dependency 설정을 해줘야겠죠?
전 Dependency 설정을 위해 SPM을 사용하였습니다.
File -> Add Package Dependencies를 선택해줍니다.
오른쪽 위 검색창에 KakaomapSDK 깃허브 주소를 넣어줍니다.
https://github.com/kakao-mapsSDK/KakaoMapsSDK-SPM.git
그리고 Add Package를 해줍니다.
그럼 프로젝트에 Package Dependencies가 추가된 것을 확인할 수 있습니다.
✅ 프로젝트 등록 및 KEY 생성
프로젝트를 생성했으면 이제 Kakao Developer에 해당 프로젝트를 등록해주고 AppKey를 받아와야 KakaoMapsSDK를 사용할 수 있는데요.
이를 위해서 우선 Kakao Developer에 프로젝트를 등록해줍시다.
Kakao Developer 사이트에 들어가 "내 애플리케이션"에 들어가면 아래와 같이 프로젝트를 추가할 수 있는 창을 확인할 수 있습니다.
여기서 애플리케이션 추가하기를 눌러 앱 이름, 회사 명을 넣은 뒤 생성을 완료해줍니다.
여기서의 앱 이름과 회사 명은 크게 중요하지 않기 때문에 본인이 알아볼 수 있도록 생성해줍니다.
생성 후 해당 애플리케이션을 누르면 왼쪽에 메뉴가 뜨는데 여기서 앱 키 를 선택해줍니다.
전 iOS 앱이다보니 네이티브 앱 키를 사용하였습니다. 설명을 보니 Admin키를 사용해도 되는 것 같네요.
우선 이 앱 키를 기억해놓습니다.
이번에는 왼쪽 메뉴에서 플랫폼을 선택해줍니다.
이전 버전에서는 애플리케이션 추가할 때 번들아이디를 넣도록 되어있던데 이번 버전에서는 이 플랫폼으로 분리되었더라구요.
이걸 안넣으면 권한 요청이 거절 당합니다. 어떤 앱이 요청을 넣는지 모르니 당연한거겠죠? ㅎㅎ..
패키지명에 내 애플리케이션의 번들아이디을 넣어준 뒤 저장을 눌러줍니다.
이렇게 KakaoMapsSDK 사용을 위한 웹에서의 설정은 마쳤습니다.
✅ KakaoMapsSDK 작동 원리
코드를 확인해보기 전에 KakaoMapsSDK 의 동작원리를 알아봅시다.
공식문서에 따르면 KakaoMapsSDK는 엔진부와 앱 인터페이스 부분으로 나뉜다고 합니다.
- KMViewContainer: 엔진이 내장되어 있으며 지도가 그려지는 뷰를 제공합니다. 각각의 KMViewController는 ViewBase 영역을 제공하며 서브 클래스로 제공되는 KakaoMap을 통해 지도의 종류를 선택할 수 있습니다.(지도, 스카이 뷰 및 3D 스카이뷰 등)
- KMController: 엔진-앱 인터페이스 연결, 인증 절차 및 엔진 상태 관리 담당합니다. 엔진의 초기화 및 Start, Stop, 그리고 렌더링 상태를 컨트롤 할 수 있습니다.
즉 KakaoMapsSDK을 사용하기 위해 필요한 클래스는 KMViewContainer와 KMController가 되겠네요!
혹시라도 뷰를 여러개 생성하고 싶은 경우는 KMViewContainer을 여러개 생성한 뒤 여러개의 KMViewContainer 들이 각각의 ViewBase 영역을 담당하도록 해야 한다고 합니다.
공식문서를 보면 KakaoMapsSDK의 Life Cycle이 친절하게 나와 있습니다.
https://apis.map.kakao.com/ios_v2/docs/getting-started/basics/01_view/
이 내용을 바탕으로 실제 코드로 들어가봅시다.
✅ KakaoMapsSDK 사용을 위한 코드
이 부분부터는 이제 공식문서를 따라가면 됩니다.
https://apis.map.kakao.com/ios_v2/
KakaoMapsSDK를 사용하기 위해서 우리는 앞서 얻어온 Key를 등록해줘야 합니다.
UIKit이라면 AppDelegate에서 등록하면 되겠지만 우리는 SwiftUI를 사용할 것이기 때문에 App.swift파일에서 설정을 해줍니다.(DianaMap_DemoApp.swift)
import SwiftUI
import KakaoMapsSDK //SDK 사용을 위해 import
@main
struct DianaMap_DemoApp: App {
init() {
SDKInitializer.InitSDK(appKey: "카카오 앱 키")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
이렇게 앱 키를 등록해 줬으면 공식문서의 요청대로 KakaoMapView.swift를 생성해줍니다.
이후 아래와 같이 코드를 작성해줍니다.
import SwiftUI
import KakaoMapsSDK
struct KakaoMapView: UIViewRepresentable {
@Binding var draw: Bool
func makeUIView(context: Self.Context) -> KMViewContainer {
let view: KMViewContainer = KMViewContainer(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
context.coordinator.createController(view)
return view
}
func updateUIView(_ uiView: KMViewContainer, context: Self.Context) {
if draw {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if context.coordinator.controller?.isEnginePrepared == false {
context.coordinator.controller?.prepareEngine()
}
if context.coordinator.controller?.isEngineActive == false {
context.coordinator.controller?.activateEngine()
}
}
}
else {
context.coordinator.controller?.pauseEngine()
context.coordinator.controller?.resetEngine()
}
}
func makeCoordinator() -> KakaoMapCoordinator {
return KakaoMapCoordinator()
}
class KakaoMapCoordinator: NSObject, MapControllerDelegate {
override init() {
first = true
auth = false
super.init()
}
func createController(_ view: KMViewContainer) {
container = view
controller = KMController(viewContainer: view)
controller?.delegate = self
}
func addViews() {
let defaultPosition: MapPoint = MapPoint(longitude: 126.978365, latitude: 37.566691)
let mapviewInfo: MapviewInfo = MapviewInfo(viewName: "mapview", viewInfoName: "map", defaultPosition: defaultPosition)
controller?.addView(mapviewInfo)
}
func addViewSucceeded(_ viewName: String, viewInfoName: String) {
print("Add view succeed!!")
let view = controller?.getView("mapview")
view?.viewRect = container!.bounds
}
func containerDidResized(_ size: CGSize) {
let mapView: KakaoMap? = controller?.getView("mapview") as? KakaoMap
mapView?.viewRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size)
if first {
let cameraUpdate: CameraUpdate = CameraUpdate.make(target: MapPoint(longitude: 126.978365, latitude: 37.566691), mapView: mapView!)
mapView?.moveCamera(cameraUpdate)
first = false
}
}
func authenticationSucceeded() {
auth = true
}
var controller: KMController?
var container: KMViewContainer?
var first: Bool
var auth: Bool
}
}
위 코드는 KakaoMapsSDK에서 제공해준 Sample App을 참고하였습니다.
https://apis.map.kakao.com/ios_v2/sample/
위와 같이 KakaoMapsView를 생성해 주었다면 이제 마지막으로 사용만 하면 되겠죠?
사용하는 쪽 코드는 아래와 같습니다.
import SwiftUI
import KakaoMapsSDK
public struct ContentView: View {
@State var draw: Bool = false
public var body: some View {
KakaoMapView(draw: $draw).onAppear(perform: {
self.draw = true
}).onDisappear(perform: {
self.draw = false
}).frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
이렇게 구현은 모두 끝이 났습니다.
결과를 보니 정상적으로 잘 뜨네요!
크게 어려움은 없었지만 참고 자료가 공식문서와 샘플앱 밖에 없어서 살짝 헤매었네요.
그래도 잘 돌아가니 뿌듯합니다!
이렇게 SwiftUI와 KakaoMapsSDK v.2를 사용한 KakaoMap 띄우기 기록을 마치겠습니다!
'SwiftUI' 카테고리의 다른 글
SwiftUI - Reusable List View 구현하기 (0) | 2024.10.14 |
---|---|
SwiftUI - ViewBuilder란? (1) | 2024.10.10 |
SwiftUI - 유저 친화적인 TextField 구현하기(feat. @FocuseState) (1) | 2024.10.07 |
SwiftUI - TabView 사용하기 (0) | 2024.10.04 |
SwiftUI - @State와 @StateObject 비교 (0) | 2024.06.15 |
- Total
- Today
- Yesterday
- private(set)
- swift
- 알고리즘
- capsulation
- swiftpackage
- 스위프트
- asymptoticnotation
- opaque
- 개발자코테
- threadprogramming
- ios
- coredata
- 코어데이터
- reusablelist
- 빅세타표기법
- ViewBuilder
- swiftcoredata
- BoxedType
- opaquetype
- boxedprotocol
- 팁킷
- kakaomapssdk
- boxedprotocoltype
- Concurrency
- tuist v4
- Algorithm
- tipview
- SwiftUI
- Tuist
- tipkit
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |