Basically, I want to set an ArcGIS account to access my API keys in IOS. If I don't have an account, it will sign me up for free. So far I have achieved this as follows:
I registered my app to generate a client ID and set a redirect URI to access the secure service. Then, I added a new swift file to my Xcode project named AppConfiguration.
I used that to define a structure to hold configuration constants required by my app.
Then I added the following struct to AppConfiguration.swift. When I enter this code, change "YOUR-APP-CLIENT-ID" to the Client ID I already set in the application definition from the prior step.
It will update the URL scheme and path to match my Redirect URIs entry from the prior step. Below is the code I used:
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"
}
After that I replaced the client_id and redirect_url values with the values shown on the authentication tab of my application definition.
Lastly, I opened ViewController.swift and update the existing setupMap() method to add the traffic image layer to the map.
After all this, at this point when I run and tested my app. The basemap should load but the traffic layer will not load. Any ideas what went wrong or what is missing?
CodePudding user response:
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
- 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 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>
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
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..
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)}
- 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 }
- Add a call to setupOAuthManager() from the application launch:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool { /*** ADD ***/ setupOAuthManager()
- Press Command-R to run the app in the iOS Simulator.