Giter VIP home page Giter VIP logo

Comments (23)

yo1995 avatar yo1995 commented on June 6, 2024 1

@yo1995 thank you.

I tried using the mapId with login and without login it did not work.

I will look into the samples and hope to find something we need.

Sure. Please feel free to reopen this issue if you've more questions, and I'll get you posted when I receive feedback regarding the AGSWebMap class.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024 1

Thanks guys it worked: I used

        let cred = AGSCredential(user: _userName_, password: _password_)
        let portal = AGSPortal.arcGISOnline(withLoginRequired: true)
        portal.credential = cred
        let portalItem = AGSPortalItem(portal: portal, itemID: _mapId_)
        let map = AGSMap(item: portalItem)
        mapView.map = map

If I have token from service and want to use AGSCredential(token: String, referer: String) what should be the value of referer?

from arcgis-runtime-samples-ios.

yo1995 avatar yo1995 commented on June 6, 2024

Hi @aliawais , I'm not quite sure about your problem. Can you try to load a webmap with its portal item ID? e.g.

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

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

Is portalItemId different from MapId?

Is there a complete sample using this approach and also showing/hiding available layers?

from arcgis-runtime-samples-ios.

yo1995 avatar yo1995 commented on June 6, 2024

Is portalItemId different from MapId?

I think they are the same thing.

Is there a complete sample using this approach and also showing/hiding available layers?

You may take a look at

for some inspirations.

AFAIK there isn't a sample that demonstrates the workflow to load multiple layers from ArcGIS Online and control their visibility. I also asked our team to see if they have suggestions.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

@yo1995 thank you.

I tried using the mapId with login and without login it did not work.

I will look into the samples and hope to find something we need.

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

@aliawais You could take a look at this sample: https://developers.arcgis.com/ios/latest/swift/sample-code/open-map-url/

That takes the URL to the item page for a web map in ArcGIS and opens it. Does that help?

from arcgis-runtime-samples-ios.

yo1995 avatar yo1995 commented on June 6, 2024

As Nick indicated - In addition, consider taking a look at these 2 samples:

Hope it helps.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

Thanks @nixta and @yo1995 will definitely have a look into these.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

@nixta @yo1995
Hi guys,

I am loading the map using follwing:

let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map

where agsCredential are created using a token from API and referer that the app sends in request. The login popup still shows up for "You need to sign in to access www.arcgis.com"

If I add another portal (not used afterwards) as follows before the above code it works to load layers and map.

let arcGISPortal = AGSPortal.arcGISOnline(withLoginRequired: true)
            arcGISPortal.credential = agsCredential
            arcGISPortal.load { (error) in
                if let _ = error {
                    print("Failed loading/signing to acrGISOnline")
                }
            }

