The name 'DisplayPromptAsync' does not exist in the current context - Xamarin - c#

I'm trying to implement a simple Dialog with a text input in Android Xamarin, using a DisplayPromptAsync:
private async void ShowDialogAsync() {
string result = await DisplayPromptAsync("Question 1", "What's your name?");
}
Source: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/pop-ups
But I'm getting the next error:
CS0103 The name 'DisplayPromptAsync' does not exist in the current context
And it doesn't give me the option to import any library. My version of Xamarin Forms is 4.6.0.726
It's something I'm missing...?
Thanks in advance...

In the ViewModel, just add the App.Current.MainPage before the call of DisplayPromptAsync:
private async void ShowDialogAsync() {
string result = await App.Current.MainPage.DisplayPromptAsync("Question 1", "What's your name?");
// OK
if (result != null)
{
// do something here
} else {
// do something else here
}
}
Thanks to Jason for his reply...

Update NuGet for Xamarin.Forms
I have updated NuGet for Xamarin.Forms from 4.2.X to 4.3.X in all projects and now it works. Apparently in 4.2.X the method "appears" available with intellisense, but at runtime it fails with the mentioned error. Updating all NuGet packages seemed to solve the problem.

Related

Rg.Plugins.Popup error Rg.Plugins.Popup.Exceptions.RGPopupStackInvalidException: 'No Page in PopupStack'

i ran into this exception in my Xamarin Forms app that seems clear yet hard to resolve.
I created a kind of loader using the Rg.Plugins.Popup and i want to dismiss this loader when a user presses the back button while a web services is still running. But it throws this exception Rg.Plugins.Popup.Exceptions.RGPopupStackInvalidException: 'No Page in PopupStack' which means i am trying to remove a page that doesn't exist, and the app crashes. I have also followed the setup i saw here in the Docs. Below is my code;
private async void RemovePage()
{
var popPage = Rg.Plugins.Popup.Services.PopupNavigation.Instance.PopupStack;
if (!popPage.Any() || popPage.Count == 0 || popPage == null)
{
return;
}
else
{
var lastPage = popPage.Last();
if (lastPage.GetType() == typeof(LoadingPopup))
{
await Rg.Plugins.Popup.Services.PopupNavigation.Instance.RemovePageAsync(lastPage);
}
else
{
return;
}
}
}
Note: I am using the latest stable version 2.0.0.12 of Rg.Plugins.Popup and Xamarin.Forms 5.0.0.2012. Please what am i doing wrong here?

SceneManager.LoadScene doesn't work on development mobile build

I'm trying to build a Unity game on android/iOS by checking the development build option (so that I can use the profiler for debugging), but the SceneManager.LoadScene function doesn't work. I tried the scene name and index as the function parameters, but both didn't work.
It's important to note that the game works perfectly fine if I uncheck the development build option. I'm currently using Unity 2019.3.5.f1.
Edit:
I noticed that the scene loads without any problems when I run SceneManager.LoadScene from the Start() function. However, in most parts of my code, I run SceneManager.LoadScene from inside other functions, such as event handlers.
Here are a few code examples:
I run this function in Awake(). It reaches SceneManager.LoadScene("Credentials"); then stops:
private void ConfirmGooglePlayerServicesRequirements()
{
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
app = Firebase.FirebaseApp.DefaultInstance;
InitializeFirebase();
if (!signedIn)
SceneManager.LoadScene("Credentials");
}
else
{
Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
}
This is a Firebase function which is called whenever a user signs in/out. It invokes an event called signedInEvent, which is handled by a function in another script that runs SceneManager.LoadScene.
void AuthStateChanged(object sender, System.EventArgs eventArgs)
{
if (auth.CurrentUser != user)
{
signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null)
{
Debug.Log("Signed out " + user.UserId);
}
user = auth.CurrentUser;
if (signedIn)
{
Debug.Log("Signed in " + user.UserId);
displayName = user.DisplayName ?? "";
emailAddress = user.Email ?? "";
userId = user.UserId ?? "";
signedInEvent.Invoke(displayName, emailAddress, userId);
}
}
}
Notes:
Scenes/FirstScene is enabled. It was disabled when I took the screenshot above because I was doing some tests.
I got this error using adb (android debug bridge) a while ago when I ran the game in development mode. It might be related to this issue: FindGameObjectWithTag can only be called from the main thread
Thanks!
FindGameObjectWithTag can only be called from the main thread
This is indeed related! Now that you posted your code:
ContinueWith might get called on a background thread. Most of the Unity API may only be called from the main thread otherwise it might either show an error such as the one you mentioned or sometimes it just fails silently.
In general this is often solved by something like e.g. UnityMainThreadDispatcher.
However, specifically for Firebase there already exists an extension called ContinueWithOnMainThread in the Firebase.Extensions namespace which makes sure the callback code is actually executed in the main thread where the Unity API works.
Extension methods for System.Threading.Tasks.Task and System.Threading.Tasks.Task<T> that allow the continuation function to be executed on the main thread in Unity.
using Firebase.Extensions;
private void ConfirmGooglePlayerServicesRequirements()
{
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
app = Firebase.FirebaseApp.DefaultInstance;
InitializeFirebase();
if (!signedIn)
{
SceneManager.LoadScene("Credentials");
}
}
else
{
Debug.LogError($"Could not resolve all Firebase dependencies: {dependencyStatus}", this);
// Firebase Unity SDK is not safe to use here.
}
});
}

