When I use Portable.Ninject in a Xamarin.Forms app, instantiating the StandardKernel always results in a NotImplementedException.
I can consistently replicate the problem as follows:
Create Xamarin.Forms application (in VS2017: Cross Platform App (Xamarin))
Configure it to use PCL
I'm only interested in Android and for the sake of brevity, I removed all other platform projects.
Add NuGet Package Portable.Ninject to the PCL and Android platforms
Then, in App.xaml.cs I simply try the following:
public App()
{
InitializeComponent();
//ommitting NinjectModules for brevity
var kernel = new Ninject.StandardKernel(); //exception is thrown here
MainPage = new NavigationPage(new MainView());
}
What am I missing here?
Currently I'm using Portable.Ninject version 3.3.1.
I also tried the XLabs.IoC.Ninject package (which also uses Portable.Ninject) and got the same result.
For those who experience the same problem:
tldr; clean you projects, and rebuild.
Explanation: At first I had only added Ninject to my PCL, and had forgotten to add it to the Android project. Although I added the Ninject library to the Android project soon afterwards, it would still result in the exception being thrown.
The solution was to clean the projects and rebuild them. Sometimes it's just that easy!
Related
I have a Xamarin application in which I have included the Syncfusion Datagrid control. I am trying to deploy this to an IOS simulator in visual studio. I have added the NuGet package and included a community license. However, it wasn't displaying on the screen. To fix this I added the following line of code, as advised by https://www.syncfusion.com/forums/137574/no-visible-data-grid-on-ios-platform-only.
Syncfusion.SfDataGrid.XForms.iOS.SfDataGridRenderer.Init();
However, this now results in my application crashing with the only debugger info being:
main.cs:
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate"); #System.NullReferenceException: 'Object reference not set to an instance of an object'
}
AppDelegate.cs:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
Syncfusion.SfDataGrid.XForms.iOS.SfDataGridRenderer.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
If I haven't given you enough info about my setup please just ask and I will happily provide it. :)
Thanks in advance!
I don't know what the cause of the problem was, however, by downgrading my Xamarin.Forms and Xamarin.Essentials package to versions 4.5.0.495 and 1.3.1 respectively I no longer got the error and the screen was displayed properly.
I figured this out by making a new test project and trying to recreate my code. Then I tried running it and it worked. Thus I changed the versions of my original code to the versions that worked in the project that was generated by a Xamarin template.
Thanks everyone for their help :)
I too have experienced this same issue; after recent updates, my app crashed with a null exception on the main.cs in iOS. I finally isolated and resolved what was triggering the issue.
The problem occurred when I populated a SfDataGrid with more rows than could fit on a (cross platform, iOS) simulator screen; this would trigger a crash as soon as I tried to scroll vertically or horizontally. If the number of rows was less than the screen size, however, it didn't crash. The app also worked fine a week or so ago.
It turns out that there appears to be a bug in the latest release of Xamarin.Forms version 4.6.0.968. By downgrading Xamarin.Forms to version 4.6.0.847, the problem was resolved.
The following link provides further details On this issue:
https://www.syncfusion.com/forums/155376/sfdatagrid-crashes-app-when-user-start-to-scroll-the-content-18-1-0-57
https://github.com/xamarin/Xamarin.Forms/issues/11132
You do not need the renderer initialization if you are using Xamarin.iOS platform and not the cross-platform.
In case, if you are using the iOS version of Xamarin.Forms, then refer the getting started documentation here to know the step by step configuration of the DataGrid component. Confirm that you have installed the Syncfusion.Xamarin.SfDataGrid NuGet package.
In case, if you are using the Xamarin.iOS platform itself, then please refer the documentation here for the step by step configurations and be sure that you have installed the Syncfusion.Xamarin.SfDataGrid.IOS package.
I hope that helps.
I'm writing an Android Wear app using Xamarin. I'm using the Microsoft.Extensions.DependencyInjection library to handle service dependency injection in my app. It works completely fine when I run the app in Debug mode through Visual Studio (Ctrl + F5), on my actual smartwatch. The app functions correctly and everything. When I publish the app using the "Archive..." function of the Xamarin toolset and then sideload the published version onto my Smartwatch, however, the app crashes at startup with an exception stating System.InvalidOperationException: A suitable constructor for type 'My.Library.SomeManager' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.. This spawns from a call to IServiceProvider.GetService for the SomeManager type.
I don't know why this would be. I'm logging to logcat when I register the services, and can see them being registered in the published version, but for some odd reason, the dependency injection engine is not able to find them. I don't know enough about the inner workings of Xamarin to choose a direction to troubleshoot this. Does anybody know what would be causing this odd behavior?
Assuming your Release configuration has the Linker set to something other than None?
Classes, constructors and/or methods that are only referenced via reflection calls for activation and used via interfaces (typical for DI) can not be seen by the static analysis that the Mono Linker performs and thus are stripped from the assembly(s) in order the get the final app bundle size down to a "acceptable" size.
Note: This process is comparable to the Proguard tool, and its replacement,R8, used to strip un-used Java code and has the some "limitation" and most of my Xamarin.Android projects end up with a custom Mono linker and Proguard/R8 config file.
If you do not "own" the code that is being stripped, you can manually reference a class/method so the Linker does not strip it:
[Preserve]
public static class LinkerPreserve
{
static LinkerPreserve()
{
throw new Exception(typeof(My.Library.SomeManager).FullName);
}
}
If you own the code, you can apply the PreserveAttribute to the class.
[Preserve]
public class SomeManager
{
~~~~
}
You can also apply the --linkskip=ASSEMBLY in the build options...
Refer the docs for details:
https://developer.xamarin.com/api/type/MonoTouch.Foundation.PreserveAttribute/
It take full control of the Mono linking process you can create a custom linking config file:
https://learn.microsoft.com/en-us/xamarin/cross-platform/deploy-test/linker
Have been having a little issue for the last couple of days now where I will create a new Xamarin Forms project on Visual Studio 2017 and add a Xamarin.UITest Cross-Platform Test Project for unit testing I recieve a series of NU1201 Errors when I reference the .Android App in the UITest Project.
Here is the exact error i get:
Error NU1201 Project App1.Android is not compatible with net461 (.NETFramework,Version=v4.6.1) / win-x64. Project App1.Android supports: monoandroid81 (MonoAndroid,Version=v8.1)
I have played around with the Android version numbers to see if the UITesting package doesnt support the latest android but no matter what version of android i target the problem remains the same.
Here is a screenshot of the project.
All the code is unchanged from the default project and runs in the simulator fine but only produces these errors when the Android app is referenced to the UITest project.
Solved it after many more hours of testing and trialling. Instead of adding the Android project to the references, Within the AppInitializer I added another method to the StartApp() call like so:
public class AppInitializer
{
public static IApp StartApp(Platform platform)
{
if (platform == Platform.Android)
{
return ConfigureApp.Android.InstalledApp("com.companyname.App1").StartApp();
}
return ConfigureApp.iOS.StartApp();
}
}
Therefore once I had already run the app via the emulator for the first time and installed on the device, the UITest simply uses the installed APK on the emulator instead of the project.
For those who ran into error NU1201, you might have come to the right place. This may not apply to the question asked but I ran into error NU1201 the other day and the reason for that is the nuproj configuration file for our nuget project has target configuration wrong. It should have been
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
instead of
<TargetFramework>net462</TargetFramework>
because the project is not of "SDK-style."
References: https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-target-framework-and-target-platform?view=vs-2019
After reviewing my options regarding saving JWT token, I chose Xamarin.Essentials Secure Storage.
Problem being that my app always breaks when trying to save a token within the storage with the following error:
"System.AggregateException has been thrown"
The details are as follow:
"Xamarin.Essentials.NotImplementedInReferenceAssemblyException
This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation."
This clearly means that something went wrong in the installaion of the nuget package, so I:
Uninstalled and reinstalled the xamarin.essentials package.
Upgraded .Netstandard to 2.0, thinking that 1.6 wasn't compatible.
Checked if the package is referenced within the csproj file.
So forth, nothing.
For now, I have a TokenStorageController with the following lines of codes :
public bool SaveToken(string token)
{
if(token != null)
{
Preferences.Set(key, token);
if(Preferences.ContainsKey(key))
{
return true;
}
}
return false;
}
The RestService class from where the controller gets called looks like this :
//await SecureStorage.SetAsync("oauth_token", "booommmmmm"); // changed to this simply to check if my controller was the problem
TokenStorageController tokenStorage = new TokenStorageController();
await tokenStorage.SaveToken("boommmmm"); // where I get an error
And here is the exact line where the error occurs:
var loginTask = Task.Run(() => restService.LoginAsync(user)).Result;
If no solutions, I will remove all packages and reinstall them all. ONE BY ONE! I swear I'll do it!
And if no solutions at all, I will store the token within SQL as I already have a controller in place to do so.
I am a Xamarin and C# noob so bear with me please.
FYI: I am using a macOS client for testing purposes, as the cause could be that SecureStorage doesn't work for macOS apps.
Thanks!
Xamarin.Mac is not currently a supported platform, just iOS, Android, UWP.
The code is available for review at:
https://github.com/xamarin/Essentials/tree/master/Xamarin.Essentials/SecureStorage
i am trying to install MVVMCross plugin in UWP project but it seems to fail.
in the PCL it seems to be working fine, but in the UWP I'm expecting that the plugin will create a Bootstrap folder and it doesn't happen.
I even started a new project from scratch named it "TipCalc.WindowsUWP", installed the MVVMCross and then the JSON plugin using NuGet and nothing happens.
the output of the plugin installation looks fine:
Restoring packages for 'TipCalc.WindowsUWP'.
Restoring packages for C:\Users\kayce\Documents\Visual Studio 2015\Projects\TenBisServer\MvvmCross\TipCalc\TipCalc.WindowsUWP\project.json...
Package restore completed successfully for 'TipCalc.WindowsUWP'.
Successfully installed 'MvvmCross.Plugin.Json 4.2.3' to TipCalc.WindowsUWP
========== Finished ==========
what I am missing ?
This is expected behavior, as a UWP project uses a project.json (NuGet 3) template. Currently all additional content and scripting specified in the NuGet package with have no affect on your project when including a package (See Changes affecting existing packages).
You will have to manually add the bootstrap folder and relevant plugin bootstrap .cs file, or you can register the interface and implementation of the plugin in your Setup.cs.
Bootstrap Approach:
using MvvmCross.Platform.Plugins;
namespace <<YOUR_NAMESSPACE>>.Bootstrap
{
public class JsonPluginBootstrap
: MvxPluginBootstrapAction<MvvmCross.Plugins.Json.PluginLoader>
{
}
}
Setup.cs Approach:
protected override void InitializeLastChance()
{
base.InitializeLastChance();
Mvx.RegisterSingleton<IMvxJsonConverter>(new MvxJsonConverter());
}