Closed gaurakshay closed 3 years ago
Here is a sample project that has the server, and the Xamarin project that replicates the issue.
I am also going to try this on a physical iPhone rather than a simulator.
Did you try to call SQLitePCL.Batteries.Init()
on IOS ? It's mandatory otherwise It won't work on IOS.
Here are the guidelines : https://github.com/ericsink/SQLitePCL.raw/wiki/SQLitePCL.Batteries.Init#where-should-i-call-sqlitepclbatteries_v2init
Let me know if it's resolving your issue
Thanks @Mimetis . I plan on trying out a couple of other libraries that can be used to support SQLite on iOS device. Currently, I am only using sqlite-net-pcl.
I have tried adding a call to SQLitePCL.Batteries_V2.Init()
on the iOS simulator.
(_If I don't add the call to SQLitePCL.Batteries_V2.Init()
, I am getting the error:_
You need to call SQLitePCL.row.SetProvider(). If you are using a bundle package, this is done by calling SQLitePCL.Batteries.Init().
)
As per your advise I have added a call to SQLitePCL.Batteries_V2.Init()
and I am getting the same error as I listed in the original issue reported.
I have tested and I am able to add new entries in the database as well as query them without any issues on the iOS emulator. The only error that I encounter is when I call agent.SynchronizeAsync()
.
No idea I you're able to debug the source code, maybe you can get the internal error raised ?
I will try...
I can now confirm that my initial report was incorrect. The exception is being thrown on an iOS device even if there are no filters applied to the tables which are participating in sync.
This is the exception stack trace which I was able to get:
[0:] Dotmim.Sync.SyncException: byref delegate ---> System.NotImplementedException: byref delegate
at System.Linq.Expressions.Interpreter.LightLambda.CreateCustomDelegate (System.Type delegateType) [0x001cf] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightLambda.cs:422
at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00012] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightLambda.cs:446
at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate (System.Runtime.CompilerServices.IStrongBox[] closure) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightDelegateCreator.cs:33
at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightDelegateCreator.cs:28
at System.Linq.Expressions.Expression`1[TDelegate].Compile (System.Boolean preferInterpretation) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs:211
at System.Linq.Expressions.Expression`1[TDelegate].Compile () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs:192
at System.Runtime.CompilerServices.CallSite`1[T].CreateCustomNoMatchDelegate (System.Reflection.MethodInfo invoke) [0x0002b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs:668
at System.Runtime.CompilerServices.CallSite`1[T].MakeUpdateDelegate () [0x00010] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs:304
at System.Runtime.CompilerServices.CallSite`1[T].GetUpdateDelegate (T& addr) [0x0000d] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs:234
at System.Runtime.CompilerServices.CallSite`1[T].GetUpdateDelegate () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs:224
at System.Runtime.CompilerServices.CallSite`1[T]..ctor (System.Runtime.CompilerServices.CallSiteBinder binder) [0x00007] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs:167
at System.Runtime.CompilerServices.CallSite`1[T].Create (System.Runtime.CompilerServices.CallSiteBinder binder) [0x0002c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs:216
at Dotmim.Sync.SyncTypeConverter.TryConvertTo[T] (System.Object value, System.Globalization.CultureInfo provider) [0x012e7] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.SyncTypeConverter.TryConvertFromDbType (System.Object value, System.Data.DbType typeOfT, System.Globalization.CultureInfo provider) [0x00097] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.DbSyncAdapter.SetParameterValue (System.Data.Common.DbCommand command, System.String parameterName, System.Object value) [0x0002b] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.DbSyncAdapter.SetColumnParametersValues (System.Data.Common.DbCommand command, Dotmim.Sync.SyncRow row) [0x00072] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.DbSyncAdapter+<>c__DisplayClass24_0.<ApplyChangesAsync>b__0 () [0x0007e] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.DbSyncAdapter+<>c__DisplayClass24_0.<ApplyChangesAsync>b__0 () [0x00376] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.DbSyncAdapter.ApplyChangesAsync (Dotmim.Sync.SyncContext context, System.Guid localScopeId, System.Guid senderScopeId, Dotmim.Sync.SyncTable changesTable, System.Int64 lastTimestamp, System.Collections.Generic.List`1[T] conflicts, Dotmim.Sync.InterceptorWrapper`1[T] iTableChangesBatchApplying, System.Data.Common.DbConnection connection, System.Data.Common.DbTransaction transaction, System.Threading.CancellationToken cancellationToken) [0x002ce] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.BaseOrchestrator.InternalApplyTableChangesAsync (Dotmim.Sync.SyncTable schemaTable, Dotmim.Sync.SyncContext context, Dotmim.Sync.MessageApplyChanges message, System.Data.Common.DbConnection connection, System.Data.Common.DbTransaction transaction, System.Data.DataRowState applyType, Dotmim.Sync.DatabaseChangesApplied changesApplied, System.Threading.CancellationToken cancellationToken, System.IProgress`1[T] progress) [0x004ac] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.BaseOrchestrator.InternalApplyChangesAsync (Dotmim.Sync.SyncContext context, Dotmim.Sync.MessageApplyChanges message, System.Data.Common.DbConnection connection, System.Data.Common.DbTransaction transaction, System.Threading.CancellationToken cancellationToken, System.IProgress`1[T] progress) [0x004d4] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.LocalOrchestrator+<>c__DisplayClass7_0.<ApplyChangesAsync>b__0 (Dotmim.Sync.SyncContext ctx, System.Data.Common.DbConnection connection, System.Data.Common.DbTransaction transaction) [0x00151] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.BaseOrchestrator.RunInTransactionAsync[T] (Dotmim.Sync.Enumerations.SyncStage stage, System.Func`4[T1,T2,T3,TResult] actionTask, System.Threading.CancellationToken cancellationToken) [0x00239] in <1938b9d809814d548672472ac82fe072>:0
--- End of inner exception stack trace ---
at Dotmim.Sync.BaseOrchestrator.RaiseError (System.Exception exception) [0x00046] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.BaseOrchestrator.RunInTransactionAsync[T] (Dotmim.Sync.Enumerations.SyncStage stage, System.Func`4[T1,T2,T3,TResult] actionTask, System.Threading.CancellationToken cancellationToken) [0x00376] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.BaseOrchestrator.RunInTransactionAsync[T] (Dotmim.Sync.Enumerations.SyncStage stage, System.Func`4[T1,T2,T3,TResult] actionTask, System.Threading.CancellationToken cancellationToken) [0x00429] in <1938b9d809814d548672472ac82fe072>:0
at Dotmim.Sync.SyncAgent.SynchronizeAsync (Dotmim.Sync.Enumerations.SyncType syncType, System.Threading.CancellationToken cancellationToken, System.IProgress`1[T] progress) [0x00cca] in <1938b9d809814d548672472ac82fe072>:0
at TeamManagement.Xam.Form.ViewModels.MainPageViewModel.OnSyncRequestAsync () [0x0007e] in C:\Users\agaur\source\github\TeamManagement\TeamManagement.Xam.Form\ViewModels\MainPageViewModel.cs:47
The code that I am using for the synchronization on the client is simply:
var webClientOrchestrator = new WebClientOrchestrator("<url>/api/sync");
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "test.db");
var clientProvider = new SqliteSyncProvider(databasePath);
// Creating an agent that will handle all the process
var agent = new SyncAgent(clientProvider, webClientOrchestrator);
try
{
// Launch the sync process
var s1 = await agent.SynchronizeAsync();
Debug.WriteLine(s1);
}
catch (Exception ex)
{
var st = ex.ToString();
Debug.WriteLine(st);
}
Is there anything specific that I can provide that might help analyze this issue?
I tried to use Source Link
and Symbol Files (nuget server)
but Xamarin.Forms app is not letting me step into the code. I can step into the code without any issues in a test console app so I am not sure what is causing the issues with stepping into your code using Xamarin.Forms app.
Thank you.
Can you try to debug with the source code cloned on your machine ?
Seems you have a problem with Dotmim.Sync.SyncTypeConverter.TryConvertTo[T]
This method is just making a type conversion.
I think I am beginning to understand this issue a little better. I believe (this is only a hunch) that whenever there is something to download from the server, the error is being thrown. This is the only logical explanation of what I am seeing so far.
@Mimetis Downloading the code onto my machine and debugging it is literally what popped into my head late yesterday. I will try to do this today.
So for some reason, on iOS, the following TypeConversion fails:
if (Guid.TryParse(value.ToString(), out Guid j))
return (T)Convert.ChangeType(j, typeOfT, provider);
This piece of code is in SyncTypeConverter.cs
, line number 75
. value
that is passed is "3743d190-288c-4de2-fdef-08d85676f789"
which is a valid Guid value.
Interestingly, this doesn't fail on Android emulator which I checked.
Running this simple piece of code is enough to confirm that Xamarin.iOS is unable to use dynamic
variable when calling Guid.TryParse
.
dynamic guidDynamic= "3743d190-288c-4de2-fdef-08d85676f789";
if (Guid.TryParse(guidDynamic.ToString(), out Guid j)) // this fails.
Debug.WriteLine("succesful");
Interestingly, if I slightly tweak the method to something like below, it works just fine:
dynamic guidDynamic= "3743d190-288c-4de2-fdef-08d85676f789";
string guidString= guidDynamic.ToString(); // convert dynamic value to string value
if (Guid.TryParse(guidString, out Guid j)) // this works.
Debug.WriteLine("succesful");
To test this, I changed the SyncTypeConverter.cs
class slightly:
else if (typeOfT == typeof(Guid))
{
string valueStr = value.ToString(); // added this
if (Guid.TryParse(valueStr, out Guid j)) // changed value.ToString() to valueStr
return (T)Convert.ChangeType(j, typeOfT, provider);
else if (value.GetType() == typeof(byte[]))
return (T)Convert.ChangeType(new Guid(value as byte[]), typeOfT, provider);
else
return (T)Convert.ChangeType(new Guid(value.ToString()), typeOfT, provider);
This works in Xamarin.iOS perfectly!!! I have also tested this in Xamarin.Android and it works there as well.
Can you make a PR ? :)
Sure can! Give a couple of minutes please :)
Done!
If we set Batch size on Xamarin iOS Simulator we still get this error.
I don't have access to IOS emulator, maybe @akema-trebla or @gaurakshay , can you take a look at it ?
@akema-trebla can you share a sample repro? Please share the DB setup as well.
Hi!
When I add parameter in a Xamarin(iOS) client, I am receiving the following error:
Without the parameter, the sync happens happily (without any rows of course because of missing parameter)
I am using Web API to expose my database to my client systems. There are filters on all the tables so that only the relevant information gets sent down to the clients. Luckily, there is only one parameter. The server setup is pretty straight forward affair:
When testing this setup with a Console (.net core), I am not having any issues with syncing with the server (the same code is being used in both Xamarin and Console app):
I am hoping that I am doing something silly and missing something obvious. Any help or guidance is appreciated!