First prompt of proactive localised formflow in wrong language in bot framework

I've submitted this as a bug report but also filing it here in case I'm doing something wrong and this isn't really a bug.
Bot framework version
3.16.1.38846
Describe the issue
I'm trying to create a localised formflow that can be proactively triggered. I'm able to create the form and trigger it through an API call using the proactive dialog trigger. However, the first question is always in English, despite the locale not being English. Nonetheless, it expects an answer in the locale in play (Mandarin in this case, (zh-SG)).
If I were to not trigger it through my API, all my questions are localised based on whatever locale I send in through the bot framework emulator. I tested this by setting up a keyword check in the root dialog, and I'm able to get all my formflow questions asked in the language specified. I've attached screenshots of how this seems to play out too.
To Reproduce
Steps to reproduce the behavior:
Create a simple form
Localise the form using the guide in the documentation
Call the form using the bot framework emulator using a simple keyword check in the root dialog. Use the default locale of en-US (Sample below)
Call the form using the bot framework emulator using a simple keyword check in the root dialog. Use the other language's locale (in this case, zh-SG)
Call the form using a proactive dialog trigger through a WebAPI. Method looks like this. Parameters such as the activity object have been previously seralised to a database. I've obscured certain parameters to protect some confidential information
Sample trigger
if (activity.Text.Equals("Trigger"))
{
var form = new FormDialog<Form1>(new Form1(), Form1.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formCompleteAsync);
}
WebAPI method
public IHttpActionResult Post([FromBody]Model Model)
{
if (ModelState.IsValid)
{
try
{
StartProactiveDialogAsync(model.someId, model.anotherId)
return Ok();
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
else
{
return BadRequest(ModelState);
}
}
StartProactiveDialogAsync
public async Task StartProactiveDialogAsync(someId, anotherId )
{
try
{
// Recreate the message from the conversation reference that was saved previously.
Activity activity = JsonConvert.DeserializeObject<Activity>(BotUserData.ConversationReference);
MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl);
var client = new ConnectorClient(new Uri(activity.ServiceUrl));
// Create a scope that can be used to work with state from bot framework.
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(CancellationToken.None);
// This is the dialog stack.
var stack = scope.Resolve<IDialogTask>();
// Create the new dialog and add it to the stack.
var dialog = new CallDialog(parameter1, parameter2);
stack.Call(dialog.Void<object, IMessageActivity>(), null);
await stack.PollAsync(CancellationToken.None);
// Flush the dialog stack back to its state store.
await botData.FlushAsync(CancellationToken.None);
}
}
catch (Exception e)
{
await ProprietaryDiagnosticsTool.SendDiagnostic(e);
}
}
CallDialog
public class CallDialog : IDialog<object>
{
Parameter1 param1;
Parameter2 param2;
public CallDialog(Parameter1 param1, Parameter2 param2)
{
this.param1 = param1;
this.param2 = param2;
}
public async Task StartAsync(IDialogContext context)
{
switch (param1.Id)
{
case 1:
{
var form = new FormDialog<Form1>(new Form1(), Form1.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formComplete);
break;
}
case 2:
{
var form = new FormDialog<Form2>(new Form2(), Form2.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formComplete);
break;
}
case 3:
{
var form = new FormDialog<Form3>(new Form3(), Form3.BuildForm, FormOptions.PromptInStart, null);
context.Call(form, formComplete);
break;
}
}
}
private async Task formComplete(IDialogContext context, IAwaitable<FormParent> result)
{
var ans = await result;
await context.PostAsync("Result received");
context.Done(this);
}
}
Expected behavior
When calling the proactive dialog which calls the form in a different locale, the form should be presented in the locale specified
Screenshots
English formflow triggered through keyword - correct
English formflow triggered through API - correct
Mandarin formflow triggered through keyword - correct
Mandarin formflow triggered through API - incorrect
The error message says
"Yes" is not an option for question 1.
Additional information
I've traced the context.activity object through the various methods, from StartProactiveDialogAsync to CallDialog all the way till the formComplete method. The locale does tend to be correct, its simply the display of the first question of the proactive dialog calling the formflow that happens to be in the wrong language.
Eric from Microsoft helped to resolve this.
His full answer can be found here: https://github.com/Microsoft/BotBuilder-V3/issues/82
Simply put the locale needs to be pulled out of context.activity.privateconversationdata and sent to the form itself as it does not pick up the locale on its own when resuming a conversation.

