When using Appcenter, can I still call VersionTracking inside the App constructor? - xamarin

The application I am working with uses AppCenter with code like this:
public App()
{
InitializeComponent();
VersionTracking.Track();
VersionChecks();
VersionChecks();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetDeviceInfo();
SetResourceColors();
SetResourceDimensions();
MainPage = new AppShell();
}
protected override void OnStart()
{
AppCenter.Start("xx", typeof(Crashes), typeof(Push));
Analytics.TrackEvent(VersionTracking.CurrentVersion);
}
Although I don't see any error messages when it starts up I am concerned about the way this is coded as from what I can see the App constructor fires first followed by the OnStart().
So if this happens, how can VersionTracking work. Should that code not be in the OnStart and how about the additional code that I have which sets up the application?
Would appreciate any advice that people can offer about the use of AppCenter with Xamarin forms.

Answer
Yes, you can use Xamarin.Essentials.VersionTracking in the constructor of App.
Explanation
You are confusing three different SDKs: Xamarin.Essentials, Xamarin.Forms and AppCenter.
VersionTracking is an API in Xamarin.Essentials.
App is a subclass of the Xamarin.Forms.Application API.
AppCenter.Start is an API in the AppCenter
These are three independent SDKs and each can be used independently of the others.

Xamarin.Forms app startup flow is like : Native App Startup -> Xamarin.Forms.Application Startup
Your App class is instantiated only after Native app has finished loading.
As versioning is managed by native app, there is no problem in initialising VersionTracking in constructor, as Native app has fully loaded by this time.

Related

How to import Activity of NfcFCardEmulation.EnableService from Xamarin common project, not Android project?

I'm developing an app using Xamarin's HCE feature.
The project structure is as follows.
hceSample
hceSample.Android
hceSample.iOS
I am implementing hce simulation code called hceService in hceSample, not hceSample.Android.
A function called Enable_Card exists in the hce service, and you want to use the NfcFCardEmulation.EnableService function in that function.
Activity and ComponentName are requested as parameters of the function.
The ComponentName area was handled easily, but I don't know how to get the Activity. Please advise.
This is the contents of enable_Card function of hceService.
private Activity activity = null;
private bool enable_Card(cardModel card)
{
try
{
sid = card.cardSN;
tag = "Felica";
emulation.EnableService(, componentName); //<- How to get Activity??
emulation.SetNfcid2ForService(componentName, sid);
return true;
}
catch
{
return false;
}
}
This is my first time asking a question on Stackoverflow.
I would appreciate it if you could point out any missing or incorrect parts.
I trying this
activity = Xamarin.Essentials.Platform.CurrentActivity; //<- this function is not found!
Added missing information!
The namespace of the Enable_Card function is located in hceSample.Service.
Are you using the NfcFCardEmulation.EnableService(Activity, ComponentName) Method, right?
The method is an android api from android sdk,you cannot use it directly in xamarin.form(yours is hceSample) project.
If you want to call the function in xamarin form project(hceSample) from native platform(hceSample.Android, or hceSample.iOS),you can use Xamarin.Forms DependencyService to achieve this.
The DependencyService class is a service locator that enables Xamarin.Forms applications to invoke native platform functionality from shared code.
For more information about DependencyService, you can check document Xamarin.Forms DependencyService. And there is a sample included in above document,which is helpful for you to understand DependencyService.
Note:
We recognize that hardware service is the right and ideal way to
implement in each OS project. However, I'm curious if there is a way
to code Android and iOS at the same time
Since the api you used is from android sdk, you can call it in native android or use DependencyService to call it on xamarin.form(yours is hceSample) project.
If you call it on xamarin.form(yours is hceSample) project, you also need to find the the corresponding function or interface in iOS.

AddWebAllowedObject is not working when .Net Native Tool Chain is Enabled

