How to wait and get results out completion of featureTable.queryFeatures

541
2
Jump to solution
09-24-2019 02:10 AM
HaiLe_Hong
New Contributor

I have a function must return a string, but my problem is Asynchronous Tasks.  How to wait and get results out completion of featureTable.queryFeatures. Thanks!

    func GetValueSum(geo : AGSGeometry ) -> String{
        var strReturn = ""

        let queryParameters = AGSQueryParameters()
        queryParameters.geometry = geo
        queryParameters.spatialRelationship = AGSSpatialRelationship.intersects
        queryParameters.outSpatialReference = self.mapView.spatialReference
        
        self.featureTable?.queryFeatures(with: queryParameters, completion: { (result: AGSFeatureQueryResult?, error: Error?) in
    
            if error != nil {
                print("Error in function")
            } else if let features = result?.featureEnumerator().allObjects {
                for feature in features {
                    strReturn += "\(feature.attributes["Label1"]!); "
                    print("For string: \(strReturn)")
                }
            }
        })
                
        print("Return string: \(strReturn)")
        return strReturn
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The result:

But the "Return string" must be the last "For string".

Thanks for help!

0 Kudos
1 Solution

Accepted Solutions
Nicholas-Furness
Esri Regular Contributor

Swift doesn't have an async keyword, so you'll need to structure your function not to return a string, but instead to require a callback block. Something like this:

func getValueSum(geo : AGSGeometry, completion: @escaping (String)->Void) {
    let queryParameters = AGSQueryParameters()
    queryParameters.geometry = geo
    queryParameters.spatialRelationship = AGSSpatialRelationship.intersects
    queryParameters.outSpatialReference = self.mapView.spatialReference
    
    self.featureTable?.queryFeatures(with: queryParameters, completion: { (result: AGSFeatureQueryResult?, error: Error?) in

        var strReturn = ""

        if error != nil {
            print("Error in function")
        } else if let features = result?.featureEnumerator().allObjects {
            for feature in features {
                strReturn += "\(feature.attributes["Label1"]!); "
                print("For string: \(strReturn)")
            }
        }
        
        completion(strReturn)
    })
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
// Call like this, and do operations on the result in the callback block…
getValueSum(geo: geometry) { allLabels in
    print("Got all the labels: \(allLabels)")
}

View solution in original post

0 Kudos
2 Replies
Nicholas-Furness
Esri Regular Contributor

Swift doesn't have an async keyword, so you'll need to structure your function not to return a string, but instead to require a callback block. Something like this:

func getValueSum(geo : AGSGeometry, completion: @escaping (String)->Void) {
    let queryParameters = AGSQueryParameters()
    queryParameters.geometry = geo
    queryParameters.spatialRelationship = AGSSpatialRelationship.intersects
    queryParameters.outSpatialReference = self.mapView.spatialReference
    
    self.featureTable?.queryFeatures(with: queryParameters, completion: { (result: AGSFeatureQueryResult?, error: Error?) in

        var strReturn = ""

        if error != nil {
            print("Error in function")
        } else if let features = result?.featureEnumerator().allObjects {
            for feature in features {
                strReturn += "\(feature.attributes["Label1"]!); "
                print("For string: \(strReturn)")
            }
        }
        
        completion(strReturn)
    })
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
// Call like this, and do operations on the result in the callback block…
getValueSum(geo: geometry) { allLabels in
    print("Got all the labels: \(allLabels)")
}
0 Kudos
HaiLe_Hong
New Contributor

Thank you Nicholas Furness!

0 Kudos