Is is possible to show layers that need to be authenticated while in offline?

167
6
3 weeks ago
ThomasKellough
New Contributor

I have a map with a set of layers consisting of two AGSVectorTiledLayers and seven AGSGroupLayers.

I currently authenticate by login in with a username and password. When I'm online, I have no problems viewing every set of layers.

However, there is one set of AGSGroupLayer that is only viewable AFTER you login. When I try to download the map for offline use, all layers and basemaps show up except the AGSGroupLayer that needs credentials. Is it possible to download this layer group for offline use or can it only be used while online?

For reference, I download the layers by using an offlineTileJob, offlineVectorTileJob, and AGSOfflineMapTask. I can post whatever code is needed, just want to know if it's possible to even do this. I felt like at one point I had these layers showing up offline, but I haven't been able to replicate it.

0 Kudos
6 Replies
Nicholas-Furness
Esri Regular Contributor

Hi.

Just to check a couple of things:

  1. Are the layers in the group layer enabled for taking offline? A group layer is just a container, so it's really authenticating the layers within the group layer that matters. Each of those layers should be offline enabled. If they're not enabled for offline use, then you can control what should happen with them using the onlineOnlyServicesOption on AGSGenerateOfflineMapParameters.
  2. Are there any errors being returned for those layers when taking the map offline? Take a look in the layerErrors property on the AGSGenerateOfflineMapResult.

From a permissions perspective, if you can authenticate to view the layer, and the layer is configured for offline use, then you should be good to go.

I will check whether GroupLayer is expected to work with offline maps (I think they should). You could try pulling the layers out of the group layer as a test. Group layers should work. I'd check that the layers are enabled for offline use. See the doc here for more info: https://doc.arcgis.com/en/arcgis-online/manage-data/take-maps-offline.htm#ESRI_SECTION1_C0331D55CAE1...

Update: You could also try the Capabilities Check and see what's supported.

0 Kudos
NikholaiO_Hara
Occasional Contributor

Hey Nicholas,

I am working with Thomas on this project.

We are pointing to a ArcGIS Online Web map that has some secured layers. We create the credentials for those layers to authenticate. The layers in question have the sync capability enabled and when you look at the settings of the web map in ArcGIS Online, the option to take the web map offline is available and enabled. One difference I found with the service that contains these layers is that it uses the PerReplica Sync model instead of the PerLayer Sync model. We have some other services that use the PerLayer Sync Model and those are working fine. With that in mind, when a layer has the PerReplica Sync model is there any extra overhead that needs to happen or something that we would be missing due to this?

0 Kudos
Nicholas-Furness
Esri Regular Contributor

It certainly sounds like everything's set up correctly.

When you get the AGSGenerateOfflineMapResult once the AGSGenerateOfflineMapJob completes, is hasErrors true? If so, what errors are provided in the layerErrors dictionary?

0 Kudos
ThomasKellough
New Contributor

I do get some errors after AGSGenerateOfflineMapJob completes, but they are not entirely helpful.

I'm using the example on the Arc GIS iOS Runtime Docs.

...
if let result = result {
    log.verbose("Finished downloading!: \(result)")
    if let layerErrors = result.layerErrors as? [AGSLayer: Error],
       let tableErrors = result.tableErrors as? [AGSFeatureTable: Error],
       !(layerErrors.isEmpty && tableErrors.isEmpty) {
        let errorMessages = layerErrors.map { "\($0.key.name): \($0.value.localizedDescription)" } +
        tableErrors.map { "\($0.key.displayName): \($0.value.localizedDescription)" }
        
        self.alertUserWithOKDismissal(title: "Offline Map Generated with Errors",
                     message: "The following error(s) occurred while generating the offline map:\n\n\(errorMessages.joined(separator: "\n"))")
    }
    completionHandler(true)
} else if let error = error {
    log.error("Error downloading the offline map: \(error)")
    completionHandler(false)
}
...

and I get the following...

ThomasKellough_0-1632777941398.png

 

 

0 Kudos
ThomasKellough
New Contributor

@Nicholas-Furness One thing I noticed that may be causing the issue is that I'm having trouble authenticating while offline. 

While online, I authenticate like this:

AGSAuthenticationManager.shared().delegate = self
func authenticationManager(_ authenticationManager: AGSAuthenticationManager, didReceive challenge: AGSAuthenticationChallenge) {
    let username = "USERNAME"
    let password = "PASSWORD"
    let credentials = AGSCredential(user: username, password: password)
    challenge.continue(with: credentials)
}

However, this delegate function never gets called while I'm loading an offline map. It's the same view controller that loads online/offline, so the delegate gets set no matter what.

When I'm loading an online map I use this code:

let portal = AGSPortal.arcGISOnline(withLoginRequired: false)
let itemId = portalItem.itemID
let portalItem = AGSPortalItem(portal: portal, itemID: itemId)
            
let map = AGSMap(item: portalItem)
mapView.map = map

 

And when loading offline map I use mobile map package like this:

let mobileMapPackage = AGSMobileMapPackage(fileURL: self.offlineMapUrl)
let tpkUrl = self.offlineMapUrl.absoluteString.replacingOccurrences(of: "gismap", with: "tpk")
var tileLayer: AGSArcGISTiledLayer?
if let tpkUrl = URL(string: tpkUrl) {
    tileLayer = AGSArcGISTiledLayer(url: tpkUrl)
}

mobileMapPackage.load { [weak self] (error) in
    self?.mapView.map = mobileMapPackage.maps.first
    self?.mapView.map?.operationalLayers.insert(tileLayer, at: 0)
    self?.delegate?.loadOfflineMapLayers()
}

 

When using a mobile map package is there another way we need to authenticate? I've tried caching the credentials to see if that helped but it did not.

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Hi Thomas.

When you're working with an already downloaded offline map, there's no authentication (authentication happens when accessing the services), so you won't see the Authentication Manager workflow in play.

Note, that has changed slightly as of 100.9, in that you can download an offline map that contains references to online layers which can be used if there's a network connection (e.g. traffic, or weather). However, that's not happening in this case.

0 Kudos