I am following this tutorial for SQLite practice in Xamarin:
https://code.tutsplus.com/tutorials/an-introduction-to-xamarinforms-and-sqlite--cms-23020
Now I am stuck here in
public RandomThoughtDatabase ()
{
_connection = DependencyService.Get"ISQLite" ().GetConnection ();
}
ISQLite is an interface in PCL
its giving this error
Error CS0119 'DependencyService.Get(DependencyFetchTarget)' is a method, which is not valid in the given context LocalStorage
Use the following instead:
public RandomThoughtDatabase () { _connection = DependencyService.Get<ISQLite>().GetConnection(); }
Related
I'm trying to login with integration to social networks, more specifically to Google in .NET MAUI. I've done it with Xamarin Forms and it worked perfectly, however, in MAUI a standard error is occurring:
Error CS0246 The type or namespace name 'Android' could not be found (are you missing a using directive or an assembly reference?) LoginWithRedes (net6.0-ios), LoginWithRedes (net6.0-maccatalyst), LoginWithRedes (net6.0-windows10.0.19041) C:\MAUI\LoginWithRedes\LoginWithRedes\Platforms\Android\GoogleManager.cs
Libraries not being recognized
Packages I added to the project
Code of the GoogleManager.CS Class where the standard error occurs to me:
`[assembly: Dependency(typeof(GoogleManager))]
namespace LoginWithRedes.Platforms.Android
{
public class GoogleManager : Java.Lang.Object, IGoogleManager, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener
{
public static GoogleApiClient _googleApiClient { get; set; }
public static GoogleManager Instance { get; private set; }
public bool IsLogedIn { get; set; }
Context _context;
public GoogleManager()
{
_context = global::Android.App.Application.Context;
Instance = this;
}
public void Login()
{
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
.RequestEmail()
.Build();
_googleApiClient = new GoogleApiClient.Builder((_context).ApplicationContext)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
.AddScope(new Scope(Scopes.Profile))
.Build();
Intent signInIntent = Auth.GoogleSignInApi.GetSignInIntent(_googleApiClient);
((MainActivity)Forms.Context).StartActivityForResult(signInIntent, 1);
_googleApiClient.Connect();
}
public void Logout()
{
var gsoBuilder = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn).RequestEmail();
GoogleSignIn.GetClient(_context, gsoBuilder.Build())?.SignOut();
_googleApiClient.Disconnect();
}
public void OnAuthCompleted(GoogleSignInResult result)
{
if (result.IsSuccess)
{
IsLogedIn = true;
Application.Current.MainPage = new MainPage();
}
else
{
}
}`
OnActivityResult method that I implemented in MainActivity class
If anyone can help me with this error, I would be very grateful.
Note: I'm new to Xamarin and Maui.
Thank you very much in advance
I'm also new to Maui, and in my experience, these errors were caused by using native Xamarin libraries in Maui. Xamarin targets each platform separately using separate nuget packages. Maui's combined 1-project architecture means you need to use packages that work for both at once.
At least when I was getting started a few months ago, these weren't readily available. Firebase client was not yet released for .NET 6.0 (Multiplatform by default).
Things may have changed since then. But I had great success using Firebase with this plugin https://github.com/TobiasBuchholz/Plugin.Firebase. It wraps up the platform specific libraries into a single project API, with a really easy to use c# interface. You can use await and stuff as you would expect. Calling the native APIs was difficult, and required a lot of code duplication. This plugin saves a lot of time, and I haven't yet run into any problems.
The documentation on the plugin is a bit sparse, but hey, it's free and works.
I have an interface
SQLiteConnection _connection = Getconnection();
public SQLite.SQLiteConnection GetConnection()
{
const string sqliteFilename = "TCRMobile.db3";
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
var dbPath = Path.Combine(documentsPath, sqliteFilename);
return new SQLite.SQLiteConnection(dbPath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex, false);
}
So when I kill my app or in any random case, the app crashed. And App Center says reason for crash as:
Cache.get_Connection ()
System.InvalidOperationException: You MUST call Xamarin.Forms.Init(); prior
to using it.
Device.get_PlatformServices ()
Device.GetAssemblies ()
DependencyService.Initialize ()
DependencyService.Get[T] (Xamarin.Forms.DependencyFetchTarget fetchTarget)
Cache.get_Connection ()
TCRMobile.DataAccess.DataAccessBase..cctor () [0x00005] in
<7ccb325064fd467288e39511a2bcad63>:0
I added global::Xamarin.Forms.Forms.Init(this, bundle); in MainActivity.cs file. But still it crashes.
Any help?
First of all, make sure that in your MainActivity.cs (Android) / AppDelegate.cs (iOS) the Forms.Init gets called before the making of the App.
So something like this would be the correct approach
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
If the above is correct, check the flow.
You should have
An interface in your portable class
public interface ISQLite
{
SQLiteConnection GetConnection();
}
An implementation for each platform (so iOS/Android/UWP) containing an assembly tag
Android example
[assembly: Xamarin.Forms.Dependency(typeof(SqLiteAndroid))]
namespace Your.Namespace.Droid
{
public class SqLiteAndroid:ISQLite
{
public SQLiteConnection GetConnection()
{
//return connection here
}
}
}
and iOS example, same principle but notice the different namespace and assembly
[assembly: Xamarin.Forms.Dependency(typeof(SqLiteiOS))]
namespace Your.Namespace.iOS
{
public class SqLiteiOS:ISQLite
{
public SQLiteConnection GetConnection()
{
//return connection here
}
}
}
A call to the DependencyService to get the connection e.g. in your App.xaml.cs
string sqlConnection= DependencyService.Get<ISQLite>().GetConnection()
Let me know if this works for you, if not, please provide some more code.
I get this problem, when I call the Database.EnsureDeleted() and Database.EnsureCreated() methods.:
Unhandled Exception:
System.Reflection.TargetParameterCountException: Number of parameters
specified does not match the expected number.
Here the init code of EF in a Xamarin Forms project.
public class DatabaseContext : DbContext
{
private readonly string _dbPath;
public DatabaseContext (string dbPath = null) : base()
{
_dbPath = dbPath ?? App.DatabasePath;
Database.EnsureDeleted();
Database.EnsureCreated();
}
}
And under the Android project here the code:
LoadApplication(new App());
App.DatabasePath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "database.sqlite");
_dbPath = dbPath ?? App.DatabasePath;
You are using a ternary operator, so you need to provide 2 resulting elements:
_dbPath = dbPath ?? App.DatabasePath : dbPath;
Unfortunately, Visual studio does not show the full exceptions for Xamarin.Forms.
Make sure to surround your code with try clause, and read the full exception message.
for me, the problem solved by including Id field (Primary Key) in HasData method.
I can't seem to get off dead center with SQLite.Net-PCL; I have a Xamarin forms solution with a PCL proj, Droid proj, iOS proj, and Windows Universal project. I have installed the nuget packages for SQLite.Net-PCL and SQLite.Net.Core-PCL.
So, I go over to the github project to find some awesome examples to get started and none of them work; apparently you have to pass a platform into the database connection, but I get a reference error on them all (such as SQLitePlatformWin32).
Search the web for the references and... nothing. Search nuget for the platforms and... nothing.
What am I missing? (yes, I feel dumb)
An example they have is
public class Database : SQLiteConnection
{
public Database(string path) : base(new SQLitePlatformWin32(), path)
{
CreateTable<Stock>();
CreateTable<Valuation>();
}}
and I get a reference error that I can't resolve on the "new SQLitePlatformWin32" line.
For anyone else struggling, here is what you need to do.
Install the SQLite.Net-PCL, SQLite.Net.Core-PCL and SQLite.Net.Async-PCL nugets
Create an interface for ISQLite in your PCL:
public interface ISQLite
{
SQLiteConnection GetConnection();
}
Call GetConnection via DependencyService
PatientDatabase = DependencyService.Get<ISQLite>().GetConnection();
PatientDatabase.CreateTable<Patient>();
The above will create the connection based on your platform (i.e. android, ios). In each platform's project, you must have a GetConnection that is accessable via DependencyService such as this for Android
[assembly: Xamarin.Forms.Dependency(typeof(SQLite_Android))]
// ...
public class SQLite_Android : ISQLite
{
public SQLite_Android() { }
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "TodoSQLite.db3";
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
var path = Path.Combine(documentsPath, sqliteFilename);
// Create the connection
var conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), path);
// Return the database connection
return conn;
}
}
My problem was I was trying to create the connection in my PCL and I couldn't find the platforms, what you need to do is create the connection in each individual project.
Have a WPF app that I am converting to ASP.net and I am having issues with SAP.
When I run this line I get an exception.
RfcDestinationManager.RegisterDestinationConfiguration(Backend);
Exception Message {"exePath must be specified when not running inside a stand alone exe."}
Stack Trace
at System.Configuration.ConfigurationManager.OpenExeConfigurationImpl(ConfigurationFileMap fileMap, Boolean isMachine, ConfigurationUserLevel userLevel, String exePath, Boolean preLoad)
at System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel userLevel)
at SAP.Middleware.Connector.RfcConfigParameters..cctor()
googling around I saw as similar issue here exePath must be specified when not running inside a stand alone exe
The issue seems to be using ConfigurationManager.OpenExeConfiguration rather that System.Web.Configuration.WebConfigurationManagerwhich is what I need to use. Problem is I can't change that as its part of the SAP.Net Connector.
Is there anything I can do?
Edit: My BackendConfig code
public class BackendConfig : IDestinationConfiguration
{
public RfcConfigParameters GetParameters(String destinationName)
{
if ("P38".Equals(destinationName))
{
var parms = new RfcConfigParameters
{
{RfcConfigParameters.AppServerHost, "SAPSERVER"},
{RfcConfigParameters.SystemNumber, "86"},
{RfcConfigParameters.SncMode, "1"},
{RfcConfigParameters.SncPartnerName, "p:SAP#SERVER"},
{RfcConfigParameters.Client, "010"},
{RfcConfigParameters.Language, "EN"},
{RfcConfigParameters.PoolSize, "5"}
};
return parms;
}
else return null;
}
// The following two are not used in this example:
public bool ChangeEventsSupported()
{
return false;
}
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
}