I see. So what you need to do is perform a Query (or multiple queries, if there are many layers).
Identify is designed to handle click or tap events on the map to find out what the user tapped on.
Query is much more powerful, and executes against the tables behind each layer in the map.
What you might do it look at the AGSMap.operationalLayers and determine a set of feature layers that you want to get information about. For each of those feature layers, get the feature table, create an AGSQueryParameters, set the geometry and spatialRelationship on that AGSQueryParameters to the geometry you get back from the sketch editor, and call query on the feature table.
Attached is a project that does this. Here's what the code looks like:
func queryMapLayers(for polygon: AGSPolygon) {
let queryParameters = AGSQueryParameters()
queryParameters.spatialRelationship = .intersects
queryParameters.geometry = polygon
map.load { [weak self] error in
guard let self = self else { return }
if let error = error {
print("Error loading the map: \(error.localizedDescription)")
return
}
// Synchronize our results
let queryGroup = DispatchGroup()
var queryResults = [AGSFeatureTable: AGSFeatureQueryResult]()
var queryErrors = [AGSFeatureTable: Error]()
let currentScale = self.mapView.mapScale
self.map.operationalLayers.lazy.compactMap {
// Let's reduce the layers to just AGSFeatureLayers
$0 as? AGSFeatureLayer
}.filter {
// Clear the selection from any previous selection.
$0.clearSelection()
// Make sure we just consider the currently visible layers.
// Just return true if you want all layers, regardless of current scale.
return $0.isVisible(atScale: currentScale)
}.compactMap {
// Convert the sequence to AGSFeatureTables
$0.featureTable
}.forEach { featureTable in
// Query each feature table, coordinating responses using the DispatchGroup.
queryGroup.enter()
print("Querying \(featureTable.tableName)")
featureTable.queryFeatures(with: queryParameters) { [featureTable] queryResult, error in
print("Queryied \(featureTable.tableName)")
defer {
// Let the dispatch group know we're done waiting for this table's query.
queryGroup.leave()
}
if let error = error {
// Save the error to handle as a batch once everything returns using DispatchGroup.
queryErrors[featureTable] = error
return
}
// Save the results to look at later, once ALL tables have responded.
queryResults[featureTable] = queryResult
// Or look at the results as we get them
if let queryResult = queryResult {
// Output the results as we get them
print("Got results for table \(featureTable.tableName)")
let layer = featureTable.layer as? AGSFeatureLayer
layer?.clearSelection()
for case let feature as AGSFeature in queryResult.featureEnumerator() {
print(feature)
layer?.select(feature)
}
}
}
}
// You could handle errors and results as they come in above, but with a DispatchGroup,
// you can control whether to wait for all results/errors to come back before doing
// something. In this case we're handling each result as it comes in above, but coordinating
// all errors we might get back.
queryGroup.notify(queue: .main) {
if !queryErrors.isEmpty {
print("\(queryErrors.count) tables failed on query:")
queryErrors.forEach { table, error in
print("Error querying table \(table.tableName): \(error)")
let layer = table.layer as? AGSFeatureLayer
layer?.clearSelection()
}
}
// We looked at each result as it came in above, but we could instead/also look at them
// all together here.
// queryResults.forEach { table, result in
// print("Got results for table \(table.tableName)")
//
// let layer = table.layer as? AGSFeatureLayer
// layer?.clearSelection()
//
// for case let feature as AGSFeature in result.featureEnumerator() {
// print(feature)
// layer?.select(feature)
// }
// }
}
}
}
Hope this helps!