// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 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() } 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!, keyPath: 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 { // have MapLibre fetch the signed URL return result as URL } // fall back to an unsigned URL return url } }