Unfortunately, the latest SDK lacks examples on caching tiles from a service. How do I use ExportTileCache on a service?
A complete example would be much appreciated.
This is the map I want to cache:
http://www.arcgis.com/home/item.html?id=226d23f076da478bba4589e7eae95952
From what I've read and understood, these are the steps I followed to use ExportTileCache:
1. Register app online
2. Setup AuthenticationManager with Server Info (client id, client secret, oauth2 settings)
3. register ServerInfo
4. Setup export cache parameters
5. Call ExportTileCache on the service
Upon calling ExportTileCache on the service I get the error 'Token required'. Shouldn't ExportTileCache initiate a challenge procedure from the service and in doing so get a token, all handled by the AuthenticationManager?
I am also unsure which URL should be used where. I assume the first URL(SERVICE_OFFLINE_URL) specified here is the URL that I should pass as the ServerUri to ServerInfo, and the fully qualified basemap url(BASEMAP_OFFLINE_URL) passed to ExportTileCache.CreateAsync. Am I correct?
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">const</SPAN> <SPAN class="keyword token">string</SPAN> SERVICE_OFFLINE_URL <SPAN class="operator token">=</SPAN> <SPAN class="string token"><SPAN>"</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Ftiledbasemaps.arcgis.com%2Farcgis%2Frest" target="_blank">https://tiledbasemaps.arcgis.com/arcgis/rest</A><SPAN>"</SPAN></SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">const</SPAN> <SPAN class="keyword token">string</SPAN> OTHER_URL <SPAN class="operator token">=</SPAN> <SPAN class="string token"><SPAN>"</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fwww.arcgis.com%2Fsharing%2Frest" target="_blank">https://www.arcgis.com/sharing/rest</A><SPAN>"</SPAN></SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">const</SPAN> <SPAN class="keyword token">string</SPAN> BASEMAP_OFFLINE_URL <SPAN class="operator token">=</SPAN> <SPAN class="string token"><SPAN>"</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Ftiledbasemaps.arcgis.com%2Farcgis%2Frest%2Fservices%2FWorld_Imagery%2FMapServer" target="_blank">https://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Imagery/MapServer</A><SPAN>"</SPAN></SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">const</SPAN> <SPAN class="keyword token">string</SPAN> OAUTH2_URN <SPAN class="operator token">=</SPAN> <SPAN class="string token">"urn:ietf:wg:oauth:2.0:oob"</SPAN><SPAN class="punctuation token">;</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">async</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">CreateTileCacheAsync</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
Envelope extent <SPAN class="operator token">=</SPAN>
<SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Envelope</SPAN><SPAN class="punctuation token">(</SPAN>
<SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">MapPoint</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">25.6129589203346</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">27.9394285297344</SPAN><SPAN class="punctuation token">,</SPAN> SpatialReferences<SPAN class="punctuation token">.</SPAN>Wgs84<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">MapPoint</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">26.1950346130634</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">29.2006589984844</SPAN><SPAN class="punctuation token">,</SPAN> SpatialReferences<SPAN class="punctuation token">.</SPAN>Wgs84<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Authentication<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Initialize</SPAN><SPAN class="punctuation token">(</SPAN>CLIENT_ID<SPAN class="punctuation token">,</SPAN> CLIENT_SECRET<SPAN class="punctuation token">,</SPAN> SERVICE_OFFLINE_URL<SPAN class="punctuation token">,</SPAN> OAUTH2_URN<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">var</SPAN> t <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> ExportTileCacheTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">CreateAsync</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Uri</SPAN><SPAN class="punctuation token">(</SPAN>BASEMAP_OFFLINE_URL<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> creds<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">var</SPAN> cacheParams <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> t<SPAN class="punctuation token">.</SPAN><SPAN class="token function">CreateDefaultExportTileCacheParametersAsync</SPAN><SPAN class="punctuation token">(</SPAN>extent<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">8000</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2000</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">var</SPAN> outFolder <SPAN class="operator token">=</SPAN> System<SPAN class="punctuation token">.</SPAN>AppDomain<SPAN class="punctuation token">.</SPAN>CurrentDomain<SPAN class="punctuation token">.</SPAN>BaseDirectory<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">var</SPAN> job <SPAN class="operator token">=</SPAN> t<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ExportTileCache</SPAN><SPAN class="punctuation token">(</SPAN>cacheParams<SPAN class="punctuation token">,</SPAN> outFolder <SPAN class="operator token">+</SPAN> <SPAN class="string token">"asdf.tpk"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">var</SPAN> result <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> job<SPAN class="punctuation token">.</SPAN><SPAN class="token function">GetResultAsync</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Debug<SPAN class="punctuation token">.</SPAN><SPAN class="token function">WriteLine</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"Tile Cache created at "</SPAN> <SPAN class="operator token">+</SPAN> result<SPAN class="punctuation token">.</SPAN>Path<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Debug<SPAN class="punctuation token">.</SPAN><SPAN class="token function">WriteLine</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"format: "</SPAN> <SPAN class="operator token">+</SPAN> result<SPAN class="punctuation token">.</SPAN>CacheStorageFormat<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>Authentication code:
The ChallengeHandler and OAuthAuthorizeHandler are taken from the sample code in the runtime samples Security section.
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">class</SPAN> <SPAN class="token class-name">Authentication</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">Initialize</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">string</SPAN> clientId<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">string</SPAN> clientSecret<SPAN class="punctuation token">,</SPAN> String serverUrl<SPAN class="punctuation token">,</SPAN> String redirectUrl<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
ClientId <SPAN class="operator token">=</SPAN> clientId<SPAN class="punctuation token">;</SPAN>
ClientSecret <SPAN class="operator token">=</SPAN> clientSecret<SPAN class="punctuation token">;</SPAN>
ServerUrl <SPAN class="operator token">=</SPAN> serverUrl<SPAN class="punctuation token">;</SPAN>
RedirectUrl <SPAN class="operator token">=</SPAN> redirectUrl<SPAN class="punctuation token">;</SPAN>
<SPAN class="token function">UpdateAuthenticationManager</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">string</SPAN> ClientId <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">string</SPAN> ClientSecret <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">string</SPAN> ServerUrl <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">string</SPAN> RedirectUrl <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">UpdateAuthenticationManager</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
Esri<SPAN class="punctuation token">.</SPAN>ArcGISRuntime<SPAN class="punctuation token">.</SPAN>Security<SPAN class="punctuation token">.</SPAN>ServerInfo serverInfo <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">ServerInfo</SPAN>
<SPAN class="punctuation token">{</SPAN>
ServerUri <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Uri</SPAN><SPAN class="punctuation token">(</SPAN>ServerUrl<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
OAuthClientInfo <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">OAuthClientInfo</SPAN>
<SPAN class="punctuation token">{</SPAN>
ClientId <SPAN class="operator token">=</SPAN> ClientId<SPAN class="punctuation token">,</SPAN>
RedirectUri <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Uri</SPAN><SPAN class="punctuation token">(</SPAN>RedirectUrl<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="operator token">!</SPAN><SPAN class="keyword token">string</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">IsNullOrEmpty</SPAN><SPAN class="punctuation token">(</SPAN>ClientSecret<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
serverInfo<SPAN class="punctuation token">.</SPAN>TokenAuthenticationType <SPAN class="operator token">=</SPAN> TokenAuthenticationType<SPAN class="punctuation token">.</SPAN>OAuthAuthorizationCode<SPAN class="punctuation token">;</SPAN>
serverInfo<SPAN class="punctuation token">.</SPAN>OAuthClientInfo<SPAN class="punctuation token">.</SPAN>ClientSecret <SPAN class="operator token">=</SPAN> ClientSecret<SPAN class="punctuation token">;</SPAN>
serverInfo<SPAN class="punctuation token">.</SPAN>TokenServiceUri <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Uri</SPAN><SPAN class="punctuation token">(</SPAN>TOKEN_SERVICE_URL<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">else</SPAN>
<SPAN class="punctuation token">{</SPAN>
serverInfo<SPAN class="punctuation token">.</SPAN>TokenAuthenticationType <SPAN class="operator token">=</SPAN> TokenAuthenticationType<SPAN class="punctuation token">.</SPAN>OAuthImplicit<SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
AuthenticationManager<SPAN class="punctuation token">.</SPAN>Current<SPAN class="punctuation token">.</SPAN><SPAN class="token function">RegisterServer</SPAN><SPAN class="punctuation token">(</SPAN>serverInfo<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
AuthenticationManager<SPAN class="punctuation token">.</SPAN>Current<SPAN class="punctuation token">.</SPAN>OAuthAuthorizeHandler <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">OAuthAuthorize</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
AuthenticationManager<SPAN class="punctuation token">.</SPAN>Current<SPAN class="punctuation token">.</SPAN>ChallengeHandler <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">ChallengeHandler</SPAN><SPAN class="punctuation token">(</SPAN>CreateCredentialAsync<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="comment token">// ...</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN> <SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">async</SPAN> Task<SPAN class="operator token"><</SPAN>Credential<SPAN class="operator token">></SPAN> <SPAN class="token function">CreateCredentialAsync</SPAN><SPAN class="punctuation token">(</SPAN>CredentialRequestInfo info<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
OAuthTokenCredential credential <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">try</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="comment token">// Create generate token options if necessary</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>info<SPAN class="punctuation token">.</SPAN>GenerateTokenOptions <SPAN class="operator token">==</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">)</SPAN>
info<SPAN class="punctuation token">.</SPAN>GenerateTokenOptions <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">GenerateTokenOptions</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// AuthenticationManager will handle challenging the user for credentials</SPAN>
credential <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> AuthenticationManager<SPAN class="punctuation token">.</SPAN>Current<SPAN class="punctuation token">.</SPAN><SPAN class="token function">GenerateCredentialAsync</SPAN><SPAN class="punctuation token">(</SPAN>
info<SPAN class="punctuation token">.</SPAN>ServiceUri<SPAN class="punctuation token">,</SPAN>
info<SPAN class="punctuation token">.</SPAN>GenerateTokenOptions<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">as</SPAN> OAuthTokenCredential<SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">catch</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="token class-name">Exception</SPAN> ex<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">throw</SPAN> <SPAN class="punctuation token">(</SPAN>ex<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">return</SPAN> credential<SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>