POST
|
You still haven't mentioned what framework you are using. You should be able to inject the IEventAggregator into the View code behind. Prism will handle this. I have WPF and Xamarin Forms code that use this approach for events associated to View updates or actions public MobileAppMapView(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
InitializeComponent();
WireUpMapViewEventHandlers(eventAggregator);
SetupEventListeners(eventAggregator);
} I have not done this with a View using regions in Xamarin, because when I originally built out my Xamarin architecture Prism hadn't introduced Regions in Xamarin yet. But it should still work
... View more
11-02-2023
06:11 AM
|
1
|
4
|
1407
|
POST
|
You don't actually say what you are developing in. If you have Prism setup, I would use the CommandToEvent from Prism instead of the MAUI toolkit like Morten shows below. But basically same principle. As a rule if using Prism stick with all of their implementations, don't mix and match MAUI toolkit and Prism implementations Or you could just fire your own events, which is what I have done. You can inject IEventAggregator into the code behind that has the MapView . I create an Event for each of the MapView interactions and wire them up private void WireUpMapViewEventHandlers(IEventAggregator eventAggregator)
{
MapView.GeoViewTapped += (s, e) => { eventAggregator.GetEvent<GeoViewTappedEvent>().Publish(e); };
MapView.GeoViewDoubleTapped += (s, e) => { eventAggregator.GetEvent<GeoViewDoubleTappedEvent>().Publish(e); };
MapView.GeoViewHolding += (s, e) => { eventAggregator.GetEvent<GeoViewHoldingEvent>().Publish(e); };
MapView.ViewpointChanged += (s, e) => { eventAggregator.GetEvent<ViewpointChangedEvent>().Publish(MapView.VisibleArea.Extent); };
MapView.NavigationCompleted += (s, e) => { eventAggregator.GetEvent<NavigationCompletedEvent>().Publish(MapView.VisibleArea.Extent); };
} This way everything if just published and I can hook into in any Module
... View more
11-01-2023
03:50 PM
|
1
|
6
|
1439
|
POST
|
Could probably come up wit a number of things. What we are looking at now is wanting to be able t inherit properties from an asset (likely linear) to an inspection point. If we could snap the inspection point to the line then we could be sure we are using the right line to inherit properties from (could possibly even use Arcade). If we just place it close, and try to do a spatial search for the nearest feature, there is the possibility of getting the wrong one
... View more
10-28-2023
02:15 PM
|
0
|
0
|
385
|
POST
|
Perhaps I am missing something. But I do not see anything in the API around snapping. I do see this in the javascript API. I also don't see any samples which might provide an approach to doing this. Is there anything to do snapping in the API? Thanks -Joe
... View more
10-26-2023
10:00 AM
|
0
|
2
|
487
|
POST
|
Instead of having the app open it when it gets the PortalItem can you add //THIS LINE SHOULD OPEN WINDOW!
var credential = await AuthenticationManager.Current.GenerateCredentialAsync(sharingUri);
AuthenticationManager.Current.AddCredential(credential); before portal = await ArcGISPortal.CreateAsync(sharingUri); In your current code, if you put a breakpoint in the ChallangeHandler delegate does it get hit when you call (before making the change I describe above) PortalItem mapItem = await PortalItem.CreateAsync(portal, "29ad2fc9b8794fb0b6dc1ca02948613d"); //This is the ID of my webmap.
... View more
10-23-2023
01:38 PM
|
0
|
1
|
654
|
POST
|
This does not register your OAuth app AuthenticationHelper.RegisterSecureServer("https://www.arcgis.com/sharing/rest"); You need to register your OAuth. The OAuthClientInfo is required ServerInfo serverInfo = new ServerInfo(serverUri)
{
TokenAuthenticationType = TokenAuthenticationType.OAuthAuthorizationCode,
OAuthClientInfo = new OAuthClientInfo(AppClientId, redirectUri)
{
UserInterfaceStyle = UserInterfaceStyle.Dark,
ClientSecret = ClientSecret,
},
};
... View more
10-23-2023
08:06 AM
|
0
|
0
|
678
|
POST
|
If you created an OAuth key through your developer account this would only be attached to your developer account. Meaning it will only give you access to items stored on your developer AGOL. An organizational account would require you to create a OAuth App in that Organization. Have you tried to create a map in the AGOL site that is accessed by your developer login (I assume the BrianBulla1 named user) that you use to access the developer dashboard? I have a developer site that came with my dev account, although I don't use. But my company has an Organizational account. An map that is setup in my Organization could not be accessed with an OAuth app I setup on the developer dashboard because it is a different account, I could access the traffic layer with my dashboard OAuth
... View more
10-16-2023
10:53 AM
|
0
|
0
|
701
|
POST
|
You need to call ArcGISRuntime.Initialize after setting the API Key
... View more
10-16-2023
10:11 AM
|
0
|
0
|
1507
|
POST
|
Are you passing an API Key? You need to pass in if using a public map. You can do when loading map or in the Runtime Initialize
... View more
10-16-2023
09:11 AM
|
0
|
0
|
1517
|
POST
|
Hard to know what you have gotten done. Have you setup the OAuth app inside of ArcGIS Online? This is discussed in the sample Authenticate with OAuth You can do through dev account if you are using AGOL tied to dev account Register an OAuth application Do on AGOL, this is a bit old so there are slight GUI changes How to Implement OAuth 2.0 for ArcGIS You need to implement the IOAuthAuthorizeHandler. See at bottom Wire up everything. This is done before you can make a call that will open the OAuth window. AppClientID, ClientSecret, RedirectUrl all come from the OAuth app in AGOL (or dev center) private void Initialize(Uri serverUri)
{
try
{
var redirectUri = new Uri(RedirectUrl);
ServerInfo serverInfo = new ServerInfo(serverUri)
{
TokenAuthenticationType = TokenAuthenticationType.OAuthAuthorizationCode,
OAuthClientInfo = new OAuthClientInfo(AppClientId, redirectUri)
{
UserInterfaceStyle = UserInterfaceStyle.Dark,
ClientSecret = ClientSecret,
},
};
AuthenticationManager.Current.RegisterServer(serverInfo);
AuthenticationManager.Current.OAuthAuthorizeHandler = _oAuthAuthorizeHandler;
AuthenticationManager.Current.ChallengeHandler = new ChallengeHandler(CreateCredentialAsync);
}
catch (Exception e)
{
_log?.Log(e.Message, Category.Exception, Priority.None);
}
}
private async Task<Credential> CreateCredentialAsync(CredentialRequestInfo info)
{
try
{
Credential credential = null;
try
{
if (info.ServiceUri != null)
{
var options = new GenerateTokenOptions { TokenExpirationInterval = TimeSpan.FromDays(1) };
credential = await AuthenticationManager.Current.GenerateCredentialAsync(info.ServiceUri, options);
AuthenticationManager.Current.AddCredential(credential);
ConnectionStatus = ConnectionStatus.Connected;
}
}
catch (OperationCanceledException)
{
ConnectionStatus = ConnectionStatus.NotConnected;
// Login was cancelled, no need to display an error to the user.
}
catch (Exception e)
{
_log.Log(e.Message, Category.Warn, Priority.None);
}
return credential;
}
catch (Exception)
{
return null;
}
} One annoying with the API is that connecting to Portal does not automatically trigger the the challenge handler. So you have to have the code in the method that connects to portal that, imo, should only be in ChallengeHandler public async Task<ArcGISPortal> OpenPortalAsync(string portalUrl, bool refresh = false)
{
var sharingUri = GetSharingUri(portalUrl);
//THIS LINE SHOULD OPEN WINDOW!
var credential = await AuthenticationManager.Current.GenerateCredentialAsync(sharingUri);
AuthenticationManager.Current.AddCredential(credential);
_portal = await ArcGISPortal.CreateAsync(sharingUri);
PortalUser = _portal.User;
return _portal;
}
private Uri GetSharingUri(string portalUrl)
{
return new Uri($"{portalUrl}/sharing/rest");
} IOAuthAuthorizeHandler implementation from esri sample: // In a desktop (WPF) app, an IOAuthAuthorizeHandler component is used to handle some of the OAuth details. Specifically, it
// implements AuthorizeAsync to show the login UI (generated by the server that hosts secure content) in a web control.
// When the user logs in successfully, cancels the login, or closes the window without continuing, the IOAuthAuthorizeHandler
// is responsible for obtaining the authorization from the server or raising an OperationCanceledException.
public class OAuthAuthorizeHandler : IOAuthAuthorizeHandler
{
// Window to contain the OAuth UI.
private Window _authWindow;
// Use a TaskCompletionSource to track the completion of the authorization.
private TaskCompletionSource<IDictionary<string, string>> _tcs;
// URL for the authorization callback result (the redirect URI configured for your application).
private string _callbackUrl;
// URL that handles the OAuth request.
private string _authorizeUrl;
// Function to handle authorization requests, takes the URIs for the secured service, the authorization endpoint, and the redirect URI.
public Task<IDictionary<string, string>> AuthorizeAsync(Uri serviceUri, Uri authorizeUri, Uri callbackUri)
{
if (_tcs != null && !_tcs.Task.IsCompleted)
throw new Exception("Task in progress");
_tcs = new TaskCompletionSource<IDictionary<string, string>>();
// Store the authorization and redirect URLs.
_authorizeUrl = authorizeUri.AbsoluteUri;
_callbackUrl = callbackUri.AbsoluteUri;
// Call a function to show the login controls, make sure it runs on the UI thread for this app.
Dispatcher dispatcher = Application.Current.Dispatcher;
if (dispatcher == null || dispatcher.CheckAccess())
{
AuthorizeOnUIThread(_authorizeUrl);
}
else
{
Action authorizeOnUIAction = () => AuthorizeOnUIThread(_authorizeUrl);
dispatcher.BeginInvoke(authorizeOnUIAction);
}
// Return the task associated with the TaskCompletionSource.
return _tcs.Task;
}
// Challenge for OAuth credentials on the UI thread.
private void AuthorizeOnUIThread(string authorizeUri)
{
// Create a WebBrowser control to display the authorize page.
WebBrowser webBrowser = new WebBrowser();
// Handle the navigation event for the browser to check for a response to the redirect URL.
webBrowser.Navigating += WebBrowserOnNavigating;
// Display the web browser in a new window.
_authWindow = new Window
{
Content = webBrowser,
Width = 450,
Height = 450,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
// Set the app's window as the owner of the browser window (if main window closes, so will the browser).
if (Application.Current != null && Application.Current.MainWindow != null)
{
_authWindow.Owner = Application.Current.MainWindow;
}
// Handle the window closed event then navigate to the authorize url.
_authWindow.Closed += OnWindowClosed;
webBrowser.Navigate(authorizeUri);
// Display the window.
_authWindow.ShowDialog();
}
// Handle the browser window closing.
private void OnWindowClosed(object sender, EventArgs e)
{
// If the browser window closes, return the focus to the main window.
if (_authWindow != null && _authWindow.Owner != null)
{
_authWindow.Owner.Focus();
}
// If the task wasn't completed, the user must have closed the window without logging in.
if (!_tcs.Task.IsCompleted)
{
// Set the task completion source exception to indicate a canceled operation.
_tcs.SetCanceled();
}
_authWindow = null;
}
// Handle browser navigation (content changing).
private void WebBrowserOnNavigating(object sender, NavigatingCancelEventArgs e)
{
// Check for a response to the callback url.
const string portalApprovalMarker = "/oauth2/approval";
WebBrowser webBrowser = sender as WebBrowser;
Uri uri = e.Uri;
// If no browser, uri, or an empty url, return.
if (webBrowser == null || uri == null || string.IsNullOrEmpty(uri.AbsoluteUri))
return;
// Check for redirect.
bool isRedirected = uri.AbsoluteUri.StartsWith(_callbackUrl) ||
_callbackUrl.Contains(portalApprovalMarker) && uri.AbsoluteUri.Contains(portalApprovalMarker);
// Check if browser was redirected to the callback URL. (This indicates succesful authentication.)
if (isRedirected)
{
e.Cancel = true;
// Call a helper function to decode the response parameters.
IDictionary<string, string> authResponse = DecodeParameters(uri);
// Set the result for the task completion source.
_tcs.SetResult(authResponse);
// Close the window.
if (_authWindow != null)
{
_authWindow.Close();
}
}
}
private static IDictionary<string, string> DecodeParameters(Uri uri)
{
// Create a dictionary of key value pairs returned in an OAuth authorization response URI query string.
string answer = "";
// Get the values from the URI fragment or query string.
if (!string.IsNullOrEmpty(uri.Fragment))
{
answer = uri.Fragment.Substring(1);
}
else
{
if (!string.IsNullOrEmpty(uri.Query))
{
answer = uri.Query.Substring(1);
}
}
// Parse parameters into key / value pairs.
Dictionary<string, string> keyValueDictionary = new Dictionary<string, string>();
string[] keysAndValues = answer.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string kvString in keysAndValues)
{
string[] pair = kvString.Split('=');
string key = pair[0];
string value = string.Empty;
if (key.Length > 1)
{
value = Uri.UnescapeDataString(pair[1]);
}
keyValueDictionary.Add(key, value);
}
// Return the dictionary of string keys/values.
return keyValueDictionary;
}
}
... View more
10-11-2023
05:49 AM
|
0
|
0
|
1549
|
POST
|
A little more detail about what you issues are, platform. The security sample in github are hard to follow because they use shared code, better to follow in the sample explanation on the site.
... View more
10-04-2023
03:49 PM
|
1
|
0
|
1594
|
POST
|
It would appear just setting up standard OAuth will do the trick, nothing different wit it being SAML
... View more
10-04-2023
03:46 PM
|
1
|
0
|
326
|
POST
|
@YashvitNaik I would agree with Michael and if you are starting something new look at MAUI. I think you can use with the Core 8 preview. Xamarin is basically already out of support by Microsoft. At this point they are not showing any indication of releasing an official Xamarin.iOS library to support XCode 15. The latest official Xamarin.iOS library only support XCode 14 which targets iOS <= 16.x. As iOS 17 is already out, Xamarin no longer supports the latest iOS devices or ones that have been updated.
... View more
10-04-2023
08:45 AM
|
0
|
0
|
603
|
POST
|
Hi, Is there any samples for connecting to an ArcGIS Enterprise that uses SAML security (Azure)? Thanks - Joe
... View more
10-04-2023
05:20 AM
|
0
|
1
|
393
|
POST
|
@dotMorten_esri So to confirm what you are saying, I could just stick with Framework 4.7.2 and not move to Net Core for the 200.x release
... View more
10-03-2023
11:27 AM
|
0
|
1
|
1124
|
Title | Kudos | Posted |
---|---|---|
1 | 01-24-2024 10:00 AM | |
1 | 08-03-2023 04:14 AM | |
1 | 11-30-2023 10:39 AM | |
1 | 11-10-2023 12:40 PM | |
1 | 11-07-2023 01:16 PM |
Online Status |
Offline
|
Date Last Visited |
6 hours ago
|