Creazione di un'app per iOS - Servizio di posizione Amazon

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Creazione di un'app per iOS

In questa sezione, creerai un'applicazione iOS con la possibilità di cercare in una posizione e di tracciare in primo piano. Innanzitutto, creerai le tue risorse Amazon Location e un'identità Amazon Cognito per la tua applicazione.

Creazione di risorse Amazon Location per la tua app

Se non li possiedi già, devi creare le risorse Amazon Location che l'applicazione utilizzerà. Creerai una risorsa cartografica per visualizzare le mappe nell'applicazione, un indice dei luoghi per cercare posizioni sulla mappa e un tracker per tracciare un oggetto sulla mappa.

Per aggiungere risorse di localizzazione all'applicazione
  1. Scegli lo stile di mappa che desideri utilizzare.

    1. Nella console Amazon Location, nella pagina Mappe, scegli Crea mappa per visualizzare in anteprima gli stili delle mappe.

    2. Aggiungi un nome e una descrizione per la nuova risorsa cartografica. Prendi nota del nome che usi per la risorsa della mappa. Ne avrai bisogno quando creerai il tuo file di script più avanti nel tutorial.

    3. Scegli una mappa.

      Nota

      La scelta di uno stile di mappa consente anche di scegliere il fornitore di dati cartografici da utilizzare. Se la tua applicazione monitora o indirizza le risorse che utilizzi nella tua attività, come veicoli per le consegne o dipendenti, puoi utilizzare HERE solo come fornitore di geolocalizzazione. Per ulteriori informazioni, consulta la sezione 82 dei termini di servizio.AWS

    4. Accetta i Termini e condizioni di Amazon Location, quindi scegli Crea mappa. Puoi interagire con la mappa che hai scelto: ingrandisci, rimpicciolisci o fai una panoramica in qualsiasi direzione.

    5. Prendi nota dell'Amazon Resource Name (ARN) visualizzato per la tua nuova risorsa cartografica. Lo utilizzerai per creare l'autenticazione corretta più avanti in questo tutorial.

  2. Scegli l'indice dei luoghi che desideri utilizzare.

    1. Nella console Amazon Location, nella pagina degli indici dei luoghi, scegli Crea indice dei luoghi.

    2. Aggiungi un nome e una descrizione per la nuova risorsa relativa all'indice dei luoghi. Prendi nota del nome che usi per la risorsa dell'indice dei luoghi. Ne avrai bisogno quando creerai il tuo file di script più avanti nel tutorial.

    3. Scegli un fornitore di dati.

      Nota

      Nella maggior parte dei casi, scegli il fornitore di dati che corrisponde al fornitore di mappe che hai già scelto. Questo aiuta a garantire che le ricerche corrispondano alle mappe.

      Se la tua applicazione monitora o indirizza le risorse che utilizzi nella tua attività, come veicoli per le consegne o dipendenti, puoi utilizzare HERE solo come provider di geolocalizzazione. Per ulteriori informazioni, consulta la sezione 82 dei termini di servizio.AWS

    4. Scegli l'opzione di archiviazione dei dati. Per questo tutorial, i risultati non vengono memorizzati, quindi puoi scegliere No, solo monouso.

    5. Accetta i Termini e condizioni di Amazon Location, quindi scegli Crea indice dei luoghi.

    6. Prendi nota dell'ARN mostrato per la tua nuova risorsa dell'indice dei luoghi. Lo userai per creare l'autenticazione corretta nella prossima sezione di questo tutorial.

  3. Per creare un tracker utilizzando la console Amazon Location.

    1. Apri la console Amazon Location Service.

    2. Nel riquadro di navigazione a sinistra, scegli Trackers.

    3. Scegli Crea tracker.

    4. Compila tutti i campi obbligatori.

    5. In Filtraggio di posizione, ti consigliamo di utilizzare l'impostazione predefinita:. TimeBased

    6. Scegli Crea tracker per terminare.

Configurazione dell'autenticazione per l'applicazione

L'applicazione creata in questo tutorial ha un utilizzo anonimo, il che significa che gli utenti non devono accedere AWS per utilizzare l'applicazione. Tuttavia, le API di Amazon Location Service richiedono l'autenticazione per essere utilizzate. Utilizzerai Amazon Cognito per fornire l'autenticazione e l'autorizzazione agli utenti anonimi. Questo tutorial utilizzerà Amazon Cognito per autenticare la tua applicazione.