I have created UWP app which has a webview embedded in it. The webview is loaded with URL of a web app.
The web app has a JavaScript object added to the window object.
example:window.html_communicator
The web app uses this html_communicator object and calls certain methods on it to invoke callbacks on the UWP application.
for example, there can be a method defined on html_communicator called onLocationSelect and the web app will call this method upon some user interaction.
The UWP app registers to the methods by calling addWebAllowedObject on the WebView.
The callbacks are working fine when I disabled .Net Native Tool Chain.
But these callbacks are not working fine when .Net Natvie Tool Chain is enabled.
Below is a javascript code snippet that calls the bridge method on button click.
var html_communicator = html_communicator || {};
window.onload = function () {
document.getElementById("locationSelect")
.addEventListener("click", () => {
if (html_communicator && html_communicator.onLocationSelect) {
document.getElementById("msg").innerHTML = `Successfully called bridge method: Button clicked at ${new Date()}`;
sumorea_app.onLocationSelect();
}
else {
document.getElementById("msg").innerHTML = `Failed to call bridge method: Button clicked at ${new Date()}`;
}
})
}
The callbacks are working fine when I disabled .Net Native Tool Chain. But these callbacks are not working fine when .Net Natvie Tool Chain is enabled.
Please refer to webview official document, In addition, trusted JavaScript content in WebView can be allowed to directly access Windows RuntimeAPI. This provides powerful native capabilities for web apps hosted in WebView. To enable this feature, the Uniform Resource Identifier (URI) for trusted content must be added to the allowlist in the ApplicationContentUriRules of the app in Package.appxmanifest, with WindowsRuntimeAccess specifically set to "all".
For Xamarin solution, you need check if has add above allowlist for UWP project.

Load startup model in platform project code and pass it to PCL on Xamarin Forms Initialization

The application I'm currently working on requires data to be retrieved from a web service during app startup that roughly takes 1.5 seconds. After the data is retrieved, it needs to be displayed on the MainPage and that is another 1.5 - 2 seconds since the data is mostly URLs of images that have to be displayed, in my case, using ffimageloading library; which means actually downloading those images first to be displayed.
I have splash startup screens for both Android and iOS implemented separately in platform projects but splash screen only stays up for the amount of time Xamarin Forms needs to load and afterwards disappears not waiting for my actual model to load from the web service. I have searched for solutions to extend the splash screen duration and mostly every solution I have read involves creating another splash screen page, loading page if you will, that is already controlled in PCL project but having two separate splash loading screens just seams not feasible to me at the moment.
So I was wondering, how would one load the initial model in platform projects, during the actual splash screen, and then later pass it to PCL project when Xamarin Forms has finished initialization, presumably to App.xaml.cs 's App() constructor function?
There is no code or enough details so I am assuming this is what you want to do.
Call the APIs asynchrnously , till then show splash screen.
Before assigning MainPage in your App.xaml.cs you should call these APIs asynchronously with await and then you use the same for binding of your mainpage
public App()
{
InitializeComponent();
//do all my prefetch stuff for app initialization.
// API and what not
var viewmodel = new AppMainViewModel();
await viewmodel.CallFooFetchAsync();
await viewmodel.BlahBlahAsync();
MainPage = new NavigationPage(new AppMainPage(viewmodel));
}
In Page
public AppMainPage(AppMainViewModel vm)
{
BindingContext =vm;
}
So by the time page loads it has all the data handy.
You can explore adding this code in OnAppearing of the page.
Note that the concept of default Splash screen is just to show an image(with different theme in Android) and setting image in iOS. You need to have conventional UI technically its not splash screen anymore.
Alternatively you can get shared project handle in native
Android Sp
protected override void OnCreate(Bundle bundle)
{
...
var app = new App(); //this will be shared project App object
Device.BeginInvokeOnMainThread(async () => await app.DoPrefetchStuffFirst()); //API calls if needed in this async method
//then
LoadApplicationm(app)
}
You can do similar thing in iOS AppDelegate
And if you call native specific methods in platforms (may be for API calls) then you would use DependencyService feature , that will pass it to shared project or Custom renderer based on where you want to use it.

