이번 노트에서는 URL Scheme을 사용하여 한국에서 대표적으로 많이 쓰이는 지도 앱들을 연동하는 방법에 대해 기술하려한다.
앱이 설치돼 있으면 앱을 실행 시켜 절정한 위치가 노출되도록 하며, 설치되어 있지 않다면 app store로 이동해 앱 설치를 유도한다.
각 URL Scheme에 접근하기 위해서는 앱에 알려줘야 한다. Project file/TARGETS/info
탭에 Queried URL Schemes
에 다음 세 항목을 추가해주면 앱이 해당 Scheme을 허용한다. 위의 설정을 하지 않으면 앱이 scheme을 인식하지 못해 동작하지 않는다.
func openTMap(latitude: Double, longitude: Double) {
let urlString = "tmap://route?rGoName=목적지명&rGoX=\(longitude)&rGoY=\(latitude)"
// 목적지명에 공백과 같은 url 작성 규칙에 중복되면 url query로 인식하여 인코딩 진행
guard let encodedStr = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }
guard let url = URL(string: encodeStr) else { return }
// 티맵 앱 스토어 설치 주소
guard let appStoreURL = URL(string: "items-apps://itunes.apple.com/app/id431589174") else { return }
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.open(appStoreURL)
}
}
func openKakaoMap(latitude: Double, longitude: Double) {
let urlString = "kakaomap://look?p=\(latitude),\(longitude)"
guard let encodedStr = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }
guard let url = URL(string: encodedStr) else { return }
guard let appStoreUrl = URL(string: "itms-apps://itunes.apple.com/app/id304608425") else { return }
let kakaomapAppURL = URL(string: "kakaomap://open")
if UIApplication.shared.canOpenURL(kakaomapAppURL!) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.open(appStoreURL)
}
}
func openNaverMap(latitude: Double, longitude: Dobule) {
// 네이버 맵은 URL Scheme을 사용하는 앱또는 웹페이지의 식별자를 필수로 보내게 되어있다.
var appName = "com.test.test"
let urlString = "nmap://place?lat=\(latitude)&lng=\(longitude)&name=목적지&appname=\(appName)"
guard let encodedStr = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }
guard let url = URL(string: encodedStr) else { return }
guard let appStoreURL = URL(string: "itms-apps://itunes.apple.com/app/id311867728?mt=8") else { return }
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.open(appStoreURL)
}
}
나는 View를 통해 ViewController로 선택된 맵을 Delegate로 받는 방법을 사용했다. 개발자 마다 각자의 스타일이 있기에 더 나은 방법으로 선택된 맵을 받아오면 된다. 이번 노트에서는 Delegate 관련 로직은 생략한다.
CoreLocation API를 사용하여 주소를 위경도로 변환 하여 사용한다.
import CoreLocation
// SelectedMap은 tmap, kakaomap, navermap으로 enum 정의했다.
func selectedMap(view: UIView, didSelectedMap: SelectedMap) {
// 롯데월드 타워 주소
let address = "서울특별시 송파구 올림픽로 300"
Task {
let geocoder = CLGeocoder()
let placemarks = try? await geocoder.geocodeAddressString(address)
if let location = placemarks?.first?.location {
let latitude = location.coordinate.latitude
let longitude = location.coordinate.longitude
switch didSelectedMap {
case .tmap:
self.openTMap(latitude: latitude, longitude: longitude)
case .kakaomap:
self.openKakaoMap(latitude: latitude, longitude: longitude)
case .navermap:
self.openNaverMap(latitude: latitude, longitude: longitude)
}
}
}
}