Nota

Per ulteriori informazioni sull'utilizzo di Amazon Cognito con Amazon Location Service, consulta. Concessione dell'accesso ad Amazon Location Service

I seguenti tutorial mostrano come configurare l'autenticazione per la mappa, l'indice dei luoghi e il tracker in cui hai creato, oltre a configurare le autorizzazioni per Amazon Location.

Crea una policy IAM per il tracciamento
  1. Accedi alla console IAM all'indirizzo https://console.aws.amazon.com/iam/ come utente con autorizzazioni da amministratore.

  2. Nel pannello di navigazione, seleziona Policies (Policy).

  3. Nel riquadro del contenuto seleziona Create policy (Crea policy).

  4. Scegli l'opzione JSON, quindi copia e incolla questa policy JSON nella casella di testo JSON.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "geo:GetMapTile", "geo:GetMapStyleDescriptor", "geo:GetMapSprites", "geo:GetMapGlyphs", "geo:SearchPlaceIndexForPosition", "geo:GetDevicePositionHistory", "geo:BatchUpdateDevicePosition" ], "Resource": [ "arn:aws:geo:{Region}:{Account}:map/{MapName}", "arn:aws:geo:{Region}:{Account}:place-index/{IndexName}", "arn:aws:geo:{Region}:{Account}:tracker/{TrackerName}" ] } ] }

    Questo è un esempio di policy per il tracciamento. Per utilizzare l'esempio per la tua politica, sostituisci i TrackerNamesegnaposti Region AccountIndexName,, MapName e.

    Nota

    Sebbene i pool di identità non autenticati siano destinati all'esposizione su siti Internet non protetti, tieni presente che verranno scambiati con credenziali standard a tempo limitato. AWS

    È importante definire in modo appropriato i ruoli IAM associati ai pool di identità non autenticati. Per ulteriori informazioni sull'utilizzo e sulla corretta definizione delle politiche in Amazon Cognito con Amazon Location Service, consulta Concessione dell'accesso ad Amazon Location Service.

  5. Nella pagina Rivedi e crea, fornisci un nome per il campo del nome della politica. Controlla le autorizzazioni concesse dalla tua politica, quindi scegli Crea politica per salvare il lavoro.

La nuova policy appare nell'elenco delle policy gestite ed è pronta a collegare.

Imposta l'autenticazione per il tracciamento
  1. Configura l'autenticazione per la tua applicazione cartografica nella console Amazon Cognito.

  2. Apri la pagina dei pool di identità.

    Nota

    Il pool che crei deve trovarsi nello stesso AWS account e AWS nella stessa regione delle risorse di Amazon Location Service che hai creato nella sezione precedente.

  3. Scegli Crea pool di identità.

  4. A partire dal passaggio Configure identity pool trust. Per l'autenticazione dell'accesso utente, seleziona Accesso ospite e premi Avanti.

  5. Nella pagina Configura le autorizzazioni seleziona Usa un ruolo IAM esistente e inserisci il nome del ruolo IAM che hai creato nel passaggio precedente. Quando sei pronto, premi Avanti per passare alla fase successiva.

  6. Nella pagina Configura proprietà, fornisci un nome per il tuo pool di identità. Quindi premi Avanti.

  7. Nella pagina Rivedi e crea, esamina tutte le informazioni presenti, quindi premi Crea pool di identità.

  8. Apri la pagina dei pool di identità e seleziona il pool di identità che hai appena creato. Quindi copia o annota nello script del browser IdentityPoolId quello che utilizzerai in seguito.

Creazione dell'applicazione iOS di base

In questo tutorial, creerai un'applicazione iOS che incorpora una mappa e consente all'utente di trovare cosa si trova in una posizione sulla mappa.

Per prima cosa, creiamo un'applicazione Swift usando la procedura guidata di progetto di Xcode.

Per creare un'applicazione vuota (Xcode)
  1. Apri Xcode e dal menu scegli File, Nuovo, Nuovo progetto.

  2. Dalla scheda iOS, seleziona App, quindi scegli Avanti.

  3. Fornisci un nome di prodotto, un identificatore dell'organizzazione e SwiftUI inseriscilo nel campo Interfaccia. Scegli Avanti per finalizzare la selezione.

  4. Seleziona una posizione in cui salvare il progetto e premi il pulsante di creazione per creare l'applicazione vuota.

Dopo aver creato l'applicazione di base, dovrai installare i pacchetti richiesti per l'app di esempio.

Installazione delle dipendenze richieste
  1. In Xcode, fai clic con il pulsante destro del mouse sul progetto e scegli Aggiungi pacchetti... . Si aprirà la finestra Pacchetti, dove potrai aggiungere pacchetti al tuo progetto.

  2. Nella finestra Pacchetti, aggiungi i seguenti pacchetti:

Impostazione del codice iniziale

Abilita le autorizzazioni di localizzazione nella tua app
  1. Apri il tuo progetto Xcode.

  2. Individua il Info.plist file del progetto.

  3. Aggiungi le chiavi necessarie per le autorizzazioni di localizzazione in base ai requisiti dell'app. Ecco le chiavi:

    • NSLocationWhenInUseUsageDescription: Descrizione del motivo per cui l'app necessita dell'accesso alla posizione quando è in uso.

    • NSLocationAlwaysAndWhenInUseUsageDescription: Descrizione del motivo per cui l'app necessita di un accesso continuo alla posizione.

Ora dovrai configurare i valori delle risorse nella tua app. Aggiungi un nuovo file denominato Config.xcconfig e compila i valori che avevi creato in precedenza nella console Amazon.

REGION = INDEX_NAME = MAP_NAME = IDENTITY_POOL_ID = TRACKER_NAME =
  1. Dalla sezione del navigatore sul lato sinistro, seleziona il progetto.

  2. Nella sezione obiettivi, seleziona la tua app e fai clic sulla scheda delle informazioni.

  3. Aggiungi proprietà informative con valori come i seguenti:

  4. Aggiungi il Config.swift file con i contenuti seguenti, che leggerà i valori di configurazione dal file di informazioni del pacchetto.

    import Foundation enum Config { static let region = Bundle.main.object(forInfoDictionaryKey: "Region") as! String static let mapName = Bundle.main.object(forInfoDictionaryKey: "MapName") as! String static let indexName = Bundle.main.object(forInfoDictionaryKey: "IndexName") as! String static let identityPoolId = Bundle.main.object(forInfoDictionaryKey: "IdentityPoolId") as! String static let trackerName = Bundle.main.object(forInfoDictionaryKey: "TrackerName") as! String }
  5. Crea una nuova cartella con il nome ViewModel e aggiungi un TrackingViewModel.swift file al suo interno.

    import SwiftUI import AmazonLocationiOSAuthSDK import MapLibre final class TrackingViewModel : ObservableObject { @Published var trackingButtonText = NSLocalizedString("StartTrackingLabel", comment: "") @Published var trackingButtonColor = Color.blue @Published var trackingButtonIcon = "play.circle" @Published var region : String @Published var mapName : String @Published var indexName : String @Published var identityPoolId : String @Published var trackerName : String @Published var showAlert = false @Published var alertTitle = "" @Published var alertMessage = "" @Published var centerLabel = "" var clientIntialised: Bool var client: LocationTracker! var authHelper: AuthHelper var credentialsProvider: LocationCredentialsProvider? var mlnMapView: MLNMapView? var mapViewDelegate: MapViewDelegate? var lastGetTrackingTime: Date? var trackingActive: Bool init(region: String, mapName: String, indexName: String, identityPoolId: String, trackerName: String) { self.region = region self.mapName = mapName self.indexName = indexName self.identityPoolId = identityPoolId self.trackerName = trackerName self.authHelper = AuthHelper() self.trackingActive = false self.clientIntialised = false } func authWithCognito(identityPoolId: String?) { guard let identityPoolId = identityPoolId?.trimmingCharacters(in: .whitespacesAndNewlines) else { alertTitle = NSLocalizedString("Error", comment: "") alertMessage = NSLocalizedString("NotAllFieldsAreConfigured", comment: "") showAlert = true return } credentialsProvider = authHelper.authenticateWithCognitoUserPool(identityPoolId: identityPoolId) initializeClient() } func initializeClient() { client = LocationTracker(provider: credentialsProvider!, trackerName: trackerName) clientIntialised = true } }

