Swift 4.1中如何结合JSON在Google Map添加并显示多个标记?
Hey there! Let's get those Google Maps markers showing up from your JSON data—you're already halfway there since you can pull the data into your app. Here's how to connect the dots (literally!):
Step 1: Clean Up Your JSON Request & Parse Data Properly
First, let's update your JSON fetch code to use async URLSession (since NSData(contentsOf:) is synchronous and can block your UI) and parse the data into a reusable structure. Let's start with a simple model to hold your device data:
// Define a struct to map your JSON data (adjust field names to match your actual JSON!) struct Device { let latitude: Double let longitude: Double let title: String let snippet: String }
Now rewrite your JSON request to fetch and parse the data asynchronously:
func fetchDevices() { guard let jsonUrl = URL(string: "http://assetlinkasia.no-ip.biz:8001/hf_tracker/api/userdevices.php?accesskey=12345&user_id=1") else { print("Invalid URL") return } URLSession.shared.dataTask(with: jsonUrl) { data, response, error in if let error = error { print("Error fetching data: \(error.localizedDescription)") return } guard let data = data else { print("No data received") return } do { // Parse the root JSON object let jsonObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] // Extract the "data" array from the root object guard let devicesData = jsonObject?["data"] as? [[String: Any]] else { print("Couldn't extract devices array from JSON") return } // Convert each JSON entry to our Device struct var devices = [Device]() for deviceDict in devicesData { // Replace these keys with the exact ones from your JSON (e.g., "lat", "lng", "device_name") guard let lat = deviceDict["latitude"] as? Double, let lng = deviceDict["longitude"] as? Double, let deviceTitle = deviceDict["device_name"] as? String, let deviceSnippet = deviceDict["location"] as? String else { print("Skipping invalid device entry") continue } devices.append(Device(latitude: lat, longitude: lng, title: deviceTitle, snippet: deviceSnippet)) } // Update the map on the main thread (UI changes must run here!) DispatchQueue.main.async { self.addMarkersToMap(with: devices) } } catch { print("Error parsing JSON: \(error.localizedDescription)") } }.resume() }
Step 2: Add Markers to Google Maps
Next, create a function to loop through your Device array and add a marker for each entry. First, make sure mapView is a class-level property so you can reference it everywhere:
// Add this as a property in your ViewController var mapView: GMSMapView! let locationManager = CLLocationManager() // Function to add markers from the devices array func addMarkersToMap(with devices: [Device]) { for device in devices { let marker = GMSMarker() // Set marker position using the device's lat/lng from JSON marker.position = CLLocationCoordinate2D(latitude: device.latitude, longitude: device.longitude) marker.infoWindowAnchor = CGPoint(x: 0.10, y: 0.10) marker.title = device.title marker.snippet = device.snippet marker.icon = UIImage(named: "markers") marker.map = mapView // Attach the marker to your map } }
Step 3: Update Your Map Setup
Adjust your original map initialization code to use the class-level mapView and trigger the device fetch:
override func viewDidLoad() { super.viewDidLoad() // Initialize map with a default camera position let initialCamera = GMSCameraPosition.camera(withLatitude: 24.8607, longitude: 67.0011, zoom: 13.0) mapView = GMSMapView.map(withFrame: view.bounds, camera: initialCamera) view.addSubview(mapView) // Set up location tracking (your original code) locationManager.delegate = self locationManager.requestWhenInUseAuthorization() locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.startUpdatingLocation() mapView.delegate = self // Fetch devices and add markers to the map fetchDevices() }
Key Reminders
- Match JSON Keys: Double-check that the keys in your parsing code exactly match the keys in your actual JSON response (e.g., if your JSON uses "lat" instead of "latitude", update the code!).
- Main Thread: Always update UI elements (like map markers) on the main thread—this is why we wrap
addMarkersToMapinDispatchQueue.main.async. - Optional Safety: The guard clauses skip any invalid entries in the JSON, preventing crashes if some data is missing.
That's it! When you run the app, it'll fetch your device data, parse the coordinates, and drop a marker for each device on your Google Map.
内容的提问来源于stack exchange,提问作者Rehan Meo

