Access services with OAuth credentials

Learn how to implement user authentication to access a secure ArcGIS service with OAuth credentials.

Overview of how to access a secure ArcGIS service with OAuth credentials.

You can use different types of authentication to access secured ArcGIS services. To implement OAuth credentials for user authentication, you can use your ArcGIS account to register an app with your portal and get a Client ID, and then configure your app to redirect users to login with their credentials when the service or content is accessed. This is known as user authentication. If the app uses premium ArcGIS Online services that consume credits, for example, the app user's account will be charged.

In this tutorial, you will build an app that implements user authentication using OAuth credentials so users can sign in and be authenticated through ArcGIS Online to access the ArcGIS World Traffic service.

Prerequisites

Before starting this tutorial:

  1. You need an ArcGIS Location Platform or ArcGIS Online account.

  2. Your system meets the system requirements.

Set up authentication

To access the secure ArcGIS location services used in this tutorial, you must implement user authentication using an ArcGIS Location Platform or an ArcGIS Online account.

Create a new OAuth credential to access the secured resources used in this tutorial.

  1. Complete the Create OAuth credentials for user authentication tutorial.

  2. Copy and paste the ClientID and RedirectURL into a safe location. They will be used in a later step.

All users that access this application need account privileges to access the basemap styles service.

Develop or Download

You have two options for completing this tutorial:

  1. Option 1: Develop the code or
  2. Option 2: Download the completed solution

Option 1: Develop the code

Create a new app

To get started, use Xcode to create an iOS app and configure it to reference the API.

  1. Open Xcode. In the menu bar, click File > New > Project.

    • In the Choose a template for your new project: window, set the following properties:
      • Multiplatform iOS
      • Application App
    • Click Next.
    • In the Choose options for your new project: window, set the following properties:
      • Product Name: <your app name>
      • Organization Identifier: <your organization>
      • Interface: SwiftUI
      • Language: Swift
    • Uncheck all other options.
    • Click Next.
    • Choose a location to store your project. Click Create.
  2. In the Project Navigator, click <your app name>App. In the Editor, right click on the struct name, <your app name>App. Select Refactor > Rename... to rename the struct to MainApp. Click the Rename button in the top right to confirm the new name. This will rename the struct and file in all affected areas.

  3. Add a reference to the API using Swift Package Manager.

  4. In the MainApp.swift file, some errors may appear after importing ArcGIS. Resolve the errors by distinguishing the Scene protocol from Scene. To do so, add the SwiftUI prefix to Scene.

    MainApp.swift
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        var body: some SwiftUI.Scene {
    
            WindowGroup {
                ContentView()
    
            }
        }
    

Add a protected layer to map

