I have data stored in a dynamoDB table on Amazon. I'm able to query that table. Within the dynamoDbObjectMapper.query statement I can print the result. With the result I want to create GMSMakers (pins on a Google Map). But when I call this the app crashes with a message stating "The API method must be called from the main thread". I just don't seem to get what I need to do.
So my question is if somebody can provide an example that can help me understand what's going on and guide me towards the solution. Passing the result of query "upwards" to the main thread so I can call the Google SDK functions.
I would appreciate it very much.....
Here is my code (please be gentle....). Result : the GMSMarker call generates this runtime exception: 'GMSThreadException', reason: 'The API method must be called from the main thread'
import UIKit
import GoogleMaps
import AWSCore
import AWSMobileClient
import AWSDynamoDB
class DiscoverViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
@IBOutlet weak var mapView: GMSMapView!
var currentPositionMarker: GMSMarker!
var locationManager = CLLocationManager()
var output: AWSDynamoDBPaginatedOutput!
var paginatedOutput: AWSDynamoDBPaginatedOutput?
override func viewDidLoad() {
super.viewDidLoad()
//Hide the mapview until the currentlocation is found. unhide will be done from the event handler.
mapView.isHidden = true
mapView.delegate = self
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
// Request current location: once.
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.requestLocation() //One time request
}
//first create query expression
let queryExpression = AWSDynamoDBQueryExpression()
queryExpression.keyConditionExpression = "#attribute1 = :value1"
queryExpression.expressionAttributeNames = [ "#attribute1": "storyUserId" ]
queryExpression.expressionAttributeValues = [ ":value1": "roger"]
let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
dynamoDbObjectMapper.query(Stories.self, expression: queryExpression) { (output: AWSDynamoDBPaginatedOutput?, error: Error?) in
if error != nil {
print("The request failed. Error: \(String(describing: error))")
}
if output != nil {
print(output!.items)
for stories in output!.items {
let story = stories as? Stories
print("Pin read \(story!._storyUserId!)")
print("Pin read \(story!._storyName!)")
print("Pin read \(story!._storyDateTime!)")
print("Pin read \(story!._storyAudioFilename!)")
print("Pin read \(story!._storyLongitude!)")
print("Pin read \(story!._storyLatitude!)")
print("Creating pin")
let positionMarker = GMSMarker()
positionMarker.position.latitude = story!._storyLatitude as! Double
positionMarker.position.longitude = story!._storyLongitude as! Double
positionMarker.title = story!._storyName
positionMarker.snippet = story!._storyAudioFilename
positionMarker.iconView = currentPositionMarkerView
positionMarker.map = self.mapView
self.showPins(result: output!)
} else {
print("No data read from the table")
}
}
// Do any additional setup after loading the view, typically from a nib.
}