AnsweredAssumed Answered

How to create Programmatic Popups?

Question asked by Caleb1987 on Feb 17, 2016
Latest reply on May 30, 2016 by ozcandurak

This is my first attempt with the Runtime SDK for iOS with Swift (after finding the Qt Runtime SDK to be too buggy) and I have some questions regarding the workflow for creating programmatic popups.  All the code samples I have seen have used AGOL web maps rather than feature services directly.  So far, I just have a basic map with a map service and 2 feature layers that I need to make pop ups for.  I have set up the AGSPopupInfo's for each feature layer and am not sure what the rest of the workflow should look like.


My best guess is to call the queryFeatures() method from each feature layer and pass in a geometry from the map touch delegate.  From here, I am stuck as I do not know how to handle the query delegate and more specifically passing the operation returned from the query to the handler since it is outside the scope where the query operation is performed.  I think I should also be using the AGSPopupsContainer as well.  Is there a better or more appropriate workflow to accomplish this?


Does anyone have any code samples for how you have done programmatic popups for feature service layers (not AGOL web maps)?  This is the code I have so far but I am struggling:


import UIKit

import ArcGIS


let kBasemapLayerName = "Basemap Tiled Layer"

var isAdmin = false

let sightingFields = ["Visual_Cue", "Tree_Stress", "Knowledge_Level", "EAB_Found_On", "Comments", "Site_Description", "Latitude", "Longitude", "Site_Address", "Inspector_Name", "Email"]

let countyFields = ["CTY_NAME", "QUARANTINED"]


// MARK: reference feature layers

let countiesURL = NSURL(string: "")

let counties = AGSFeatureLayer(URL: countiesURL, mode: .Snapshot)


let sightingURL = NSURL(string: "")

let sightings = AGSFeatureLayer(URL: sightingURL, mode: .OnDemand)


class FirstViewController: UIViewController, AGSMapViewLayerDelegate, AGSCalloutDelegate, AGSMapViewTouchDelegate, AGSPopupsContainerDelegate {



    @IBOutlet weak var mapView: AGSMapView!

    var popupVC:AGSPopupsContainerViewController!


    override func viewDidLoad() {



        // MARK: set up map with default basemaps and feature layers

        let streetsURL = ""

        let tiledLayer = AGSTiledMapServiceLayer(URL: NSURL(string: streetsURL))

        self.mapView.addMapLayer(tiledLayer, withName: kBasemapLayerName)


        // mapview layer delegate

        self.mapView.layerDelegate = self

        self.mapView.touchDelegate = self


        // MDA EAB service

        let mneabURL = NSURL(string: "")

        let eabDynMS = AGSDynamicMapServiceLayer(URL: mneabURL)

        self.mapView.addMapLayer(eabDynMS, withName: "MDA EAB Service")


        // make counties transparent

        counties.opacity = 0.5


        self.mapView.addMapLayer(counties, withName: "Counties")

        self.mapView.addMapLayer(sightings, withName: "Sightings")


        //MARK: Feature Layer popups for sightings and counties

        // sightings


        let sightingPopupInfo = AGSPopupInfo(forFeatureLayer: sightings)

        sightingPopupInfo.showAttachments = true

        sightingPopupInfo.fieldInfos = sightingFields


        // counties

        let countyPopupInfo =  AGSPopupInfo(forFeatureLayer: counties)

        countyPopupInfo.fieldInfos = countyFields




    // MARK: query features from touch delegate for mapview

    func mapView(mapView: AGSMapView!, didClickAtPoint screen: CGPoint, mapPoint mappoint: AGSPoint!, features: [NSObject : AnyObject]!) {


        let geometryEngine = AGSGeometryEngine.defaultGeometryEngine()

        let buffer = geometryEngine.bufferGeometry(mappoint, byDistance:(10 * mapView.resolution))


        // query for sightings

        var querySightings = AGSQuery()

        querySightings.geometry = buffer

        querySightings.outFields = sightingFields



        // query for counties

        var queryCounties = AGSQuery()

        queryCounties.geometry = buffer

        queryCounties.outFields = countyFields

        var countyQueryOp = counties.queryFeatureCount(queryCounties)




    //  I am not sure how to do handle the query results and display popups from resulting features


    // MARK: handle query delegates (not sure how to pass operations from outside touch delegate scope)

    func featureLayer(featureLayer: AGSFeatureLayer!, op: NSOperation, didQueryFeaturesWithFeatureSet: AGSFeatureSet?) {






    // MARK: get user's location

    func mapViewDidLoad(mapView: AGSMapView!) {


        mapView.locationDisplay.autoPanMode = .Default

        mapView.locationDisplay.wanderExtentFactor = 0.75



    override func didReceiveMemoryWarning() {





    // MARK: switch basemaps

    @IBAction func basemapChanged(sender: UISegmentedControl) {

        var basemapURL: NSURL

        switch sender.selectedSegmentIndex {

        case 0: //streets

            basemapURL = NSURL(string: "")!

        case 1: // aerial

            basemapURL = NSURL(string: "")!

        default: //streets

            basemapURL = NSURL(string: "")!






        let newBasemapLayer = AGSTiledMapServiceLayer(URL: basemapURL)

        self.mapView.insertMapLayer(newBasemapLayer, withName: kBasemapLayerName, atIndex: 0)