While we consider ways to improve this experience, the recommended solution is to loop over the AGSMap.operationalLayers and call identifyLayer for each layer where identifyEnabled is true. It's what we do behind the scenes, but excluding the basemap layers.
There do happen to be benefits to this approach for some use cases. In particular, you can provide more granular feedback to your users as each layer's results return. But of course you can also limit the layers being identified against.
To coordinate the results, you could use a DispatchGroup. Create a group. Call enter() before you make each identifyLayer call and leave() when each call returns. Then you can use notify() to execute a block when all the identifies have completed.
Call something like this (I haven't tested it!) from the AGSGeoViewTouchDelegate method:
guard let operationalLayers = mapView.map?.operationalLayers as? [AGSLayer] else { return }
let identifyGroup = DispatchGroup()
var identifyResults: [AGSIdentifyLayerResult] = []
for layer in operationalLayers where layer.isIdentifyEnabled {
identifyGroup.enter()
mapView.identifyLayer(layer, screenPoint: screenPoint, tolerance: 20, returnPopupsOnly: false) { (result) in
defer { identifyGroup.leave() }
guard result.error == nil else {
print("Error identifying on layer \(result.layerContent.name): \(result.error!)")
return
}
identifyResults.append(result)
}
}
identifyGroup.notify(queue: .main) {
for result in identifyResults {
}
}
Note that if you call the above code from some non-main thread (unlikely), you'll need to coordinate writing to the identifyResults array to be thread-safe.
Hope this helps.