Workaround for hitTest:mapPoint error in ArcGIS Runtime SDK for iOS

1049
0
10-12-2017 02:53 PM
Labels (1)

Workaround for hitTest:mapPoint error in ArcGIS Runtime SDK for iOS

Summary:  

In order to prevent a crash bug in the ArcGIS Runtime SDK for iOS from impatient users tapping rapidly at startup, assign false to the main window's UserInteractionEnabled property until after the map finishes loading its last layer.

The Bug:

You may at some point have been frustrated with how long an elevator has taken to arrive, or crosswalk sign has taken to allow you to cross. Maybe you started pressing the button multiple times.  Out of our close to a thousand users, about thirty of them apparently had similar impatience with our app at startup, tapping the launch screen and then the initial mapView before it was done loading map layers.  If they tapped at least 8 times on the launch window, and then at least once on the mapView in the first second it appeared, a crash would happen within the ArcGIS Runtime SDK for iOS with the following message:

Fatal Exception: NSGenericException
*** Collection <__NSArrayM: 0x174e5b450> was mutated while being enumerated.

The function where this triggered was AGSMapViewBase hitTestPoint:mapPoint, one of the Esri libraries.

The stack trace.  HATS is the name of my application.:

0 CoreFoundation
__exceptionPreprocess
2 CoreFoundation
-[NSException name]
3 HATS -[AGSMapViewBase hitTestPoint:mapPoint:]
4 HATS -[AGSMapView singleTap]
5 UIKit
-[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:]
15 UIKit
UIApplicationMain
16 HATS AppDelegate.swift line 16
main

This bug kept cropping up in Crashlytics for a long time, but users claimed not to see any crashes.  Once I knew how to trigger this error on demand, I discovered that another thread was always busy loading layers into the map.  I have about 100 layers, all told containing about 500,000 features.  A threading race condition between the hitTestPoint handler thread and the thread loading map layers is likely needed to cause this error.  Multiple tests kept showing a different featureTable being loaded at the time of the crash.

Our app's data is loaded from an offline feature geodatabase that was generated from a feature service.  The map also had read-only layers already loaded from a second offline geodatabase containing our basemap layers exported from an ArcMap document.

The Workaround:

  1. When creating the first application window, set the main UIWindow's UserInteractionEnabled property to false.
  2. In your viewController where you have just finished loading your last layer into your mapView, insert code to set the main window's UserInteractionEnabled back to true. In our case this required Objective-C:

UIWindow *mainWindow = [[[UIApplication sharedApplication] windows] lastObject];

mainWindow.userInteractionEnabled = true;

Labels (1)
Version history
Last update:
‎10-12-2017 02:53 PM
Updated by:
Contributors