Geolocation error, ClassNotFoundException

I am working on a Xamarin Cross Platform App and I have a problem when I try to obtain my gps coords. I have this code to get the gps information:
protected async override void OnAppearing()
{
position = await GetPosition();
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(position.Latitude, position.Longitude), Distance.FromMiles(0.3)));
}
async Task<Plugin.Geolocator.Abstractions.Position> GetPosition()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
Plugin.Geolocator.Abstractions.Position position = await locator.GetPositionAsync(TimeSpan.FromSeconds(5));
return position;
}
When it reaches the line:
Plugin.Geolocator.Abstractions.Position position = await locator.GetPositionAsync(TimeSpan.FromSeconds(5));
It gives me this exception:
Java.Lang.ClassNotFoundException: Didn't find class
"md57251f317a80041e1a60080af127573bd.GeolocationSingleListener" on
path: DexPathList[[zip file
"/data/app/com.companyname.PruebaMapas-1/base.apk"],nativeLibraryDirectories=[/data/app/com.companyname.PruebaMapas-1/lib/x86,
/system/fake-libs,
/data/app/com.companyname.PruebaMapas-1/base.apk!/lib/x86,
/system/lib, /vendor/lib]]
I don't know why. I add the "Plugin.Geolocator" using NuGet and it is on my PruebaMapas project and on my PruebaMapas.Android project too.
Can anyone help me? Thanks a lot!
Did your application works without using GeoPlugin ? If not it can be similar to this so u can try this solution. This is known issue in Xamarin android 8.1.

Await in Windows Phone 7?

I am trying to go through the Windows Phone Live tutorial but I get stuck when trying to implement the code example as it seems to be missing information.
using System;
using System.Windows;
using System.Collections.Generic;
using Microsoft.Phone.Controls;
using Microsoft.Live;
using Microsoft.Live.Controls;
namespace WindowsPhoneCodeSample
{
public partial class MainPage : PhoneApplicationPage
{
private LiveConnectClient client;
public MainPage()
{
InitializeComponent();
}
private async void btnSignin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(e.Session);
LiveOperationResult operationResult = await client.GetAsync("me");
try
{
dynamic meResult = operationResult.Result;
if (meResult.first_name != null &&
meResult.last_name != null)
{
infoTextBlock.Text = "Hello " +
meResult.first_name + " " +
meResult.last_name + "!";
}
else
{
infoTextBlock.Text = "Hello, signed-in user!";
}
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = "Error calling API: " +
exception.Message;
}
}
else
{
infoTextBlock.Text = "Not signed in.";
}
}
}
}
I get
Error 2 The name 'await' does not exist in the current context
Error 3 One or more types required to compile a dynamic expression cannot be found. Are you missing references to Microsoft.CSharp.dll and System.Core.dll?
Am I missing some reference or something?
Edit
the tutorial seems to be poorly done or very out of date. I made a windows phone 8 application and it still does not build because of the "awai"t keyword.
The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
client.GetAsync is also a void method. So not sure how it returns something as well.
await works only with awaitables - see ยง7.7.7.1 on the C# Language Specification.
Since client.GetAsync is a void returning method, it can never be an awaitable.
You need to install NuGet Package Microsoft.Bcl.Async (you can find it in NuGet Manager) so compiler recognize words await and async.
more info http://www.nuget.org/packages/Microsoft.Bcl.Async/

Categories