I am trying to react to suspend events within my Windows Store App. I added the appropriate callback method, but I've run into a problem:
App.Current.Suspending += Current_Suspending;
void Current_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e){}
The problem is that, when I trigger the suspension event in Visual Studio and the callback method is called (I have checked it with a breakpoint), it immediately terminates with an Exception:
session state service failed.
Any suggestions on how to solve this problem?
If you are using Prism as I was this can happen when the SessionStateService chokes on serializing an object. Relevant navigation parameters and anything manually added get serialized at app termination or suspension. In my specific case i had a non-nullable enum that wasn't being set on an object used as a navigation parameter. I used the following to verify the DataContractSerializer wasn't having issues with object.
test.Add("testitem", new WorkflowStep());
MemoryStream sessionData = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>));
serializer.WriteObject(sessionData, test);
Related
I started using MVVMCross several weeks ago and so far I love it, but I've noticed that whenever I'm working on the UI and making changes in the XAML and pressing save which activates the Hot Reload in Visual Studio 2019, I'm getting Null Reference Exceptions.
This is down to the fact that the MVVMCross' Prepare method is not getting called. According to their doc's this method is used to pass a parameter to the VM which can then be used throughout the VM.
public override void Prepare(MyClass param)
{
MyClass = param;
}
public override Task Initialize()
{
MyClass.DoSomething();
return base.Initialize();
}
So this is the basic usage (I think). However when I Hot Reload the XAML changes Prepare isn't called but Initialize is, which causes the Exception.
Is this a bug ?
Prepare in normal cases will only be called when calling NavigationService.Navigate.
What Hot Reload actually does is unclear. This use case is currently not officially supported by MvvmCross.
I am using Visual Studio App Center for my Xamarin Forms Android Application for capturing the Analytics(Events and Crashes)
I am configuring crashes and analytics in OnStart of my App.Xaml.cs
AppCenter.Start($"android={Settings.Current.AppCenterAnalyticsAndroid};" +
typeof(Analytics), typeof(Crashes));
And for invoking the Events I am calling the below Method.
public void TrackEvent(string name, Dictionary<string, string> properties = null)
{
Analytics.SetEnabledAsync(true).ConfigureAwait(false);
Analytics.TrackEvent(name, properties);
}
Crashes are logging correctly in App Center But the events are not.
Also I can see the corresponding entries in Log Flow
Your app secret string is invalid because it contains + typeof(Analytics), it should be , typeof(Analytics).
Since you used the android key/value delimiter we could extract the appSecret and make it work with Crashes, but typeof(Analytics) ended up in the wrong appSecret parameter string.
You shouldn't need to add Analytics.SetEnabledAsync(true).ConfigureAwait(false);
Simply Call Analytics.TrackEvent(name, properties); (it doesn't need to be in a task anyways. I track my events in the Construtor of pages, for example.
Also, when you run the application, you get a debug Message confirming that AppCenter has been configured correctly, check if that is the case.
And, it may take a while, for them to appear in the Events.
I am building an iOS app with Xamarin and MvvmCross the required the use of Bluetooth LE. I am trying to use this plugin:
https://github.com/aritchie/bluetoothle
Here is my code:
var server = CrossBleAdapter.Current.CreateGattServer();
await server.Start(new AdvertisementData()); // throws exception
It throws an exception when trying to start the server:
{System.ArgumentException: Invalid State - Unknown at
Plugin.BluetoothLE.Server.GattServer.Start
(Plugin.BluetoothLE.Server.AdvertisementData adData) [0x0005f] in
<4281c4bd57f24525b20baae1afdf610b>:0
Apparently this plugin is easy to use so I must be missing something obvious?
That Exception indicates that the hardware is in invalid or initializing state and can be seen here: https://github.com/aritchie/bluetoothle/blob/master/Plugin.BluetoothLE.Apple.Shared/Server/GattServer.cs#L74
if (this.manager.State != CBPeripheralManagerState.PoweredOn)
throw new ArgumentException("Invalid State - " + this.manager.State);
I believe this is a bug in the code as it does not wait for the delegate to signal that the State has changed.
I found a solution. Instead of placing the code in my Core project, I placed it inside the iOS project itself, in a ViewDidAppear function, and placed a global variable in my UIViewController class:
private IGattServer server = CrossBleAdapter.Current.CreateGattServer();
I think you need to access the adapter with the appropriate thread, or at the appropriate time (after other initialization), hence why it was crashing before. I couldn't find an appropriate place to put this in my Core project, so I'm not sure if I have to put this code in each platform. Anyhow here's a solution for anyone else with this problem.
Working on my first Xamarin Forms app. I put this in my App's OnStart() method:
Application.Current.Properties["Email"] = "gern#blanston.org";
That should set the value as soon as the Application starts, right?
Then I created a Login content page with an EmailAddress entry. In the page initialization, I've got this:
if (Application.Current.Properties.ContainsKey("Email"))
{
EmailAddress.Text = Application.Current.Properties["Email"] as string;
}
When I run the app, the EmailAddress Entry element is not populated.
What am I doing wrong?
OnStart command is called after App constructor and you probably creating login page in App constructor and checking in login page constructor but OnStart is not called yet. Set it before you created login/main page
Application.Current.Properties["Email"] = "gern#blanston.org";
var navPage = new MainPage();
It should work.
Here is the Documentation.
You can try to use SavePropertiesAsync
The Properties dictionary is saved to the device automatically. Data added to the dictionary will be available when the application returns from the background or even after it is restarted.
Xamarin.Forms 1.4 introduced an additional method on the Application class - SavePropertiesAsync() - which can be called to proactively persist the Properties dictionary. This is to allow you to save properties after important updates rather than risk them not getting serialized out due to a crash or being killed by the OS.
Even though NavigationService.CanGoBack returns True, NavigationService.GoBack() throws me these exceptions :
A first chance exception of type 'System.ArgumentException' occurred in System.Windows.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in
This happens systematically on two case, while the third works fine :
Crashes if I call NavigationService.GoBack() in OnNavigatedTo()
Crashes If I call NavigationService.GoBack() as a result of WebException thrown in my HTTPWebRequest when Internet is not available [1]
Works fine if Internet is available and I call NavigationService.GoBack() when my HTTPWebRequest got results, parsed them, and displayed them.
My theory is that I can't call GoBack() too soon after navigating from a page to another... My question : How can I programatically go back up the navigation stack when an HTTPWebRequest fails to load ?
Edit : I've decided to do it another way, but I think my problems might be due to navigation animations and the Windows Phone C# Toolkit (I use Feb 2011 edition)
[1] Details of my code on case 2 :
I have a simple HTTPWebRequest. My callback does this, and my app crashes when in Airplane Mode. The line NavigationService.GoBack() is responsible, even though NavigationService.CanGoBack returns true.
try
{
response = request.EndGetResponse(result);
}
catch (WebException)
{
Dispatcher.BeginInvoke(() =>
{
NavigationService.GoBack();
});
}
I tried using Deployment.Current.Dispatcher.BeginInvoke() also.
You could try using WebClient client = new WebClient();, then use client.DownloadStringAsync(new Uri("request_url")); to make your request and subscribe to the client.DownloadStringCompleted event to receive your data when the request is completed. After parsing the data, in the event handler you can then call NavigationService.GoBack(); or go to whichever page you want.
Also, if you try to do something in the OnNavigatedTo event and run into trouble you could try using the OnNavigatingFrom instead (on the previous page ofc), cancel the navigation e.Cancel = true;, do your thing as in make the request and stuff, then get the application frame and navigate to e.Uri (basically continuing the navigation you previously cancelled).
Altho this second might represent a solution as well, I think the first one is better as it does all the work async thus not blocking your UI thread. This is what I generally use in my apps. Hope it helps.