title: how to get rid of the 'The API method must be called from the main thread' problem when retrieving data from an API to use them in arrays? Swift
body: <p>I come to you because I have the following problem:</p>
  <p>I work with the 'GoogleMaps' cocoapods and I need to place several markers in a map by using the latitude, longitude and a codeID that I get from an API. I will present you guys 2 cases: the one that works (that uses 3 hard coded arrays mentioned before) and the one that I try to get from the API and that crashes no matter what I do. OK, the first case (the one that works) is this one:</p>
  <pre><code>import UIKit
  import GoogleMaps
  
  class ViewController: UIViewController {
  // MARK: - Constants and variables
  let lat: Double = 38.739429 // User's Latitude
  let lon: Double = -9.137115 // User's Longitude
  let zoom: Float = 15.0
  
  // MARK: - Elements in the storyboard
  @IBOutlet weak var googleMap: GMSMapView!
  
  // MARK: - ViewDidLoad()
  override func viewDidLoad() {
      super.viewDidLoad()
      googleMapsStuff()
  }
  
  // MARK: - Google maps method
  func googleMapsStuff() {
      googleMap.delegate = self
      self.googleMap.isMyLocationEnabled = true // User's current position (blue dot on the map)
      let arrayLat: [Double] = [38.739, 38.74, 38.741, 38.732, 38.7325, 38.733]
      let arrayLon: [Double] = [-9.136, -9.135, -9.134, -9.137, -9.1375, -9.138]
      //var arrayCompanyZoneID: [Int] = []
      let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: self.zoom)
  
      googleMap.camera = camera
      
      for index in 0..&lt;arrayLon.count {
          let marker = GMSMarker()
          marker.position = CLLocationCoordinate2D(latitude: arrayLat[index], longitude: arrayLon[index])
          marker.title = &quot;Marker number: \(index)&quot;
          marker.snippet = &quot;Marker's Lat: \(arrayLat[index]), Marker's Lon: \(arrayLon[index])&quot;
          marker.map = self.googleMap
          print(&quot;Index: \(index)&quot;)
      }
  }
  }
  </code></pre>
  <p>And as you can see in the image, it all goes smoothly well<a href="https://i.stack.imgur.com/dX5ef.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dX5ef.jpg" alt="ScreenShotGood" /></a></p>
  <p>The problem comes in the second case, when I try to fill the empty arrays (which it seems to do) when I connect to an API to get that data. This is the &quot;failure&quot; case:</p>
  <pre><code>struct MyInfo: Codable {
  let id: String
  let name: String
  let x: Double // Longitude
  let y: Double // Latitude
  let licencePlate: String?
  let range: Int?
  let batteryLevel: Int?
  let seats: Int?
  let model: String?
  let resourceImageId: String?
  let pricePerMinuteParking: Int?
  let pricePerMinuteDriving: Int?
  let realTimeData: Bool?
  let engineType: String?
  let resourceType: String?
  let companyZoneId: Int
  let helmets: Int?
  let station: Bool?
  let availableResources: Int?
  let spacesAvailable: Int?
  let allowDropoff: Bool?
  let bikesAvailable: Int?
  }
  
  class ViewController: UIViewController {
  // MARK: - Constants and variables
  let lat: Double = 38.739429 // User's Latitude
  let lon: Double = -9.137115 // User's Longitude
  let zoom: Float = 15.0
  var arrayLat: [Double] = [] // [38.7395, 38.739, 38.74, 38.741, 38.732, 38.7325, 38.733]
  var arrayLon: [Double] = [] // [-9.1365, -9.136, -9.135, -9.134, -9.137, -9.1375, -9.138]
  var arrayCompanyZoneID: [Int] = [] // [1, 2, 3, 4, 5, 6, 7]
  
  // MARK: - Elements in the storyboard
  @IBOutlet weak var googleMap: GMSMapView!
  
  // MARK: - ViewDidLoad()
  override func viewDidLoad() {
      super.viewDidLoad()
      googleMap.delegate = self
      
      self.googleMap.isMyLocationEnabled = true // User's current position (blue dot on the map)
      let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: self.lat, longitude: self.lon, zoom: self.zoom)
  
      googleMap.camera = camera
      
      guard let urlAPI = URL(string: &quot;https://apidev.meep.me/tripplan/api/v1/routers/lisboa/resources?lowerLeftLatLon=38.711046,-9.160096&amp;upperRightLatLon=38.739429,-9.137115&quot;) else { return }
      
      let task = URLSession.shared.dataTask(with: urlAPI) {(data, response, error) in
          if error == nil {
              guard let urlContent = data else { return }
              
              do {
                  let JSONResult = try JSONDecoder().decode([MyInfo].self, from: urlContent) //JSONSerialization.jsonObject(with: urlContent, options: .mutableContainers)
                  print(&quot;JSON Result:&quot;, JSONResult)
                  
                  for jsonData in JSONResult {
                      self.arrayLon.append(jsonData.x)
                      self.arrayLat.append(jsonData.y)
                      self.arrayCompanyZoneID.append(jsonData.companyZoneId)
                  }
                  
                  print(&quot;-----------------&quot;)
                  print(type(of: JSONResult))
                  print(&quot;-----------------&quot;)
                  print(&quot;ArrayLon:&quot;, self.arrayLon)
                  print(&quot;ArrayLat:&quot;, self.arrayLat)
                  print(&quot;companyZoneId: &quot;, self.arrayCompanyZoneID)
                  print(&quot;Count zoneid: &quot;, self.arrayCompanyZoneID.count)
                  print(&quot;-----------------&quot;)
                  
                  // MARK: - Place the multiple markers on the map
                  for index in 0..&lt;self.arrayCompanyZoneID.count {
                      let marker = GMSMarker()
                      marker.position = CLLocationCoordinate2D(latitude: self.arrayLat[index], longitude: self.arrayLon[index])
                      marker.title = &quot;Marker number: \(index)&quot;
                      marker.snippet = &quot;Marker's Lat: \(self.arrayLat[index]), Marker's Lon: \(self.arrayLon[index])&quot;
                      marker.map = self.googleMap
                      print(&quot;Index: \(index)&quot;)
                  }
                  
              } catch {
                  print(&quot;JSON processing failed.&quot;)
              }
          } else {
              print(&quot;Error serializing JSON:&quot;, error!)
          }
      }
      
      task.resume()
  }
  </code></pre>
  <p>And it doesn't matter what I do, the console always says:</p>
  <blockquote>
  <p>&quot;Terminating app due to uncaught exception 'GMSThreadException', reason: 'The API method must be called from the main thread' &quot;</p>
  </blockquote>
  <p>I also tried using the method</p>
  <pre><code>func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
  
  </code></pre>
  <p>but it also says that the API method most be called from the main thread.</p>
  <p>I'm so stuck here and I invested several hours to this issue but It only fails over and over.</p>
  <p>I appreciate your advice and wisdom.</p>
  <p>Thanks in advance.</p>