Aggiungere una mappa interattiva all'applicazione

Ora aggiungerai il controllo della mappa alla tua applicazione. Questo tutorial utilizza MapLibre l' AWS API per gestire la visualizzazione della mappa nell'applicazione. Il controllo della mappa stesso fa parte della libreria MapLibre GL Native iOS.

  1. Aggiungi MapView.swift il file nella cartella Views con il seguente codice:

    import SwiftUI import MapLibre struct MapView: UIViewRepresentable { var onMapViewAvailable: ((MLNMapView) -> Void)? var mlnMapView: MLNMapView? var trackingViewModel: TrackingViewModel func makeCoordinator() -> MapView.Coordinator { return Coordinator(self, trackingViewModel: trackingViewModel) } func makeUIView(context: Context) -> MLNMapView { let styleURL = URL(string: "https://maps.geo.\(trackingViewModel.region).amazonaws.com/maps/v0/maps/\(trackingViewModel.mapName)/style-descriptor") let mapView = MLNMapView(frame: .zero, styleURL: styleURL) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.setZoomLevel(15, animated: true) mapView.showsUserLocation = true mapView.userTrackingMode = .follow context.coordinator.mlnMapView = mapView mapView.delegate = context.coordinator mapView.logoView.isHidden = true context.coordinator.addCenterMarker() onMapViewAvailable?(mapView) trackingViewModel.mlnMapView = mapView return mapView } func updateUIView(_ uiView: MLNMapView, context: Context) { } class Coordinator: NSObject, MLNMapViewDelegate, MapViewDelegate { var control: MapView var mlnMapView: MLNMapView? var trackingViewModel: TrackingViewModel var centerMarker: MLNPointAnnotation? public init(_ control: MapView, trackingViewModel: TrackingViewModel) { self.control = control self.trackingViewModel = trackingViewModel super.init() self.trackingViewModel.mapViewDelegate = self } func mapViewDidFinishRenderingMap(_ mapView: MLNMapView, fullyRendered: Bool) { if(fullyRendered) { mapView.accessibilityIdentifier = "MapView" mapView.isAccessibilityElement = false } } func addCenterMarker() { guard let mlnMapView = mlnMapView else { return } let centerCoordinate = mlnMapView.centerCoordinate let marker = MLNPointAnnotation() marker.coordinate = centerCoordinate marker.accessibilityLabel = "CenterMarker" mlnMapView.addAnnotation(marker) centerMarker = marker trackingViewModel.reverseGeocodeCenter(centerCoordinate: centerCoordinate, marker: marker) } func mapView(_ mapView: MLNMapView, regionDidChangeAnimated animated: Bool) { if let marker = centerMarker { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { mapView.deselectAnnotation(marker, animated: false) marker.coordinate = mapView.centerCoordinate let centerCoordinate = mapView.centerCoordinate self.trackingViewModel.reverseGeocodeCenter(centerCoordinate: centerCoordinate, marker: marker) } } } } }
  2. Aggiungi AWSSignatureV4Delegate il file nella ViewModelcartella. Questo file viene utilizzato per firmare con tutte le richieste MapView http per il rendering della mappa:

    import MapLibre import AmazonLocationiOSAuthSDK class AWSSignatureV4Delegate : NSObject, MLNOfflineStorageDelegate { private let awsSigner: AWSSigner init(credentialsProvider: LocationCredentialsProvider) { self.awsSigner = DENY LIST ERROR , serviceName: "geo") super.init() } func offlineStorage(_ storage: MLNOfflineStorage, urlForResourceOf kind: MLNResourceKind, with url: URL) -> URL { if url.host?.contains("amazonaws.com") != true { return url } let signedURL = awsSigner.signURL(url: url, expires: .hours(1)) return signedURL } }
  3. Aggiungi UserLocationView.swift il file nella cartella Views. Questo aggiunge un pulsante che centra la mappa sulla posizione dell'utente

    import SwiftUI struct UserLocationView: View { @ObservedObject var trackingViewModel: TrackingViewModel var body: some View { Button(action: { trackingViewModel.locateMe() }) { Image(systemName: "scope") .resizable() .frame(width: 24, height: 24) .padding(5) .background(Color.white) .foregroundColor(.blue) .clipShape(RoundedRectangle(cornerRadius: 8)) .shadow(color: Color.black.opacity(0.3), radius: 3, x: 0, y: 2) } .accessibility(identifier: "LocateMeButton") .padding(.trailing, 10) .padding(.bottom, 10) .frame(maxWidth: .infinity, alignment: .trailing) } }
  4. Aggiungi il TrackingView.swift file con il seguente codice:

    import SwiftUI struct TrackingView: View { @ObservedObject var trackingViewModel: TrackingViewModel var body: some View { ZStack(alignment: .bottom) { MapView(trackingViewModel: trackingViewModel) VStack { UserLocationView(trackingViewModel: trackingViewModel) } } .onAppear() { if !trackingViewModel.identityPoolId.isEmpty { trackingViewModel.authWithCognito(identityPoolId: trackingViewModel.identityPoolId) } } } }

Ora puoi creare l'applicazione. Per eseguirla, potresti dover configurare un dispositivo per emularla in Xcode o utilizzare l'app sul tuo dispositivo. Usa questa app per vedere come si comporta il controllo della mappa. Puoi effettuare una panoramica trascinandola sulla mappa e pizzicandola per ingrandirla. Da soli, puoi modificare il funzionamento del controllo della mappa per personalizzarlo in base alle esigenze della tua applicazione.

Ora aggiungerai la ricerca con geocodifica inversa all'applicazione, in cui troverai gli elementi in una posizione. Per semplificare l'uso di un'app iOS, cercheremo al centro dello schermo. Per trovare una nuova posizione, sposta la mappa nel punto in cui desideri effettuare la ricerca. Posizioneremo un indicatore al centro della mappa per mostrare dove stiamo cercando.

  1. Aggiungi il seguente codice nel file `TrackingViewModel.swift` che è correlato alla ricerca con geocodifica inversa

    func reverseGeocodeCenter(centerCoordinate: CLLocationCoordinate2D, marker: MLNPointAnnotation) { let position = [NSNumber(value: centerCoordinate.longitude), NSNumber(value: centerCoordinate.latitude)] searchPositionAPI(position: position, marker: marker) } func searchPositionAPI(position: [Double], marker: MLNPointAnnotation) { if let amazonClient = authHelper.getLocationClient() { Task { let searchRequest = SearchPlaceIndexForPositionInput(indexName: indexName, language: "en" , maxResults: 10, position: position) let searchResponse = try? await amazonClient.searchPosition(indexName: indexName, input: searchRequest) DispatchQueue.main.async { self.centerLabel = searchResponse?.results?.first?.place?.label ?? "" self.mlnMapView?.selectAnnotation(marker, animated: true, completionHandler: {}) } } } }
  2. Aggiorna TrackingView.swift il file con il seguente codice che mostrerà l'indirizzo della posizione centrata di mapview

    import SwiftUI struct TrackingView: View { @ObservedObject var trackingViewModel: TrackingViewModel var body: some View { ZStack(alignment: .bottom) { if trackingViewModel.mapSigningIntialised { MapView(trackingViewModel: trackingViewModel) VStack { UserLocationView(trackingViewModel: trackingViewModel) CenterAddressView(trackingViewModel: trackingViewModel) } } else { Text("Loading...") } } .onAppear() { if !trackingViewModel.identityPoolId.isEmpty { Task { do { try await trackingViewModel.authWithCognito(identityPoolId: trackingViewModel.identityPoolId) } catch { print(error) } } } } } }

Aggiungere il tracciamento alla tua applicazione

L'ultimo passaggio per l'applicazione consiste nell'aggiungere funzionalità di tracciamento all'app. In questo caso, aggiungerai start tracking, stop tracking, recupererà e mostrerà i tracker point sulla tua app.

  1. Aggiungi il TrackingBottomView.swift file nel tuo progetto. Che ha un pulsante che avvia e interrompe il tracciamento delle posizioni degli utenti e mostra i punti di tracciamento sulla mappa.

    import SwiftUI struct TrackingBottomView: View { @ObservedObject var trackingViewModel: TrackingViewModel var body: some View { Button(action: { Task { if(trackingViewModel.trackingButtonText == NSLocalizedString("StartTrackingLabel", comment: "")) { trackingViewModel.startTracking() } else { trackingViewModel.stopTracking() } } }) { HStack { Spacer() Text("Tracking") .foregroundColor(trackingViewModel.trackingButtonColor) .background(.white) .cornerRadius(15.0) Image(systemName: trackingViewModel.trackingButtonIcon) .resizable() .frame(width: 24, height: 24) .padding(5) .background(.white) .foregroundColor(trackingViewModel.trackingButtonColor) } } .accessibility(identifier: "TrackingButton") .background(.white) .clipShape(RoundedRectangle(cornerRadius: 8)) .padding(.trailing, 10) .padding(.bottom, 40) .frame(width: 130, alignment: .trailing) .shadow(color: Color.black.opacity(0.3), radius: 3, x: 0, y: 2) } }
  2. Aggiorna TrackingView.swift il file con il seguente codice

    import SwiftUI struct TrackingView: View { @ObservedObject var trackingViewModel: TrackingViewModel var body: some View { ZStack(alignment: .bottom) { if trackingViewModel.mapSigningIntialised { MapView(trackingViewModel: trackingViewModel) VStack { UserLocationView(trackingViewModel: trackingViewModel) CenterAddressView(trackingViewModel: trackingViewModel) TrackingBottomView(trackingViewModel: trackingViewModel) } } else { Text("Loading...") } } .onAppear() { if !trackingViewModel.identityPoolId.isEmpty { Task { do { try await trackingViewModel.authWithCognito(identityPoolId: trackingViewModel.identityPoolId) } catch { print(error) } } } } } }
  3. Aggiungi il seguente codice nel TrackingViewModel.swift file. Queste funzioni sono responsabili dell'avvio e dell'arresto del tracciamento. Mostrerà anche un avviso di errore se l'autorizzazione alla localizzazione dell'utente viene negata.

  4. Per implementare il tracciamento in primo piano, copia e incolla il seguente esempio di codice:

    func showLocationDeniedRationale() { alertTitle = NSLocalizedString("locationManagerAlertTitle", comment: "") alertMessage = NSLocalizedString("locationManagerAlertText", comment: "") showAlert = true } // Required in info.plist: Privacy - Location When In Use Usage Description func startTracking() { do { print("Tracking Started...") if(client == nil) { initializeClient() } try client.startTracking() DispatchQueue.main.async { [self] in self.trackingButtonText = NSLocalizedString("StopTrackingLabel", comment: "") self.trackingButtonColor = .red self.trackingButtonIcon = "pause.circle" trackingActive = true } } catch TrackingLocationError.permissionDenied { showLocationDeniedRationale() } catch { print("error in tracking") } } func stopTracking() { print("Tracking Stopped...") client.stopTracking() trackingButtonText = NSLocalizedString("StartTrackingLabel", comment: "") trackingButtonColor = .blue trackingButtonIcon = "play.circle" trackingActive = false }
    Nota

    startTrackingChiederà l'autorizzazione alla localizzazione dell'utente. L'applicazione deve utilizzare le autorizzazioni When In Use o Only Once. In caso contrario, l'applicazione genererà un errore di autorizzazione negata.