Xamarin Forms - How to open specific page after clicking on notification when the app is closed?

I'm actually working on a Xamarin Forms application that need push notifications. I use the Plugin.PushNotification plugin.
When the app is running in the foreground or is sleeping (OnSleep), I have no problem to open a specific page when I click on a notification that I receive. But I was wondering how can I do that when the app is closed. Thanks!
I finally found the answer by myself and I want to share it in case someone needs it.
Nota bene: according to the official documentation of the plugin, it's Xam.Plugin.PushNotification that is deprecated. I use the new version of this plugin, Plugin.PushNotification which uses FCM for Android and APS for iOS.
There is no significant differences to open a notif when the app is running, is sleeping or is closed. Just add the next callback method in the OnCreate method (MyProject.Droid > MainApplication > OnCreate) and FinishedLaunching method (MyProject.iOS > AppDelegate > FinishedLaunching):
CrossPushNotification.Current.OnNotificationOpened += (s, p) =>
{
// manage your notification here with p.Data
App.NotifManager.ManageNotif(p.Data);
};
Common part
App.xaml.cs
// Static fields
// *************************************
public static NotifManager NotifManager;
// Constructor
// *************************************
public App()
{
...
NotifManager = new NotifManager();
...
}
NotifManager.cs
public class NotifManager
{
// Methods
// *************************************
public void ManageNotif(IDictionary<string, object> data)
{
// 1) switch between the different data[key] you have in your project and parse the data you need
// 2) pass data to the view with a MessagingCenter or an event
}
}
Unfortunately there is no succinct answer for either platform. Generally speaking, you need to tell the OS what to do when it starts the app as a result of the push notification. On both platforms, you should also consider what API level you are targeting, otherwise it won't work or even crash the app.
On iOS, you will need to implement this method in AppDelegate appropriately: FinishedLaunching(UIApplication application, NSDictionary launchOptions). The launchOptions will have the payload from the push notification for you to determine what to do with it (e.g. what page to open). For more information on iOS, Xamarin's documentation is a good place to start.
Android has a more complicated topology in terms of more drastic differences between API levels, whether you are using GCM/FCM, as well as requiring more code components. However, to answer the question directly, you will need to handle this in OnCreate(Bundle savedInstanceState) of your main Activity. If you are using Firebase, the push notification payload is available in Intent.Extras. Again, Xamarin's documentation has a good walkthrough.
Finally, note that the Plugin.PushNotification library you are using has been deprecated. I suggest you either change your library and/or your implementation soon. Part of the reason that library has been deprecated is because Google has deprecated the underlying Google Cloud Messaging (GCM) service, which will be decommissioned on April 11, 2019.

How do I clear the cache of Cordova Web View on Windows Phone 8?

I'm developing a Cordova 2.9.0 app for Windows Phone 8. The app in question utilises external content heavily, using the JS and HTML content that's being served from another source. It all works fine, but the browser component caches heavily.
The only way I have discovered to clear caches is to uninstall-install the app again to take effect. The downside to this is that my localStorage also clears, slowing down my cycles.
I presume the cache can be cleared by writing extra C# into the Cordova template they serve, which I use by the way.
So while it was not that critical, I did stumble to a working answer. The WebBrowser class does have a suitable method to call: ClearInternetCacheAsync.
Since CordovaBrowser inherits from WebBrowser, it's just a matter of adding one line to MainPage.xaml.cs where the C# init of the start page happens:
namespace FooBarApp
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.CordovaView.Loaded += CordovaView_Loaded;
// blammo!
this.CordovaView.CordovaBrowser.ClearInternetCacheAsync();
}
Phonegap Cookies Plugin can be found HERE
A simple, lightweight jQuery plugin for reading, writing and deleting cookies can be found HERE
I hope it will resolve your problem. Thanks!!

Resources