選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

將 Amazon Location 追蹤新增至您的應用程式

焦點模式
將 Amazon Location 追蹤新增至您的應用程式 - Amazon Location Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

應用程式的最後一步是將追蹤功能新增至應用程式。在這種情況下,您將在應用程式上新增開始追蹤、停止追蹤、擷取和顯示追蹤點。

  1. 在專案中新增 TrackingBottomView.swift 檔案。有一個按鈕,可啟動和停止追蹤使用者位置,並在地圖上顯示追蹤點。

    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. 使用下列程式碼更新TrackingView.swift檔案

    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. TrackingViewModel.swift 檔案中新增下列程式碼。這些函數負責開始和停止追蹤。如果使用者位置許可遭拒,也會顯示錯誤提醒。

  4. 若要實作前景追蹤複製,請貼上下列程式碼範例:

    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 }
    注意

    startTracking 會要求使用者的位置許可。應用程式必須使用使用中僅限一次許可。否則,應用程式會捨棄許可遭拒的錯誤。

若要取得和顯示追蹤位置,請遵循下列程序:

  1. 若要從使用者的裝置取得位置,您需要提供開始和結束日期和時間。單一呼叫最多傳回 100 個追蹤位置,但如果有超過 100 個追蹤位置,則會傳回 `nextToken` 值。您需要使用 `` 呼叫後續的 `getTrackerDeviceLocationnextToken`,以載入指定開始和結束時間的更多追蹤點。

    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. 現在使用下列程式碼取代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]?) }

若要本地化字串值 ,請使用下列程序。

  1. 建立並新增名為 的新檔案Localizable.xcstrings

  2. Localizable.xcstrings 檔案上按一下滑鼠右鍵,並將其開啟為原始碼

  3. 將其內容取代為以下內容:

    { "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. 儲存您的檔案,並建置和執行您的應用程式以預覽功能。

  5. 允許位置許可,然後點選追蹤按鈕。應用程式將開始上傳使用者位置,並將其上傳至 Amazon Location 追蹤器。它也會在地圖上顯示使用者位置變更、追蹤點和目前地址。

您的快速入門應用程式已完成。本教學課程已向您示範如何建立 iOS 應用程式:

  • 建立使用者可以互動的地圖。

  • 處理與使用者變更地圖檢視相關聯的數個地圖事件。

  • 呼叫 Amazon Location ServiceAPI,特別是使用 Amazon Location 的 搜尋位置的地圖 searchByPosition API。

下一步是什麼

您已完成快速入門教學課程,並應了解如何使用 Amazon Location Service 建置應用程式。

此應用程式的原始程式碼可在 上取得GitHub

若要進一步了解 Amazon Location,您可以查看下列資源:

在本頁面

隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。