Hi,
IOS SWIFT
I want to query features with attachments.
I have tried to use the sample edit data attachment but not successful.
When I using the identify layer, am able to get the attachment, but I want to achieve through query layers. Below are the code, I have tried.
var featureTable: AGSServiceFeatureTable!
featureTable = AGSServiceFeatureTable(url: URL(string: layoutMapping.offersURL)!)
let featureLayer = AGSFeatureLayer(featureTable: featureTable)
let map = AGSMap()
let mapImageLayer = AGSArcGISTiledLayer(url: URL(string: layoutMapping.arcGISURL)!)
map.operationalLayers.add(mapImageLayer)
map.operationalLayers.add(featureLayer)
self.mapViews.map = map
let layers:[AGSLayer]! = map.operationalLayers as! [AGSLayer]
let featureLayer1:AGSFeatureLayer = layers[1] as! AGSFeatureLayer
let queryParams = AGSQueryParameters()
let query = "1=1"
queryParams.whereClause = query
let table1 = featureLayer1.featureTable as! AGSServiceFeatureTable
table1.queryFeatures(with: queryParams, queryFeatureFields: .loadAll, completion: { (result:AGSFeatureQueryResult?, error:Error?) -> Void in
if error != nil {
let alert = UIAlertController(title: self.layoutMapping.appTitle, message: "Server Connection Failed!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)
}
else if let features = result?.featureEnumerator().allObjects as? [AGSArcGISFeature] , features.count > 0 {
for feature in features
{
var imageList = [UIImage]()
guard let arcgisFeature = feature as? AGSArcGISFeature else {
print("test")
}
feature.fetchAttachments { (attachments:[AGSAttachment]?, error:Error?) -> Void in
if let error = error {
print(error)
}
else if let attachments = attachments {
print(attachments.count)
let attachment = attachments[0]
attachment.fetchData { (data:Data?, error:Error?) -> Void in
if let error = error {
print(error)
}
else if let data = data {
let image = UIImage(data: data)!
//cell.imageView?.image = image
imageList.append(image)
}
}
}
}
}
}
})
Please provide your answer.
Thanks
The problem you're seeing is that each AGSArcGISFeature is going out of scope and being deallocated before the async fetchAttachments call is completing. You could try something like this, which uses Swift closure captures to hold a reference to a feature until the fetchAttachments call has completed.
func getAttachments() {
let params = AGSQueryParameters()
params.whereClause = "1=1"
table.queryFeatures(with: params, queryFeatureFields: .loadAll) { (results, error) in
guard error == nil else {
print("Error querying features: \(error!.localizedDescription)")
return
}
guard let featureEnumerator = results?.featureEnumerator() else { return }
// Create a Set to store feature references
var featuresHavingAttachmentsFetched = Set<AGSArcGISFeature>()
var i = 0
for result in featureEnumerator {
guard let feature = result as? AGSArcGISFeature else { continue }
// Store the feature reference in the set
featuresHavingAttachmentsFetched.insert(feature)
print("Getting attachments for feature \(i).")
// Call fetch attachments, but also capture `feature` so that it can be removed from the
// set maintaining the reference to it once the attachment fetch completes.
feature.fetchAttachments() { [feature, i] (attachments, error) in
defer {
// Remove the feature reference when this fetchAttachments callback block exits.
// We've held on to it long enough now and don't need it any more.
featuresHavingAttachmentsFetched.remove(feature)
}
guard error == nil else {
print("Error getting attachments for feature \(i): \(error!.localizedDescription)")
return
}
print("Got \(attachments?.count ?? 0) attachments for feature \(i).")
}
i += 1
}
}
}
Cheers,
Nick.