public Task <InvokeResult> InvokeAsync(InvokeOptions options) { if (string.IsNullOrWhiteSpace(options.StartUrl)) { throw new ArgumentException("Missing StartUrl", nameof(options)); } if (string.IsNullOrWhiteSpace(options.EndUrl)) { throw new ArgumentException("Missing EndUrl", nameof(options)); } // must be able to wait for the intent to be finished to continue // with setting the task result var _tcs = new TaskCompletionSource <InvokeResult>(); // create & open chrome custom tab _customTabs = new CustomTabsActivityManager(_context); // build custom tab var builder = new CustomTabsIntent.Builder(_customTabs.Session) .SetToolbarColor(Color.Argb(255, 52, 152, 219)) .SetShowTitle(true) .EnableUrlBarHiding(); var customTabsIntent = builder.Build(); // ensures the intent is not kept in the history stack, which makes // sure navigating away from it will close it customTabsIntent.Intent.AddFlags(ActivityFlags.NoHistory); ActivityMediator.MessageReceivedEventHandler callback = null; callback = (response) => { // remove handler AndroidClientChromeCustomTabsApplication .Mediator.ActivityMessageReceived -= callback; // set result _tcs.SetResult(new InvokeResult { Response = response, ResultType = InvokeResultType.Success }); // start MainActivity (will close the custom tab) _context.StartActivity(typeof(MainActivity)); }; // attach handler AndroidClientChromeCustomTabsApplication.Mediator.ActivityMessageReceived += callback; // launch customTabsIntent.LaunchUrl(_context, Android.Net.Uri.Parse(options.StartUrl)); // need an intent to be triggered when browsing to the "io.identitymodel.native://callback" // scheme/URI => CallbackInterceptorActivity return(_tcs.Task); }
public Task <BrowserResult> InvokeAsync(BrowserOptions options) { if (string.IsNullOrWhiteSpace(options.StartUrl)) { throw new ArgumentException("Missing StartUrl", nameof(options)); } if (string.IsNullOrWhiteSpace(options.EndUrl)) { throw new ArgumentException("Missing EndUrl", nameof(options)); } // must be able to wait for the intent to be finished to continue // with setting the task result var tcs = new TaskCompletionSource <BrowserResult>(); // create Safari controller _safari = new SafariServices.SFSafariViewController(new NSUrl(options.StartUrl)); _safari.Delegate = this; ActivityMediator.MessageReceivedEventHandler callback = null; callback = async(response) => { // remove handler ActivityMediator.Instance.ActivityMessageReceived -= callback; if (response == "UserCancel") { tcs.SetResult(new BrowserResult { ResultType = BrowserResultType.UserCancel }); } else { // Close Safari await _safari.DismissViewControllerAsync(true); // set result tcs.SetResult(new BrowserResult { Response = response, ResultType = BrowserResultType.Success }); } }; // attach handler ActivityMediator.Instance.ActivityMessageReceived += callback; // launch Safari _controller.PresentViewController(_safari, true, null); // need an intent to be triggered when browsing to the "io.identitymodel.native://callback" // scheme/URI => CallbackInterceptorActivity return(tcs.Task); }
public Task <BrowserResult> InvokeAsync(BrowserOptions options) { if (string.IsNullOrWhiteSpace(options.StartUrl)) { throw new ArgumentException("Missing StartUrl", nameof(options)); } if (string.IsNullOrWhiteSpace(options.EndUrl)) { throw new ArgumentException("Missing EndUrl", nameof(options)); } // must be able to wait for the intent to be finished to continue // with setting the task result var tcs = new TaskCompletionSource <BrowserResult>(); ActivityMediator.MessageReceivedEventHandler callback = null; callback = (response) => { // remove handler ActivityMediator.Instance.ActivityMessageReceived -= callback; // set result if (response == "UserCancel") { tcs.SetResult(new BrowserResult { ResultType = BrowserResultType.UserCancel }); } else { tcs.SetResult(new BrowserResult { Response = response, ResultType = BrowserResultType.Success }); } }; // attach handler ActivityMediator.Instance.ActivityMessageReceived += callback; // Launch browser var uri = Android.Net.Uri.Parse(options.StartUrl); var intent = new Intent(Intent.ActionView, uri); intent.AddFlags(ActivityFlags.NoHistory); _context.StartActivity(intent); // need an intent to be triggered when browsing to the "io.identitymodel.native://callback" // scheme/URI => CallbackInterceptorActivity return(tcs.Task); }
public Task <BrowserResult> InvokeAsync(BrowserOptions options) { if (string.IsNullOrWhiteSpace(options.StartUrl)) { throw new ArgumentException("Missing StartUrl", nameof(options)); } if (string.IsNullOrWhiteSpace(options.EndUrl)) { throw new ArgumentException("Missing EndUrl", nameof(options)); } // must be able to wait for the authentication session to be finished to continue // with setting the task result var tcs = new TaskCompletionSource <BrowserResult>(); // For iOS 11, we use the new SFAuthenticationSession if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0)) { // create the authentication session _authSession = new SFAuthenticationSession( new NSUrl(options.StartUrl), options.EndUrl, (callbackUrl, error) => { if (error != null) { tcs.SetResult(new BrowserResult { ResultType = BrowserResultType.UserCancel, Error = error.ToString() }); } else { tcs.SetResult(new BrowserResult { ResultType = BrowserResultType.Success, Response = callbackUrl.AbsoluteString }); } }); // launch authentication session _authSession.Start(); } else // For pre-iOS 11, we use a normal SFSafariViewController { // create Safari controller _safari = new SFSafariViewController(new NSUrl(options.StartUrl)) { Delegate = this }; ActivityMediator.MessageReceivedEventHandler callback = null; callback = async(response) => { // remove handler ActivityMediator.Instance.ActivityMessageReceived -= callback; if (response == "UserCancel") { tcs.SetResult(new BrowserResult { ResultType = BrowserResultType.UserCancel }); } else { // Close Safari await _safari.DismissViewControllerAsync(true); // set result tcs.SetResult(new BrowserResult { Response = response, ResultType = BrowserResultType.Success }); } }; // attach handler ActivityMediator.Instance.ActivityMessageReceived += callback; // https://forums.xamarin.com/discussion/24689/how-to-acces-the-current-view-uiviewcontroller-from-an-external-service var window = UIApplication.SharedApplication.KeyWindow; var vc = window.RootViewController; while (vc.PresentedViewController != null) { vc = vc.PresentedViewController; } // launch Safari vc.PresentViewController(_safari, true, null); } // Result for this task will be set in the authentication session // completion handler return(tcs.Task); }