Access services with OAuth 2.0

The following are required for this tutorial:

  1. An ArcGIS account to access your API keys. If you don't have an account, sign up for free.
  2. Your system meets the system requirements.
  3. The ArcGIS Runtime API for iOS is installed.

Steps

Configure OAuth 2.0 for your app

  1. Register your app to generate a client ID and set a redirect URI to access the secure service:

    Use this redirect URL when creating the OAuthConfiguration when iOS returns control back to your app after OAuth 2.0 login. If you change this value, you must change it every place it is referenced.

    If you attempt to spawn a login attempt from anywhere other than a white-listed location, the request will be denied.

    1. Sign in to your ArcGIS account. If you don't already have one, sign-up for free. You need to sign in so you can define an application and assign a client ID for authentication.
    2. At the top right of the main menu, click > New Application to create a new application.
    3. Fill in your application details and then select Register New Application. Take note of the Client ID value that is automatically assigned to your app.
    4. On the Authentication tab use the Redirect URIs section to add my-app://auth. Take note of the redirect URL you choose as you will need it later. Also note this URI is composed of two parts: a scheme (my-app), followed by a path (auth), separated with ://.

Set the app settings

  1. Add a new swift file to your Xcode project named AppConfiguration. You will use this to define a structure to hold configuration constants required by your app.

    • In Xcode's app menu, select File > New > File.
    • Select Swift File from the Source sub-menu.
    • Name the file AppConfiguration and ensure your app's target is checked.
    • Click create.
  2. Add the following struct to AppConfiguration.swift. When you enter this code, change "YOUR-APP-CLIENT-ID" to the Client ID you set in the application definition from the prior step. Update the URL scheme and path to match your Redirect URIs entry from the prior step.

           
    struct AppConfiguration {
        static let trafficLayerURL = URL(string: "https://traffic.arcgis.com/arcgis/rest/services/World/Traffic/MapServer")!
        static let clientID: String = "YOUR-APP-CLIENT-ID"
        static let urlScheme: String = "my-app"
        static let urlAuthPath: String = "auth"
        static let keychainIdentifier: String = "\(Bundle.main.bundleIdentifier!).keychainIdentifier"
    }
    
    • Replace the client_id and redirect_url values with the values shown on the authentication tab of your application definition.
  3. Open ViewController.swift and update the existing setupMap() method to add the traffic image layer to the map.

    The traffic layer is a premium service on ArcGIS Online, and requires an authenticated user to access it.

         
         mapView.map = AGSMap(basemapType: .navigationVector, latitude: 34.09042, longitude: -118.71511, levelOfDetail: 10)
    
         /*** ADD ***/
         let trafficLayer = AGSArcGISMapImageLayer(url: AppConfiguration.trafficLayerURL)
         mapView.map?.operationalLayers.add(trafficLayer)

At this point you can run and test your app. The basemap should load but the traffic layer will not load until you are able to use the AGSAuthenticationManager to log in a user and get a valid access token.

Integrate OAuth 2.0 into your app

  1. Configure a redirect URL scheme for your app. Right-click on info.plist file in the Project Navigator and then select Open As > / Source Code. Edit the file just after the opening top-level <dict> tag and add the following XML:

    Be sure to use your exact bundle identifier for your app.

    Use the scheme part of the Redirect URI you configured in the application definition, but without the path (everything before the ://). This is how OAuth 2.0 in iOS is able to return information about the authentication process back to your app. Note these strings must match exactly.

                   
    <dict>
        <!-- *** ADD *** -->
        <key>CFBundleURLTypes</key>
        <array>
          <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLName</key>
            <string>com.esri.your-bundle-identifier</string>
            <key>CFBundleURLSchemes</key>
            <array>
              <string>my-app</string>
            </array>
          </dict>
        </array>
  2. Open AppDelegate.swift to setup the AGSAuthenticationManager in your AppDelegate. This is done here because iOS will delegate control back to your with UIApplication.OpenURLOptionsKey once OAuth 2.0 completes. Import the ArcGIS library:

       
    import UIKit
    /*** ADD ***/
    import ArcGIS
  3. Create a new function to setup the authentication manager. This code creates a configuration with the parameters you assigned to your app in AppConfiguration and then assigns that configuration to the AGSAuthenticationManager. The credentials are also saved in the device's keychain..

    To construct the required redirectURL, combine the urlScheme and urlAuthPath from your AppConfiguration separated with ://.

         
     private func setupOAuthManager() {
         let config = AGSOAuthConfiguration(portalURL: nil, clientID: AppConfiguration.clientID, redirectURL: "\(AppConfiguration.urlScheme)://\(AppConfiguration.urlAuthPath)")
         AGSAuthenticationManager.shared().oAuthConfigurations.add(config)
         AGSAuthenticationManager.shared().credentialCache.enableAutoSyncToKeychain(withIdentifier: AppConfiguration.keychainIdentifier, accessGroup: nil, acrossDevices: false)
     }
    
  4. When OAuth 2.0 completes, iOS will return control back to your app using the Redirect URI. Here you ensure the inbound URL is your app's redirect URL. Use the AGSApplicationDelegate to open the inbound OAuth 2.0 redirect.

            
        func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
           if let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false),
               AppConfiguration.urlScheme == urlComponents.scheme,
               AppConfiguration.urlAuthPath == urlComponents.host {
               AGSApplicationDelegate.shared().application(app, open: url, options: options)
           }
           return true
        }
    
  5. Add a call to setupOAuthManager() from the application launch:

       
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         /*** ADD ***/
         setupOAuthManager()
    
  6. Press Command-R to run the app in the iOS Simulator.

    Other ways to run the project in Xcode:

    • In Xcode's app menu, select Product > Run.
    • Press the Run button at the top-left of the Xcode project window.

Congratulations, you're done!

Your app should open on your device then show a dialog from ArcGIS Online asking for OAuth 2.0 login. Once successfully logged in the map displays with the traffic layer added. Compare your solution with our completed solution project.