This should get you to where you want to get. It's a bit limited. It returns AGSGraphics rather than an AGSFeatureSet of some sort, but I think it'll do what you need:
func doQuery(mapPoint: AGSPoint, fields: [String] = ["*"], returnGeometry: Bool = true, completion: (([AGSGraphic]?) -> Void)? = nil) {
guard let serviceURL = layer.url?.appendingPathComponent("\(3)") else { return }
var mapPointData: Data?
do {
let mapPointJSON = try mapPoint.toJSON()
mapPointData = try JSONSerialization.data(withJSONObject: mapPointJSON)
} catch {
print("Could not convert AGSPoint to JSON: \(error.localizedDescription)")
completion?(nil)
return
}
guard mapPointData != nil,
let mapPointJSONString = String(data: mapPointData!, encoding: .utf8) else {
completion?(nil)
return
}
let inSR = mapPoint.spatialReference ?? AGSSpatialReference.webMercator()
let outSR = mapView.spatialReference ?? AGSSpatialReference.webMercator()
let parameters: [String : Any] = [
"f": "json",
"geometry": mapPointJSONString,
"geometryType": "esriGeometryPoint",
"inSR": inSR.wkid,
"maxAllowableOffset": 0.000000,
"outFields": fields.joined(separator: ","),
"outSR":outSR.wkid,
"returnDistinctValues": false,
"returnGeometry": returnGeometry,
"returnM": true,
"returnZ": true,
"spatialRel": "esriSpatialRelIntersects"
]
let queryUrl = serviceURL.appendingPathComponent("query")
let operation = AGSJSONRequestOperation(remoteResource: nil, url: queryUrl, queryParameters: parameters)
operation.registerListener(self) { (result, error) in
if let error = error {
print("Error performing query! \(error.localizedDescription)")
completion?(nil)
return
}
guard let result = result as? [String: Any],
let fields = (result["fields"] as? [Any])?.compactMap({ try? AGSField.fromJSON($0) as? AGSField }),
let graphics = (result["features"] as? [[String: Any]])?.compactMap({ data -> AGSGraphic? in
let attributes = data["attributes"] as? [String: Any]
let geometry: AGSGeometry? = {
if let geomDict = data["geometry"] as? [String: Any] {
let geom = try? AGSGeometry.fromJSON(geomDict) as? AGSGeometry
if let geom = geom, geom.spatialReference == nil {
return AGSGeometryEngine.projectGeometry(geom, to: outSR)
}
return geom
}
return nil
}()
if attributes == nil && geometry == nil { return nil }
return AGSGraphic(geometry: geometry, symbol: nil, attributes: attributes)
}) else
{
completion?(nil)
return
}
completion?(graphics)
}
AGSOperationQueue.shared().addOperation(operation)
}
Note line 41 where I don't have to provide a credential because I'm using AGSJSONRequestOperation and if we've already authenticated for that service URL with Runtime, it'll use that credential automatically. And I've been a bit lazy in terms of returning errors, and the layer is hardcoded, but you can call this with something like this:
doQuery(mapPoint: mapPoint, fields: ["OBJECTID", "NAME"]) { graphics in
guard let graphics = graphics else {
print("Something went wrong during the query")
return
}
print("Got \(graphics.count) graphics back!")
}
Hope this helps!