Add the World Traffic layer to the map.

  1. In the Project Navigator, click ContentView.swift.

  2. In the Editor, add an import statement to reference the API.

    ContentView.swift
    Use dark colors for code blocks
    16 17 18 19
    Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    import SwiftUI
    
    import ArcGIS
    
    
  3. Add a Map with the @State property wrapper with a default value. Create a Map with an arcGISTopographic basemap style and an inital viewpoint and return it.

    ContentView.swift
    Use dark colors for code blocks
    22 23 24 25 26 27 28 29
    Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    struct ContentView: View {
    
        @State private var map = {
            let map = Map(basemapStyle: .arcGISTopographic)
            map.initialViewpoint = Viewpoint(latitude: 34.02700, longitude: -118.80500, scale: 72_000)
    
            return map
        }()
    
  4. Add a secured traffic layer to the map's operational layers collection.

    ContentView.swift
    Use dark colors for code blocks
    24 25 26 27 28 29 30 31 32 33
    Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
        @State private var map = {
            let map = Map(basemapStyle: .arcGISTopographic)
            map.initialViewpoint = Viewpoint(latitude: 34.02700, longitude: -118.80500, scale: 72_000)
    
            let trafficLayerURL = URL(string: "http://www.arcgis.com/home/item.html?id=ff11eb5b930b4fabba15c47feb130de4")!
            let trafficLayer = ArcGISMapImageLayer(url: trafficLayerURL)
            map.addOperationalLayer(trafficLayer)
    
            return map
        }()
    
  5. Replace the default code in the body to display the map. Create a MapView using the previously created map.

    ContentView.swift
    Use dark colors for code blocks
    35 36 37 38 39
    Change line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
        var body: some View {
    
            MapView(map: map)
    
        }
    
  6. Open the MainApp.swift file. Add the .ignoreSafeArea modifier to the ContentView. This modifier ensures that the map view is displayed beyond the safe area to all edges.

    MainApp.swift
    Use dark colors for code blocks
    49 50 51 52 53 54 55 56 57
    Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        var body: some SwiftUI.Scene {
    
            WindowGroup {
                ContentView()
    
                    .ignoresSafeArea()
    
            }
        }
    

Integrate OAuth credentials into your app

Use the ArcGIS Maps SDK for Swift Toolkit component to create an Authenticator object that handles authentication every time a secured ArcGIS resource is accessed.

  1. The Toolkit is required to access the Authenticator component. Follow the installation instructions to add Toolkit to the MainApp.swift file.

    MainApp.swift
    Use dark colors for code blocks
    16 17 18 19
    Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    import SwiftUI
    import ArcGIS
    
    import ArcGISToolkit
    
  2. Create an Authenticator object with the Observed Object property wrapper.

    MainApp.swift
    Use dark colors for code blocks
    23 24 25 26 27 28 29 30 31
    Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    struct MainApp: App {
    
        // Setup an `Authenticator` with OAuth configuration.
        @ObservedObject var authenticator = Authenticator(
            oAuthUserConfigurations: [
    
            ]
        )
    
    
  3. Initialize the Authenticator with an OAuthConfiguration object. Use your ClientID and RedirectURL credentials that you created in the Set up authentication step.

    MainApp.swift
    Use dark colors for code blocks
    25 26 27 28 29 30 31 32 33 34 35 36 37
    Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        // Setup an `Authenticator` with OAuth configuration.
        @ObservedObject var authenticator = Authenticator(
            oAuthUserConfigurations: [
    
                OAuthUserConfiguration(
                    // Enter OAuth credentials for user authentication.
                    portalURL: URL(string: "https://www.arcgis.com")!,
                    clientID: "<#YOUR-CLIENT-ID#>",
                    redirectURL: URL(string: "<#YOUR-REDIRECT-URL#>")!
                )
    
            ]
        )
    
  4. Create an initializer function and assign the authenticator to the ArcGISAuthenticationChallengeHandler. This points the challenge to the authenticator which will handle the request.

    MainApp.swift
    Use dark colors for code blocks
    23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
    Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    struct MainApp: App {
    
        // Setup an `Authenticator` with OAuth configuration.
        @ObservedObject var authenticator = Authenticator(
            oAuthUserConfigurations: [
    
                OAuthUserConfiguration(
                    // Enter OAuth credentials for user authentication.
                    portalURL: URL(string: "https://www.arcgis.com")!,
                    clientID: "<#YOUR-CLIENT-ID#>",
                    redirectURL: URL(string: "<#YOUR-REDIRECT-URL#>")!
                )
    
            ]
        )
    
        init() {
            ArcGISEnvironment.authenticationManager.arcGISAuthenticationChallengeHandler = authenticator
        }
    
    
  5. Lastly, display the OAuth interface. Add the authenticator view modifier, passing in the authenticator object.

    MainApp.swift
    Use dark colors for code blocks
    49 50 51 52 53 54 55 56 57 58 59
    Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        var body: some SwiftUI.Scene {
    
            WindowGroup {
                ContentView()
    
                    .authenticator(authenticator)
    
                    .ignoresSafeArea()
    
            }
        }
    
  6. Press Command+R to run the app.

Upon app launch, you will be prompted to log in with your ArcGIS Location Platform or ArcGIS Online credentials. Once you authenticate successfully, the basemap and traffic layer will appear in the map.

Manage data persistence

In real-world applications, you can create and persist a credential store in the keychain so that the user does not have to sign in again when the app is re-launched.

  1. Create an asynchronous function called setupPersistentCredentialStorage that sets up new credential stores that will be persisted to the keychain. Use the authenticationManager.setupPersistentCredentialStorage method to create the credential store and set the keychain access to whenUnlocked. This will allow the item to be accessible only when device is unlocked.

    MainApp.swift
    Use dark colors for code blocks
    39 40 41 42 43 44 45 46 47
    Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        init() {
            ArcGISEnvironment.authenticationManager.arcGISAuthenticationChallengeHandler = authenticator
        }
    
        private func setupPersistentCredentialStorage() async {
            Task {
                try await ArcGISEnvironment.authenticationManager.setupPersistentCredentialStorage(access: .whenUnlocked)
            }
        }
    
  2. Set up the credential stores upon app launch. Add a task function to ContentView. In the closure, call the setupPersistentCredentialStorage function.

    MainApp.swift
    Use dark colors for code blocks
    49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        var body: some SwiftUI.Scene {
    
            WindowGroup {
                ContentView()
    
                    .authenticator(authenticator)
    
                    .ignoresSafeArea()
    
                    .task {
                        await setupPersistentCredentialStorage()
                    }
    
            }
        }
    
  3. Press Command + R to run the app.

Upon app launch, you will not be prompted to log in again.

Alternatively, you can download the tutorial solution, as follows.

Option 2: Download the solution

  1. Click the Download solution link under Solution and unzip the file to a location on your machine.

  2. Open the .xcodeproj file in Xcode.

Since the downloaded solution does not contain authentication credentials, you must add the developer credentials that you created in the Set up authentication section.

Set developer credentials in the solution

  1. In the Project Navigator, click MainApp.swift.

  2. Enter your clientID and redirectURL values that you created earlier.

    MainApp.swift
    Expand
    Use dark colors for code blocks
    25 26 27 28 29 30 31 32 33 34 35 36 37
    Change lineChange lineChange lineChange lineChange lineChange line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
        // Setup an `Authenticator` with OAuth configuration.
        @ObservedObject var authenticator = Authenticator(
            oAuthUserConfigurations: [
    
                OAuthUserConfiguration(
                    // Enter OAuth credentials for user authentication.
                    portalURL: URL(string: "https://www.arcgis.com")!,
                    clientID: "<#YOUR-CLIENT-ID#>",
                    redirectURL: URL(string: "<#YOUR-REDIRECT-URL#>")!
                )
    
            ]
        )
    
    Expand

Best Practice: The OAuth credentials are stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.

Run the solution

Press Command + R to run the app.

Upon app launch, you will be prompted to log in with your ArcGIS Location Platform or ArcGIS Online credentials. Once you authenticate successfully, the basemap and traffic layer will appear in the map.

What's next?

Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.