A short while ago we released the next generation of ArcGIS Runtime SDKs for iOS, macOS, Android, Java, Qt and .Net. It is the first time we were able to release all the SDKs at the same time and with the same set of functionality. This was possible because the Runtime SDKs were rebuilt from the ground up using a completely new architecture and introduce a number of new concepts, patterns, and capabilities that are common to all the SDKs. We’re very excited for you to try out this latest version (v100.0) and you can read more about its new and notable features in the Release Notes. In this post we will outline how you can migrate your existing iOS apps to the latest version of ArcGIS Runtime.
Version 100.0 has a number of changes from the previous 10.x line of releases, far too many to compile an exhaustive list, but in this post I will provide an overview of some of those changes so that it can guide your migration efforts. The changes were necessary to accommodate an ambitious agenda of new capabilities such as visualizaiton of 3D scenes, direct read and processing of local rasters, new data formats such as mobile map packages and vector tiles, and many more yet to come, but most importantly, to more closely unify all the different SDKs to have a common conceptual design and similar programming patterns to help many of you who are involved in building apps on multiple development platforms.
Before you migrate
Even though v100.0 is packed with a lot of new capabilities, unfortunately it does not provide all the functionality that was available with 10.2.x at this time. We are working hard to add the missing pieces with subsequent releases and our goal is to achieve full functional parity later this year. So before you begin migrating existing apps to v100.0, you should refer to choosing the right version to see if the current release contains all the functionality your existing apps require. If not, don’t worry. We have extended the support lifecycle for version 10.2.x so that you can continue to use it until equivalent functionality is available in the latest releases.
Overview of changes
AGSWebMap and its related classes that used to represent a web map have been removed. A web map is now represented by AGSMap which can have a variety of sources. This makes working with maps simple and consistent regardless of where it originates from, be it on a remote ArcGIS portal, inside a mobile map package (.mmpk file) on disk, or even it is only in memory that has been programmatically created by combining layers and a basemap.
In general, layers do not automatically load their metadata asynchronously and they no longer have a delegate (AGSLayerDelegate) that is notified when the layer is initialized or when it fails to load. Rather, layers now follow the loadable pattern (AGSLoadable) that is used to explicitly load their metadata and monitor their load status. Refer to the loadable pattern topic for more information.
AGSDynamicMapServiceLayer has been renamed to AGSArcGISMapImageLayer. Sublayer visibility is now controlled by removing or adding sublayers to the mapImageSublayers array.
AGSTiledServiceLayer and AGSLocalTiledLayer have been combined into a single AGSArcGISTiledLayer that can display tiles from a remote ArcGIS Tile Service or a local tile cache (AGSTileCache).
AGSFeatureLayer no longer connects directly to a feature service. Rather, it requires a feature table which contains the feature data to be displayed by the layer. The query and editing capabilities of the layer are now performed on the table instead. For offline scenarios, you can use an AGSGeodatabaseFeatureTable that represents data in a local geodatabase on disk, and for connected scenarios, you can use an AGSServiceFeatureTable which represents the feature data in a remote feature service. For cases when the data exists only in the app in memory and not on disk or in a remote service, you can use AGSFeatureCollectionTable.
AGSImageServiceLayer, AGSWMTSLayer, and AGSWMSLayer have been removed. They are being considered for a future release.
You can no longer add layers directly to the mapview. Instead, layers need to be added to a map which is then set on the mapview. To display graphics, you need to add a graphics overlay to the mapview containing those graphics. These graphics are displayed on top of all other map layers.
To programmatically navigate the mapview, you need to change its viewpoint using setViewpoint…() methods. AGSMapViewDidEndZoomingNotification and AGSMapViewDidEndPanningNotification notifications have been removed. To be informed when a user pans or zooms the maps, you can register a block with the viewpointChangedHandler.
To control which gestures and interactions are supported by the mapview, you can change its interactionOptions settings.
To be notified about touch events on the mapview, you need to set a touch delegate on the mapview. This delegate must conform to the AGSGeoViewTouchDelegate protocol which is a replacement of the previous AGSMapViewTouchDelegate protocol. The new delegate methods are similar to the old ones but there are some minor name changes. You must implement these delegate methods with the correct signatures to be sure they are invoked. Also, the touch events no longer automatically return the graphics or features that were hit-tested at the touch location. You need to manually perform the hit-testing in the touch event handler using identifyGraphicsOverlay…() or identifyLayer…() methods on the mapview.
AGSMapViewLayerDelegate has been removed. As a replacement for mapViewDidLoad() delegate method, you can monitor the mapview’s spatialReference property to know when it is fully initialized to display its map contents. The other delegate methods are no longer relevant as the mapview does not perform automatic hit-testing of features/graphics on touch events as described above.
AGSMapViewCalloutDelegate has been removed. The mapview no longer automatically displays or dismisses the callout when a user taps on graphics or features the map. You are responsible for displaying and dismissing the callout by listening to the touch events.
The mapview no longer automatically displays or dismisses the callout when a user taps on graphics or features on the map. You are responsible for displaying and dismissing the callout by listening to the touch events and hit-testing for graphics or features using identifyGraphicsOverlay…() or identifyLayer…() methods on the mapview.
AGSHitTestable, AGSInfoTemplateDelegate and AGSLayerCalloutDelegate have also been removed for the same reason.
Graphics Layer (AGSGraphicsLayer) has been replaced by Graphics Overlay (AGSGraphicsOverlay). Graphics need to be added to a graphics overlay instead of a graphic layer. Graphics Overlays display graphics on top of all other layers in a map. They cannot be interleaved with other layer like was the case with Graphics Layers.
If you want to interleave your own data with the map layers, consider using a feature collection layer (AGSFeatureCollectionLayer) instead of graphics overlays. A feature collection layer displays data in a feature collection which contains features organized into individual feature collection tables. You can create one of these feature collection tables in memory and add your feature data to it.
Sketch Layer (AGSSketchGraphicsLayer) has been replaced by Sketch Editor (AGSSketchEditor). A sketch editor needs to be set on the mapview and then started to begin creating or modifying a sketch.
The AGSSketchGraphicsLayerGeometryDidChangeNotification notification has been replaced with AGSSketchEditorGeometryDidChangeNotification
Mutable geometries (AGSMutablePoint, AGSMutableEnvelope, AGSMutablePolygon, AGSMutablePolyline, AGSMutableMultipoint) have been replaced with geometry builders – AGSPointBuilder, AGSEnvelopeBuilder, AGSPolygonBuilder, AGSPolylineBuilder, AGSMultipointBuilder.
Instance methods on geometry engine (AGSGeometryEngine) have been changed to static class methods.
Geodatabase Sync Task (AGSGDBSyncTask) has been renamed to AGSGeodatabaseSyncTask. Also, the asynchronous operations to generate new a geodatabase and sync an existing geodatabase now return a job handle (AGSGenerateGeodatabaseJob, and AGSSyncGeodatabaseJob) to represent the execution on the service. The job has to be explicitly started to initiate the processing on the service and it also provides the results of the execution in the completion block.
Export Tile Cache Task (AGSExportTileCacheTask) also returns a job handle (AGSExportTileCacheJob, and AGSEstimateTileCacheSizeJob) for the asynchronous operations to generate a tile cache and estimate the tile cache size. The job has to be explicitly started to initiate the processing on the service and it also provides the results of the execution in the completion block.
Geometry Service Task (AGSGeometryServiceTask) has been removed. Use AGSGeometryEngine instead.
Query Task (AGSQueryTask) has been removed. Use the query…() methods on AGSServiceFeatureTableinstead.
Identify Task (AGSIdentifyTask) has been removed. Use identifyGraphicsOverlay…() or identifyLayer…() methods on AGSMapView instead.
Locator (AGSLocator) has been renamed to AGSLocatorTask. AGSLocatorDelegate has been removed and replaced with completion blocks on the locator task’s asynchronous operations that previously required the delegates.
AGSRouteTaskDelegate has been removed and replaced with completion blocks on the route task’s asynchronous operations that previously required the delegates.
Geoprocessor (AGSGeoprocessor) has been renamed to AGSGeoprocessingTask. The asynchronous operations to perform the geoprocessing function returns a job handle (AGSGeoprocessingJob). The job has to be explicitly started to submit it to the service and it also provides the results of the execution in the completion block. The AGSGeoprocessorDelegate has been removed and replaced with completion blocks on the job’s asynchronous operations.
Find Task (AGSFindTask), Closest Facility Task, (AGSClosestFacilityTask), Service Area Task (AGSServiceAreaTask) have been removed. They are being considered for a future release.
The following delegates have been removed – AGSPortalDelegate, AGSPortalGroupDelegate, AGSPortalInfoDelegate, AGSPortalItemDelegate, AGSPortalUserDelegate. They have been replaced with completion blocks on the corresponding asynchronous operations that required the delegates.
AGSPortal, AGSPortalItem, and AGSPortalUser classes implement the loadable pattern (AGSLoadable)which means they must be loaded for their information to be available.
The following notifications have been removed. The AGSLoadable protocol provides mechanisms to monitor the loadStatus of AGSPortal
Performing authentication has been re-architected around a central authentication manager (AGSAuthenticationManager) that issues challenges (AGSAuthenticationChallenge) when a resource (such as a layer or a task) attempts to access a secure service. Additionally, the SDK contains an in-built challenge handler that tries to resolve the challenge by displaying UI to solicit user details, but developers can choose to customize this behavior and handle challenges themselves by providing a delegate (AGSAuthenticationManagerDelegate).
AGSOAuthLoginViewController has been removed. To support oAuth based authentication in your app you need to set the app’s oAuth configuration (AGSOAuthConfiguration) on AGSAuthenticationManager. The configuration includes, among other things, a redirectURL which must use a custom URL scheme for the app. This will allow the user to sign in using an external Safari browser which offers more security as compared to performing the authentication in app. When the user finishes logging in through Safari, the app will be invoked and passed the credentials to access the resource. You will need to use AGSApplicationDelegate to handle this app invocation and complete the oAuth authentication workflow.
Like earlier, you have access to all the capabilities during development and testing, however the licensing model for deployment has changed to include 4 levels – Lite, Basic, Standard, and Advanced where each level unlocks a different set capabilities. You can license your app either by using a license key or a by logging into a portal with a named user. More details are available in the License your app topic.
The information above provides a high level overview of the changes between version 10.2.x and 100.0, but as you embark on migrating your apps, you may find yourself deep in the weeds needing more fine-grained, detailed information about how to change references to classes, methods or properties that have changed and no longer compile. We know that many of you borrow heavily from the SDK samples or use them as a starting point and build on it. So to ease your migration path a little and provide more detailed information, we’ve ported the most popular 10.2.x samples to the latest version of the SDK. You can download the diff and open it in Safari to see a simple side-by-side comparison of what code needed to be changed. The diff is searchable in Safari so you can look for specific classes, methods, or properties and quickly find the corresponding changes. We’ve also made the ported samples available for download in a branch on GitHub.
We hope this post is useful as you migrate to 100.0. Feel free to reach out to the community on the Geonet forum for any questions or to share your experience, we’ll be watching that space and there to help you along the way.