1.9 C
New York
Sunday, December 1, 2024

ios – Including annotations to mapbox map on Swift


I’m attempting to create a mapbox map and cargo a listing of nations from a csv file. The annotations are added from this line which works. Nevertheless, I solely want this operate to execute as soon as or it’ll causes efficiency challenge. Irrespective of I alter the road to a different place, it would not work.

I’m new to Swift and any assist is way appreciated.

func updateUIView(_ uiView: MapboxMaps.MapView, context: Context) {
        addCountryAnnotations(to: uiView, context: context)
    }

That is my full code.

//
//  ContentView.swift
//

import SwiftUI
import MapboxMaps
import CoreLocation
import FlagKit

struct ContentView: View {
    @StateObject personal var viewModel = CountryViewModel()
    @StateObject personal var locationManager = LocationManager()
    @State personal var isPanelExpanded = false
    @State personal var selectedCountry: Nation?
    @State personal var countryInfo: String = ""
    
    var physique: some View {
        ZStack {
            MapViewRepresentable(international locations: viewModel.international locations, userLocation: locationManager.location, onCountryTapped: { nation, data in
                selectedCountry = nation
                countryInfo = data
                isPanelExpanded = true
            })
            .ignoresSafeArea()
            .onAppear {
                viewModel.loadCountries()
                locationManager.requestLocation()
            }
            
            VStack {
                Spacer()
                BottomPanelView(isExpanded: $isPanelExpanded, nation: $selectedCountry, countryInfo: $countryInfo)
                    .body(top: isPanelExpanded ? 300 : 100)
                    .transition(.transfer(edge: .backside))
            }
        }
    }
}

struct MapViewRepresentable: UIViewRepresentable {
    let international locations: [Country]
    let userLocation: CLLocationCoordinate2D?
    let onCountryTapped: (Nation, String) -> Void
    
    personal func fetchCountryInfo(for nation: Nation, completion: @escaping (Outcome) -> Void) {
        let countryName = nation.identify.replacingOccurrences(of: " ", with: "_")
        let urlString = "https://en.wikipedia.org/api/rest_v1/web page/abstract/(countryName)"
        
        guard let url = URL(string: urlString) else {
            completion(.failure(NSError(area: "Invalid URL", code: 0, userInfo: nil)))
            return
        }
        
        let process = URLSession.shared.dataTask(with: url) { information, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let information = information else {
                completion(.failure(NSError(area: "No information", code: 0, userInfo: nil)))
                return
            }
            
            do {
                if let json = attempt JSONSerialization.jsonObject(with: information, choices: []) as? [String: Any],
                   let extract = json["extract"] as? String {
                    print("Fetched content material: (extract)") // Debugging print assertion
                    completion(.success(extract))
                } else {
                    completion(.failure(NSError(area: "Invalid JSON", code: 0, userInfo: nil)))
                }
            } catch {
                completion(.failure(error))
            }
        }
        
        process.resume()
    }
    
    static let defaultLocation = CLLocationCoordinate2D(latitude: 22.3193, longitude: 114.1694)
    
    func makeUIView(context: Context) -> MapboxMaps.MapView {
        let choices = MapInitOptions(cameraOptions: CameraOptions(heart: userLocation ?? MapViewRepresentable.defaultLocation, zoom: 10))
        let mapView = MapboxMaps.MapView(body: .zero, mapInitOptions: choices)
        mapView.gestures.delegate = context.coordinator
        context.coordinator.mapView = mapView
        return mapView
    }
    
    func updateUIView(_ uiView: MapboxMaps.MapView, context: Context) {
        addCountryAnnotations(to: uiView, context: context)
    }
    
    personal func addCountryAnnotations(to mapView: MapboxMaps.MapView, context: Context) {
        var annotations: [PointAnnotation] = []
        
        for nation in international locations {
            var annotation = PointAnnotation(coordinate: nation.coordinate)
            if let flagImage = nation.flagImage {
                annotation.picture = .init(picture: flagImage.resized(to: CGSize(width: 30, top: 20)), identify: nation.code)
            }
            annotation.iconAnchor = .backside
            annotations.append(annotation)
        }
        
        let annotationManager = mapView.annotations.makePointAnnotationManager()
        annotationManager.annotations = annotations
        annotationManager.delegate = context.coordinator
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, AnnotationInteractionDelegate, GestureManagerDelegate {
        var dad or mum: MapViewRepresentable
        var mapView: MapboxMaps.MapView?
        
        init(_ dad or mum: MapViewRepresentable) {
            self.dad or mum = dad or mum
        }
        
        func annotationManager(_ supervisor: AnnotationManager, didDetectTappedAnnotations annotations: [Annotation]) {
            guard let annotation = annotations.first as? PointAnnotation, let countryName = annotation.textField else { return }
            if let nation = dad or mum.international locations.first(the place: { $0.identify == countryName }) {
                dad or mum.fetchCountryInfo(for: nation) { end in
                    swap consequence {
                    case .success(let data):
                        DispatchQueue.most important.async {
                            self.dad or mum.onCountryTapped(nation, data)
                        }
                    case .failure(let error):
                        print("Did not fetch nation data: (error.localizedDescription)")
                    }
                }
                flyToCountry(nation)
            }
        }
        
        personal func flyToCountry(_ nation: Nation) {
            guard let mapView = mapView else { return }
            let cameraOptions = CameraOptions(heart: nation.coordinate, zoom: 10, bearing: 0, pitch: 0)
            mapView.digital camera.fly(to: cameraOptions, length: 2.0)
        }
        
        // Implement required strategies for GestureManagerDelegate
        func gestureManager(_ gestureManager: GestureManager, didBegin gestureType: GestureType) {}
        func gestureManager(_ gestureManager: GestureManager, didEnd gestureType: GestureType, willAnimate: Bool) {}
        func gestureManager(_ gestureManager: GestureManager, didEndAnimatingFor gestureType: GestureType) {}
    }
}

class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    personal let locationManager = CLLocationManager()
    @Printed var location: CLLocationCoordinate2D?
    
    override init() {
        tremendous.init()
        locationManager.delegate = self
    }
    
    func requestLocation() {
        locationManager.requestWhenInUseAuthorization()
        locationManager.requestLocation()
    }
    
    func locationManager(_ supervisor: CLLocationManager, didUpdateLocations areas: [CLLocation]) {
        location = areas.first?.coordinate
    }
    
    func locationManager(_ supervisor: CLLocationManager, didFailWithError error: Error) {
        print("Did not get consumer location: (error.localizedDescription)")
    }
}

extension UIImage {
    func resized(to measurement: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(measurement, false, 0.0)
        draw(in: CGRect(origin: .zero, measurement: measurement))
        let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return resizedImage!
    }
}

I adopted the official documentations of right here, nonetheless, it would not give instance on learn how to work together from organising the map and nonetheless utilizing UIKit. I assume that is fairly outdated.

https://docs.mapbox.com/ios/maps/guides/markers-and-annotations/annotations/

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles