Created
July 29, 2014 17:48
-
-
Save eito/e91d946815eb490da90e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AGSQueryTask.swift | |
// swift-samples | |
// | |
// Created by Eric Ito on 7/28/14. | |
// Copyright (c) 2014 Esri. All rights reserved. | |
// | |
import ArcGIS | |
// workaround for accessing closure wrapped in an enum | |
// https://devforums.apple.com/message/986308#986308 | |
struct Container<T> { | |
var closure: T | |
} | |
// this enum will have our closure types | |
enum QueryCallbackType { | |
case ExecuteClosure(Container<(featureSet: AGSFeatureSet?, error: NSError?) -> ()>) | |
case ExecuteWithIDsClosure(Container<(objectIDs: [Int]?, error: NSError?) -> ()>) | |
case ExecuteWithRelatedFeaturesClosure(Container<(relatedFeatures: [Int:[AGSFeatureSet]]?, error: NSError?) -> ()>) | |
case ExecuteFeatureCountClosure(Container<(featureCount: Int?, error: NSError?) -> ()>) | |
} | |
enum QueryResultsType { | |
case Execute((AGSFeatureSet?, NSError?)) | |
case ExecuteWithIDs(([Int]?, NSError?)) | |
case ExecuteWithRelatedFeatures(([Int:[AGSFeatureSet]]?, NSError?)) | |
case ExecuteFeatureCount((Int?, NSError?)) | |
} | |
extension AGSQueryTask: AGSQueryTaskDelegate { | |
// create a private struct to hold our Dictionary | |
private struct Static { | |
static var instance: [Int:QueryCallbackType]! = nil | |
static var token: dispatch_once_t = 0 | |
} | |
// this will map our operation to our callback | |
var callbacks: [Int:QueryCallbackType]! { | |
get { | |
dispatch_once(&Static.token) { Static.instance = [Int:QueryCallbackType]() } | |
return Static.instance! | |
} | |
set { | |
Static.instance = newValue | |
} | |
} | |
public func executeQuery(query: AGSQuery, withCompletion completion: (featureSet: AGSFeatureSet?, error: NSError?) -> ()) -> NSOperation? { | |
// get callbacks so we can call completion | |
self.delegate = self | |
let op = self.executeWithQuery(query) | |
if var cbs = self.callbacks { | |
cbs[op.hash] = .ExecuteClosure(Container(closure: completion)) | |
self.callbacks = cbs | |
} | |
return op | |
} | |
public func executeForIDsWithQuery(query: AGSQuery, withCompletion completion:(objectIDs: [Int]?, error: NSError?) -> ()) -> NSOperation? { | |
self.delegate = self | |
let op = self.executeForIdsWithQuery(query) | |
if var cbs = self.callbacks { | |
cbs[op.hash] = .ExecuteWithIDsClosure(Container(closure: completion)) | |
self.callbacks = cbs | |
} | |
return op | |
} | |
public func executeWithRelationshipQuery(query: AGSRelationshipQuery, withCompletion completion:(relatedFeatures: [Int: [AGSFeatureSet]]?, error: NSError?) -> ()) -> NSOperation! { | |
self.delegate = self | |
let op = self.executeWithRelationshipQuery(query) | |
if var cbs = self.callbacks { | |
cbs[op.hash] = .ExecuteWithRelatedFeaturesClosure(Container(closure: completion)) | |
self.callbacks = cbs | |
} | |
return op | |
} | |
public func executeFeatureCountWithQuery(query: AGSQuery, withCompletion completion:(count: Int?, error: NSError?) -> ()) -> NSOperation! { | |
self.delegate = self | |
let op = self.executeFeatureCountWithQuery(query) | |
if var cbs = self.callbacks { | |
cbs[op.hash] = .ExecuteFeatureCountClosure(Container(closure: completion)) | |
self.callbacks = cbs | |
} | |
return op | |
} | |
// MARK: AGSQueryTaskDelegate | |
// TODO: Why do we have to mark these delegate methods public?? | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didExecuteWithFeatureSetResult featureSet: AGSFeatureSet!) { | |
fireCallbackForOperation(op, resultType: .Execute((featureSet, nil))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didFailWithError error: NSError!) { | |
fireCallbackForOperation(op, resultType: .Execute((nil, error))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didExecuteWithObjectIds objectIds: [AnyObject]!) { | |
fireCallbackForOperation(op, resultType: .ExecuteWithIDs((objectIds as? [Int], nil))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didFailQueryForIdsWithError error: NSError!) { | |
fireCallbackForOperation(op, resultType: .ExecuteWithIDs((nil, error))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didExecuteWithRelatedFeatures relatedFeatures: [NSObject : AnyObject]!) { | |
fireCallbackForOperation(op, resultType: .ExecuteWithRelatedFeatures((relatedFeatures as? [Int:[AGSFeatureSet]], nil))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didFailRelationshipQueryWithError error: NSError!) { | |
fireCallbackForOperation(op, resultType: .ExecuteWithRelatedFeatures((nil, error))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didExecuteWithFeatureCount count: Int) { | |
fireCallbackForOperation(op, resultType: .ExecuteFeatureCount((count, nil))) | |
} | |
public func queryTask(queryTask: AGSQueryTask!, operation op: NSOperation!, didFailQueryFeatureCountWithError error: NSError!) { | |
fireCallbackForOperation(op, resultType: .ExecuteFeatureCount((nil, error))) | |
} | |
// MARK: Private | |
private func fireCallbackForOperation(operation: NSOperation, resultType: QueryResultsType) { | |
switch resultType { | |
case .Execute(let (featureSet, error)): | |
fireCallbackForOperation(operation, values: (featureSet, error)) | |
case .ExecuteWithIDs(let (objectIDs, error)): | |
fireCallbackForOperation(operation, values: (objectIDs, error)) | |
case .ExecuteWithRelatedFeatures(let (relatedFeatures, error)): | |
fireCallbackForOperation(operation, values: (relatedFeatures, error)) | |
case .ExecuteFeatureCount(let (count, error)): | |
fireCallbackForOperation(operation, values: (count, error)) | |
} | |
} | |
private func fireCallbackForOperation(operation: NSOperation, values: (Any?, Any?)) { | |
if var cb = self.callbacks { | |
if let callbackType = self.callbacks[operation.hash] as? QueryCallbackType { | |
switch callbackType { | |
case .ExecuteClosure(let container): | |
let (featureSet, error) = values | |
container.closure(featureSet: featureSet as? AGSFeatureSet, error: error as? NSError) | |
case .ExecuteWithIDsClosure(let container): | |
let (objectIDs, error) = values | |
container.closure(objectIDs: objectIDs as? [Int], error: error as? NSError) | |
case .ExecuteWithRelatedFeaturesClosure(let container): | |
container.closure(relatedFeatures: values.0 as? [Int:[AGSFeatureSet]], error: values.1 as? NSError) | |
case .ExecuteFeatureCountClosure(let container): | |
container.closure(featureCount: values.0 as? Int, error: values.1 as? NSError) | |
} | |
cb[operation.hash] = nil | |
self.callbacks = cb | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment