Amazon Location Service에서 iOSSDK용 MapLibre 네이티브 사용 - Amazon Location Service

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Amazon Location Service에서 iOSSDK용 MapLibre 네이티브 사용

MapLibre iOSSDK용 Native를 사용하여 클라이언트 측 맵을 iOS 애플리케이션에 임베드합니다.

iOSSDK용 MapLibre 네이티브는 Mapbox GL 네이티브 를 기반으로 하는 라이브러리이며 Amazon Location Service Maps 에서 제공하는 스타일 및 타일과 호환됩니다API. iOSSDK용 MapLibre Native를 통합하여 확장 가능하고 사용자 지정 가능한 벡터 맵과 대화형 맵 뷰를 iOS 애플리케이션에 포함할 수 있습니다.

이 자습서에서는 iOSSDK용 MapLibre 네이티브를 Amazon Location과 통합하는 방법을 설명합니다. 이 자습서의 샘플 애플리케이션은 의 Amazon Location Service 샘플 리포지토리의 일부로 사용할 수 있습니다GitHub.

애플리케이션 빌드: 초기화

애플리케이션을 초기화하려면:

  1. 템플릿에서 새 Xcode 프로젝트를 생성합니다.

  2. 인터페이스로 SwiftUI를 선택합니다.

  3. 수명 주기로 SwiftUI 애플리케이션을 선택합니다.

  4. 해당 언어로 Swift를 선택합니다.

Swift 패키지를 사용하여 종속성 추가 MapLibre

Xcode 프로젝트에 패키지 종속성을 추가하려면:

  1. 파일 > Swift 패키지 > 패키지 종속성 추가로 이동합니다.

  2. 리포지토리를 입력합니다URL. https://github.com/maplibre/maplibre-gl-native-distribution

    참고

    Swift 패키지에 대한 자세한 내용은 Apple.com에서 Adding Package Dependencies to Your App 항목을 참조하세요.

  3. 터미널에 를 설치합니다 CocoaPods.

    sudo gem install cocoapods
  4. 애플리케이션의 프로젝트 디렉터리로 이동하여 CocoaPods 패키지 관리자로 Podfile을 초기화합니다.

    pod init
  5. Podfile을 열어 AWSCore을 종속성으로 추가합니다.

    platform :ios, '12.0' target 'Amazon Location Service Demo' do use_frameworks! pod 'AWSCore' end
  6. 종속성 다운로드 및 설치:

    pod install --repo-update
  7. CocoaPods 생성한 Xcode 워크스페이스를 엽니다.

    xed .

애플리케이션 빌드: 구성

Info.plist에 다음 키와 값을 추가하여 애플리케이션을 구성합니다.

AWSRegion us-east-1
IdentityPoolId us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd
MapName ExampleMap

애플리케이션 빌드: ContentView 레이아웃

맵을 렌더링하려면 ContentView.swift을 편집합니다.

  • 맵을 렌더링하는 MapView를 추가합니다.

  • 속성을 표시하는 TextField를 추가합니다.

이렇게 하면 맵의 초기 중심점도 설정됩니다.

