Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]

SwiftGoogle MapsXcode9 Beta

Swift Problem Overview


I am using google maps in Xcode 9 beta, iOS 11.

I am getting an error outputted to the log as follows:

> Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState] PID: 4442, TID: 837820, Thread name: com.google.Maps.LabelingBehavior, Queue name: com.apple.root.default-qos.overcommit, QoS: 21

Why would this be occurring as I am almost certain I'm not altering any interface elements from the main thread in my code.

 override func viewDidLoad() {
        
    let locationManager = CLLocationManager()
        
        
    locationManager.requestAlwaysAuthorization()
        
        
    locationManager.requestWhenInUseAuthorization()
        
        if CLLocationManager.locationServicesEnabled() {
            
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }
        
      viewMap.delegate = self
        
     let camera = GMSCameraPosition.camera(withLatitude: 53.7931183329367, longitude: -1.53649874031544, zoom: 17.0)
        
        
        viewMap.animate(to: camera)
        
      
    }
    
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }
    
    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
        
        
    }
    
    func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
        
        if(moving > 1){
            moving = 1
        UIView.animate(withDuration: 0.5, delay: 0, animations: {
            
            self.topBarConstraint.constant = self.topBarConstraint.constant + (self.topBar.bounds.height / 2)
            
            self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant + (self.topBar.bounds.height / 2)
            
            self.view.layoutIfNeeded()
        }, completion: nil)
    }
         moving = 1
    }
    
    
    // Camera change Position this methods will call every time
    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
        moving = moving + 1
        if(moving == 2){
            
            
            UIView.animate(withDuration: 0.5, delay: 0, animations: {
                
                
                self.topBarConstraint.constant = self.topBarConstraint.constant - (self.topBar.bounds.height / 2)
                
                self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant - (self.topBar.bounds.height / 2)
                
                
                self.view.layoutIfNeeded()
            }, completion: nil)
        }
        DispatchQueue.main.async {
            
            print("Moving: \(moving) Latitude: \(self.viewMap.camera.target.latitude)")
            print("Moving: \(moving)  Longitude: \(self.viewMap.camera.target.longitude)")
        }
    }
    

Swift Solutions


Solution 1 - Swift

It's hard to find the UI code which is not executed in main thread sometimes. You can use the trick below to locate it and fix it.

  1. Choose Edit Scheme -> Diagnostics, tick Main Thread Checker.

Xcode 11.4.1

Click the small arrow next to the Main Thread Checker to create a Main Thread Checker breakpoint. enter image description here

Previous Xcode

Tick on Pause on issues. enter image description here

  1. Run your iOS application to reproduce this issue. (Xcode should pause on the first issue.) enter image description here

  2. Wrap the code that modify the UI in DispatchQueue.main.async {} enter image description here

Solution 2 - Swift

First, make sure your invocations of google maps and ui changes are called from the main thread.

You can enable Thread Sanitizer option in Xcode using below steps:

Screenshot

You can put offending lines on the main thread with the following:

DispatchQueue.main.async {
    //Do UI Code here. 
    //Call Google maps methods.
}

Also, update your current version of google maps. Google maps had to make a couple of updates for the thread checker.

For the question: "Why would this be occurring?" I think Apple added an assertion for an edge case which Google then had to update their pod for.

Solution 3 - Swift

Wrap the lines of code that modify the UI in DispatchQueue.main.async {} in order to make sure they execute on the main thread. Otherwise, you may be calling them from a background thread, where UI modifications are not allowed. All such lines of code must be executed from the main thread.

Solution 4 - Swift

Refer this link https://developer.apple.com/documentation/code_diagnostics/main_thread_checker

For me this worked when I called from block.

Solution 5 - Swift

Solution 6 - Swift

Choose scheme -> Diagnotics, remove main thread checker, then the warning will disappear. scheme editor

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattBlackView Question on Stackoverflow
Solution 1 - SwiftwebcpuView Answer on Stackoverflow
Solution 2 - SwiftScottyBladesView Answer on Stackoverflow
Solution 3 - SwiftTomaView Answer on Stackoverflow
Solution 4 - SwiftKrishna Chaitanya BandaruView Answer on Stackoverflow
Solution 5 - SwiftgamalView Answer on Stackoverflow
Solution 6 - SwiftL.PengView Answer on Stackoverflow