Per ottenere e visualizzare le posizioni di tracciamento, segui questa procedura:

  1. Per ottenere le posizioni dal dispositivo dell'utente, devi fornire la data e l'ora di inizio e fine. Una singola chiamata restituisce un massimo di 100 posizioni di tracciamento, ma se ci sono più di 100 posizioni di tracciamento, restituirà un valore `nextToken`. Dovrai chiamare le successive chiamate `getTrackerDeviceLocation` con `NextToken` per caricare più punti di tracciamento per l'ora di inizio e di fine specificata.

    func getTrackingPoints(nextToken: String? = nil) async throws { guard trackingActive else { return } // Initialize startTime to 24 hours ago from the current date and time. let startTime: Date = Date().addingTimeInterval(-86400) var endTime: Date = Date() if lastGetTrackingTime != nil { endTime = lastGetTrackingTime! } let result = try await client?.getTrackerDeviceLocation(nextToken: nextToken, startTime: startTime, endTime: endTime) if let trackingData = result { lastGetTrackingTime = Date() let devicePositions = trackingData.devicePositions let positions = devicePositions!.sorted { (pos1: LocationClientTypes.DevicePosition, pos2: LocationClientTypes.DevicePosition) -> Bool in guard let date1 = pos1.sampleTime, let date2 = pos2.sampleTime else { return false } return date1 < date2 } let trackingPoints = positions.compactMap { position -> CLLocationCoordinate2D? in guard let latitude = position.position!.last, let longitude = position.position!.first else { return nil } return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } DispatchQueue.main.async { self.mapViewDelegate!.drawTrackingPoints( trackingPoints: trackingPoints) } if let nextToken = trackingData.nextToken { try await getTrackingPoints(nextToken: nextToken) } } }
  2. Ora sostituisci il codice nel file con il seguente codice: MapView.swift

    import SwiftUI import MapLibre struct MapView: UIViewRepresentable { var onMapViewAvailable: ((MLNMapView) -> Void)? var mlnMapView: MLNMapView? var trackingViewModel: TrackingViewModel func makeCoordinator() -> MapView.Coordinator { return Coordinator(self, trackingViewModel: trackingViewModel) } func makeUIView(context: Context) -> MLNMapView { let styleURL = URL(string: "https://maps.geo.\(trackingViewModel.region).amazonaws.com/maps/v0/maps/\(trackingViewModel.mapName)/style-descriptor") let mapView = MLNMapView(frame: .zero, styleURL: styleURL) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.setZoomLevel(15, animated: true) mapView.showsUserLocation = true mapView.userTrackingMode = .follow context.coordinator.mlnMapView = mapView mapView.delegate = context.coordinator mapView.logoView.isHidden = true context.coordinator.addCenterMarker() onMapViewAvailable?(mapView) trackingViewModel.mlnMapView = mapView return mapView } func updateUIView(_ uiView: MLNMapView, context: Context) { } class Coordinator: NSObject, MLNMapViewDelegate, MapViewDelegate { var control: MapView var mlnMapView: MLNMapView? var trackingViewModel: TrackingViewModel var centerMarker: MLNPointAnnotation? public init(_ control: MapView, trackingViewModel: TrackingViewModel) { self.control = control self.trackingViewModel = trackingViewModel super.init() self.trackingViewModel.mapViewDelegate = self } func mapViewDidFinishRenderingMap(_ mapView: MLNMapView, fullyRendered: Bool) { if(fullyRendered) { mapView.accessibilityIdentifier = "MapView" mapView.isAccessibilityElement = false } } func addCenterMarker() { guard let mlnMapView = mlnMapView else { return } let centerCoordinate = mlnMapView.centerCoordinate let marker = MLNPointAnnotation() marker.coordinate = centerCoordinate marker.accessibilityLabel = "CenterMarker" mlnMapView.addAnnotation(marker) centerMarker = marker trackingViewModel.reverseGeocodeCenter(centerCoordinate: centerCoordinate, marker: marker) } func mapView(_ mapView: MLNMapView, regionDidChangeAnimated animated: Bool) { if let marker = centerMarker { DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { mapView.deselectAnnotation(marker, animated: false) marker.coordinate = mapView.centerCoordinate let centerCoordinate = mapView.centerCoordinate self.trackingViewModel.reverseGeocodeCenter(centerCoordinate: centerCoordinate, marker: marker) } } } func mapView(_ mapView: MLNMapView, viewFor annotation: MLNAnnotation) -> MLNAnnotationView? { guard let pointAnnotation = annotation as? MLNPointAnnotation else { return nil } let reuseIdentifier: String var color: UIColor = .black if pointAnnotation.accessibilityLabel == "Tracking" { reuseIdentifier = "TrackingAnnotation" color = UIColor(red: 0.00784313725, green: 0.50588235294, blue: 0.58039215686, alpha: 1) } else if pointAnnotation.accessibilityLabel == "LocationChange" { reuseIdentifier = "LocationChange" color = .gray } else { reuseIdentifier = "DefaultAnnotationView" } var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) if annotationView == nil { if reuseIdentifier != "DefaultAnnotationView" { annotationView = MLNAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier) //If point annotation is an uploaded Tracking point the radius is 20 and color is blue, otherwise radius is 10 and color is gray let radius = pointAnnotation.accessibilityLabel == "Tracking" ? 20:10 annotationView?.frame = CGRect(x: 0, y: 0, width: radius, height: radius) annotationView?.backgroundColor = color annotationView?.layer.cornerRadius = 10 if pointAnnotation.accessibilityLabel == "Tracking" { annotationView?.layer.borderColor = UIColor.white.cgColor annotationView?.layer.borderWidth = 2.0 annotationView?.layer.shadowColor = UIColor.black.cgColor annotationView?.layer.shadowOffset = CGSize(width: 0, height: 2) annotationView?.layer.shadowRadius = 3 annotationView?.layer.shadowOpacity = 0.2 annotationView?.clipsToBounds = false } } else { return nil } } return annotationView } func mapView(_ mapView: MLNMapView, didUpdate userLocation: MLNUserLocation?) { if (userLocation?.location) != nil { if trackingViewModel.trackingActive { let point = MLNPointAnnotation() point.coordinate = (userLocation?.location!.coordinate)! point.accessibilityLabel = "LocationChange" mapView.addAnnotation(point) Task { do { try await trackingViewModel.getTrackingPoints() } catch { print(error) } } } } } func checkIfTrackingAnnotationExists(on mapView: MLNMapView, at coordinates: CLLocationCoordinate2D) -> Bool { let existingAnnotation = mapView.annotations?.first(where: { annotation in guard let annotation = annotation as? MLNPointAnnotation else { return false } return annotation.coordinate.latitude == coordinates.latitude && annotation.coordinate.longitude == coordinates.longitude && annotation.accessibilityLabel == "Tracking" }) return existingAnnotation != nil } public func drawTrackingPoints(trackingPoints: [CLLocationCoordinate2D]?) { guard let mapView = mlnMapView, let newTrackingPoints = trackingPoints, !newTrackingPoints.isEmpty else { return } let uniqueCoordinates = newTrackingPoints.filter { coordinate in !checkIfTrackingAnnotationExists(on: mapView, at: coordinate) } let points = uniqueCoordinates.map { coordinate -> MLNPointAnnotation in let point = MLNPointAnnotation() point.coordinate = coordinate point.accessibilityLabel = "Tracking" return point } mapView.addAnnotations(points) } } } protocol MapViewDelegate: AnyObject { func drawTrackingPoints(trackingPoints: [CLLocationCoordinate2D]?) }

Per localizzare i valori delle stringhe, utilizzate la procedura seguente.

  1. Crea e aggiungi un nuovo file chiamatoLocalizable.xcstrings.

  2. Fai clic con il pulsante destro del mouse sul Localizable.xcstrings file e aprilo come codice sorgente.

  3. Sostituisci il suo contenuto con quanto segue:

    { "sourceLanguage" : "en", "strings" : { "Cancel" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Cancel" } } } }, "Error" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Error" } } } }, "Loading..." : { }, "locationManagerAlertText" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Allow \\\"Quick Start App\\\" to use your location" } } } }, "locationManagerAlertTitle" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "We need your location to detect your location in map" } } } }, "NotAllFieldsAreConfigured" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Not all the fields are configured" } } } }, "OK" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "OK" } } } }, "StartTrackingLabel" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Start Tracking" } } } }, "StopTrackingLabel" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Stop Tracking" } } } }, "Tracking" : { } }, "version" : "1.0" }
  4. Salva i tuoi file e crea ed esegui l'app per visualizzare in anteprima la funzionalità.

  5. Consenti l'autorizzazione alla posizione e tocca il pulsante di tracciamento. L'app inizierà a caricare le posizioni degli utenti e le caricherà sul localizzatore di localizzazione Amazon. Mostrerà anche le modifiche alla posizione dell'utente, i punti di tracciamento e l'indirizzo corrente sulla mappa.

La tua richiesta di avvio rapido è completa. Questo tutorial ti ha mostrato come creare un'applicazione iOS che:

  • Crea una mappa con cui gli utenti possono interagire.

  • Gestisce diversi eventi della mappa associati alla modifica della visualizzazione della mappa da parte dell'utente.

  • Richiama un'API Amazon Location Service, in particolare per cercare sulla mappa di una posizione, utilizzando l' searchByPosition API di Amazon Location.

Cosa c'è dopo

Il codice sorgente di questa applicazione è disponibile su GitHub.

Per ottenere di più da Amazon Location, puoi consultare le seguenti risorse: