You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4.1中如何结合JSON在Google Map添加并显示多个标记?

Fixing Multiple Markers on Google Maps with Swift 4.1 + JSON Data

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 addMarkersToMap in DispatchQueue.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:43:37