But when I try to fetch basemaps using code below it shows login popup again but to sign in to portal.

        portal.load { (error) in
            if error == nil {
                portal.fetchBasemaps { (basemaps, err) in
                
            }
        }

If I create agsCredential using username and password, then it works fine without creating the extra portal with let arcGISPortal = AGSPortal.arcGISOnline(withLoginRequired: true)

I would need help in sorting the above using the token and referer, secondly how to authenticate for multiple paths e.g. portalURL/portal and portalURL/server/rest...

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

@nixta @yo1995
Hi guys,

I am loading the map using follwing:

let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map

What is the portalURL? And please provide details on how you’re getting the token.

Building a credential using the token is a less common approach (and you should use the AGSAuthenticationManager challengeHandler pattern if you’re doing that, for seamless token refreshes).

It sounds to me like you might be getting a token from one portal and using it on another.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

Hi @nixta @yo1995

Before loading a map, the app makes calls one of our APIs and we pass a 'referer' in header. The API uses ESRI/ArcGIS service to obtain a token for the provided referer. Then API returns us a mapId, portalURL, token, tokenExpiry. The same API is used by our front-end (web).

JSON format of response:
{
"gisBaseUrl": "portalURL",
"token": {
"token": "",
"expires": 1606815960364,
"ssl": true
},
"authRequiredPaths": [
"/portal",
"/server/rest/services"
],
"gisPortalPath": "/portal",
"defaultWebMapId": "mapId"
}

One suggestion from we developer was that they also sign in to authRequiredPaths as it might be casing issue, how to do that?

The portalURLs (gisBaseURL) could be one of the following format:

Then use the portal URL and

agsCredential = AGSCredential(token: portalToken, referer: referer)
let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map
        map.load { (error) in 
              // handle error or handle successfully loaded map
              // load base maps
}

I tried one thing with AGSAuthenticationManager, after getting token from our API, set AGSAuthenticationManager.shared().delegate to self and then in one of the delegates did following:

func authenticationManager(_ authenticationManager: AGSAuthenticationManager, didReceive challenge: AGSAuthenticationChallenge) {
        agsCredential?.token = esriAuthViewModel.portalToken()
        challenge.continue(with: agsCredential)
    }

The strange thing I noticed was that agsCredential is class level variable, and its token was getting null.

So I need to use the token from our API and dont want to show the authentication challenge popup, if there any implementation suggestion please provide, can you also please refer to a proper implementation of using AGSAuthenticationManager.

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

There is a lot going on here, and it's not really relevant to this repo. Might be worth picking the conversation up over at the iOS Runtime forum. But…

Firstly, a token obtained for https://atlas.{client Name}.com (which, by the looks of things, is an on-premise ArcGIS Enterprise instance) will not work at https://{client Name}.maps.arcgis.com. And vice-versa.

agsCredential must be something in your codebase. Not sure what that is or how it's created. You can look at the proposedCredential that is passed to the challengeHandler. Set the token on that. However, you still want to make sure that the token was generated for the right service/portal.

You might find some useful info here too.

You appear to be using challengeHandler correctly, btw. Just not sure if passing back agsCredential is a good thing since we don't know what it is or where it comes from in your codebase.

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

What is the URL that is being used to generate the token?

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

It could also be that the token is expired. If you use the username and password, Runtime will automatically get a new token if the old one expires.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

@nixta

Token is generated for each portal when it changes. The URL for one of them is
https://atlas.{clientName}.com/portal/sharing/rest/generateToken

The token is generated at time app make the call to our API, and its has an expiry of 24hours.

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

@nixta

Token is generated for each portal when it changes. The URL for one of them is
https://atlas.{clientName}.com/portal/sharing/rest/generateToken

The token is generated at time app make the call to our API, and its has an expiry of 24hours.

Then in the code above:

let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map

what is the portalURL? If it's not atlas.{clientName}.com or if the token was not obtained using credentials that authorize access to the mapId web map, then the credential will not work and you will be prompted.

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

The token is generated for that portalURL which we get in the response and the mapId is associated with that token and portal.

The thing is when create agsCredetails using user name and password it works fine. Can you please link me to the sample using the Authentication manager.

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

Unfortunately we don't have an AuthenticationManager sample that covers using credentials with token.

One thought. You said this:

I am loading the map using follwing:

let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map

where agsCredential are created using a token from API and referer that the app sends in request. The login popup still shows up for "You need to sign in to access www.arcgis.com"

If I add another portal (not used afterwards) as follows before the above code it works to load layers and map.

let arcGISPortal = AGSPortal.arcGISOnline(withLoginRequired: true)
            arcGISPortal.credential = agsCredential
            arcGISPortal.load { (error) in
                if let _ = error {
                    print("Failed loading/signing to acrGISOnline")
                }
            }

Is agsCredential the same when applied to both portals?

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

I used that approach for portal https://{client Name}.maps.arcgis.com, and the agsCredential was same for arcGISOnline(withLoginRequired: true)

For portal https://atlas.{client Name}.com it works without the extra AGSPortal.arcGISOnline(withLoginRequired: true).
At one time I using one portalURL and one mapId, for simplicity if UserA logs in to the app we use https://atlas.{client Name}.com and if UserB logs in we use https://atlas.{client Name}.com

from arcgis-runtime-samples-ios.

nixta avatar nixta commented on June 6, 2024

To confirm:

This does NOT work:

Display a map from https://{client Name}.maps.arcgis.com.

// portalURL = https://{client Name}.maps.arcgis.com
// agsCredential is a token obtained from www.arcgis.com
let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map

This DOES work:

Display a map after loading the www.arcgis.com portal with a separate credential first:

// agsCredential is obtained from www.arcgis.com
let arcGISPortal = AGSPortal.arcGISOnline(withLoginRequired: true)
            arcGISPortal.credential = agsCredential
            arcGISPortal.load { (error) in
                if let _ = error {
                    print("Failed loading/signing to acrGISOnline")
                }
            }
// portalURL = https://{client Name}.maps.arcgis.com
// agsCredential is the same as above
let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.credential = agsCredential
        let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
        let map = AGSMap(item: portalItem)
        esriMapView.map = map

Is that correct? That's what I understood from #1012 (comment)

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

yes

from arcgis-runtime-samples-ios.

aliawais avatar aliawais commented on June 6, 2024

Posting my solution here, may its helpful for others.

Once our API returns the token it generated from ARCGisPortal, the controller sets its self as delegate to following AGSAuthenticationManager.shared().delegate = self

AGSPortal is created without setting its AGSCredential property and I do following:

let portal = AGSPortal(url: portalURL, loginRequired: true)
        portal.load { (error) in
            if let _ = error {
                self.delegate?.mapLoadingFailed()
            } else {
                let portalItem = AGSPortalItem(portal: portal, itemID: mapId)
                self.loadWebMap(portalItem: portalItem)
                self.loadBaseMaps(portal: portal)
            }
        }

Following is how I have handled one of the delegate methods

func authenticationManager(_ authenticationManager: AGSAuthenticationManager, didReceive challenge: AGSAuthenticationChallenge) {
            // creating credentials from token returned from our API
            let agsCredentials = AGSCredential(token: credentialToken, referer: referer)
            challenge.continue(with: agsCredentials)
        }
    }

So now whenever the credentials challenge is received, the method continue with the AGSCredentials.

from arcgis-runtime-samples-ios.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.