I am trying to add activity indicator while updating annotation on the map. But it seems not to work such a way. Application screen disables and becomes frozen once process of update is started, so that's why probably activity indicator is not visible.
My question is: Is it possible to update annotations on the map asynchronous with the app, so activity indicator would be visible.
I believe it is really annoying for the user not to see indicator if it takes more then 2 sec.
Solution:
self.activityIndicator.startAnimating()
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), {
self.showPins(self.initialLat, locationLong: self.initialLong)
})
self.activityIndicator.stopAnimating()
You have to make sure you are doing these things:
Apple recommends in the MKMapView Class Reference all annotations (pins) should be loaded at once:
When configuring your map interface, you should add all of your annotation objects right away. The map view uses the coordinate data in each annotation object to determine when the corresponding annotation view needs to appear onscreen. [...] Because annotation views are needed only when they are onscreen, the MKMapView class provides a mechanism for queueing annotation views that are not in use. Annotation views with a reuse identifier can be detached and queued internally by the map view when they move offscreen. This feature improves memory use by keeping only a small number of annotation views in memory at once and by recycling the views you do have. It also improves scrolling performance by alleviating the need to create new views while the map is scrolling.
You have to make sure you are correctly reusing existing annotation views by using dequeueReusableAnnotationViewWithIdentifier in the viewForAnnotation
method.
If you can't fetch / load the annotations at once you could use Grand Central Dispatch to let the 'heavy' method run on a background thread so the UI doesn't block. Note: any changes to the UI from within that method (on the bg thread) will need to explicitly happen on the main UI thread.
Regarding backgrounding, take a look at this Stackoverflow answer:
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
print("This is run on the background queue")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("This is run on the main queue, after the previous code in outer block")
})
})
Or alternatively, use this 'Async' library for some syntactic sugar.