import SwiftUI struct ContentView: View { @State private var attribution = "" var body: some View { MapView(attribution: $attribution) .centerCoordinate(.init(latitude: 49.2819, longitude: -123.1187)) .zoomLevel(12) .edgesIgnoringSafeArea(.all) .overlay( TextField("", text: $attribution) .disabled(true) .font(.system(size: 12, weight: .light, design: .default)) .foregroundColor(.black) .background(Color.init(Color.RGBColorSpace.sRGB, white: 0.5, opacity: 0.5)) .cornerRadius(1), alignment: .bottomTrailing) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
참고

애플리케이션 또는 문서에서 사용하는 각 데이터 공급자에 대한 워드마크 또는 텍스트 속성을 제공해야 합니다. 속성 문자열은 sources.esri.attribution, sources.here.attribution, source.grabmaptiles.attribution 키의 스타일 설명자 응답에 포함됩니다. 데이터 공급자와 함께 Amazon Location 리소스를 사용할 때는 서비스 이용 약관을 반드시 읽어보세요.

애플리케이션 빌드: 변환 요청

다음 클래스 정의가 AWSSignatureV4Delegate.swift 포함된 라는 새 Swift 파일을 생성하여 AWS 요청을 가로채고 서명 버전 4를 사용하여 서명합니다. 이 클래스의 인스턴스는 지도 보기URLs에서 를 다시 작성할 책임도 있는 오프라인 스토리지 위임자로 할당됩니다.

import AWSCore import Mapbox class AWSSignatureV4Delegate : NSObject, MGLOfflineStorageDelegate { private let region: AWSRegionType private let identityPoolId: String private let credentialsProvider: AWSCredentialsProvider init(region: AWSRegionType, identityPoolId: String) { self.region = region self.identityPoolId = identityPoolId self.credentialsProvider = AWSCognitoCredentialsProvider(regionType: region, identityPoolId: identityPoolId) super.init() } class func doubleEncode(path: String) -> String? { return path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)? .addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) } func offlineStorage(_ storage: MGLOfflineStorage, urlForResourceOf kind: MGLResourceKind, with url: URL) -> URL { if url.host?.contains("amazonaws.com") != true { // not an AWS URL return url } // URL-encode spaces, etc. let keyPath = String(url.path.dropFirst()) guard let percentEncodedKeyPath = keyPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { print("Invalid characters in path '\(keyPath)'; unsafe to sign") return url } let endpoint = AWSEndpoint(region: region, serviceName: "geo", url: url) let requestHeaders: [String: String] = ["host": endpoint!.hostName] // sign the URL let task = AWSSignatureV4Signer .generateQueryStringForSignatureV4( withCredentialProvider: credentialsProvider, httpMethod: .GET, expireDuration: 60, endpoint: endpoint!, // workaround for https://github.com/aws-amplify/aws-sdk-ios/issues/3215 keyPath: AWSSignatureV4Delegate.doubleEncode(path: percentEncodedKeyPath), requestHeaders: requestHeaders, requestParameters: .none, signBody: true) task.waitUntilFinished() if let error = task.error as NSError? { print("Error occurred: \(error)") } if let result = task.result { var urlComponents = URLComponents(url: (result as URL), resolvingAgainstBaseURL: false)! // re-use the original path; workaround for https://github.com/aws-amplify/aws-sdk-ios/issues/3215 urlComponents.path = url.path // have Mapbox GL fetch the signed URL return (urlComponents.url)! } // fall back to an unsigned URL return url } }

애플리케이션 빌드: 맵 보기

맵 보기는 AWSSignatureV4Delegate 인스턴스를 초기화하고, 리소스를 가져오고 맵을 렌더링하는 기본 MGLMapView 구성을 담당합니다. 또한 스타일 설명자 소스에서 속성 문자열을 다시 ContentView로 전파되는 것도 처리합니다.

다음 MapView.swift 정의를 포함하는 struct라는 이름을 가진 새 Swift 파일을 생성합니다.

import SwiftUI import AWSCore import Mapbox struct MapView: UIViewRepresentable { @Binding var attribution: String private var mapView: MGLMapView private var signingDelegate: MGLOfflineStorageDelegate init(attribution: Binding<String>) { let regionName = Bundle.main.object(forInfoDictionaryKey: "AWSRegion") as! String let identityPoolId = Bundle.main.object(forInfoDictionaryKey: "IdentityPoolId") as! String let mapName = Bundle.main.object(forInfoDictionaryKey: "MapName") as! String let region = (regionName as NSString).aws_regionTypeValue() // MGLOfflineStorage doesn't take ownership, so this needs to be a member here signingDelegate = AWSSignatureV4Delegate(region: region, identityPoolId: identityPoolId) // register a delegate that will handle SigV4 signing MGLOfflineStorage.shared.delegate = signingDelegate mapView = MGLMapView( frame: .zero, styleURL: URL(string: "https://maps.geo.\(regionName).amazonaws.com/maps/v0/maps/\(mapName)/style-descriptor")) _attribution = attribution } func makeCoordinator() -> Coordinator { Coordinator($attribution) } class Coordinator: NSObject, MGLMapViewDelegate { var attribution: Binding<String> init(_ attribution: Binding<String>) { self.attribution = attribution } func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) { let source = style.sources.first as? MGLVectorTileSource let attribution = source?.attributionInfos.first self.attribution.wrappedValue = attribution?.title.string ?? "" } } // MARK: - UIViewRepresentable protocol func makeUIView(context: UIViewRepresentableContext<MapView>) -> MGLMapView { mapView.delegate = context.coordinator mapView.logoView.isHidden = true mapView.attributionButton.isHidden = true return mapView } func updateUIView(_ uiView: MGLMapView, context: UIViewRepresentableContext<MapView>) { } // MARK: - MGLMapView proxy func centerCoordinate(_ centerCoordinate: CLLocationCoordinate2D) -> MapView { mapView.centerCoordinate = centerCoordinate return self } func zoomLevel(_ zoomLevel: Double) -> MapView { mapView.zoomLevel = zoomLevel return self } }

이 애플리케이션을 실행하면 선택한 스타일로 전체 화면 맵이 표시됩니다. 이 샘플은 의 Amazon Location Service 샘플 리포지토리의 일부로 사용할 수 있습니다GitHub.