runtime: System.Text.Json Serializer does not appear to work on Xamarin iOS
Perhaps not surprisingly, System.Text.Json.Serializer does not appear to function on iOS likely owing to the lack of Emit support.
public class ChatMessage
{
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("sent")]
public DateTime? SentOn { get; set; }
}
JsonSerializer.Deserialize<ChatMessage>(json);
This yields:
System.ExecutionEngineException: Attempting to JIT compile method ‘(wrapper delegate-invoke) void <Module>:invoke_callvirt_void_ChatMessage_Nullable1<DateTime> (Chat.Messaging.ChatMessage,System.Nullable
1<System.DateTime>)’ while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 34 (16 by maintainers)
Nope - very surprising, to say the least. And what is even worse: you don’t discover this until you spent time on implementing it, then get the weird error message when running on a real iOS device, then search on Google and then find this issue. Not a good developer experience at all…
So shouldn’t the dependencies of the NuGet package reflect that it simply should not be attempted on Xamarin iOS? I actually found this surprising and have now wasted several hours moving from Json.Net to System.Text.Json because I liked the idea of having the same serializer in both front-end and the .Net Core 3.0 back-end. And because of the performance improvements that it should give.
Another surprise was that it works on the Xamarin iOS simulator, but not on the real device.
So this was a dead-end and that would have been nice to know beforehand.
Yes, there are number of other constructs that System.Text.Json uses that are not compatible with full AOT compilation. For example,
MakeGenericType
is not compatible with full AOT compilation. Some of the delegate constructs that you have mentioned are not friendly to full AOT compilation either.Unlikely. Making System.Text.Json compatible with full AOT compilation will require fundamental changes. I believe that the best fix is going to be to pre-generate the serializers at build time: https://github.com/dotnet/corefx/issues/41398
cc @marek-safar
Note the package includes functionality that does not care about AOT eg the readers/writers.
We even released a version of our app, because we didn’t find anything wrong, because “most” cases simply work. We now have to create a new version and revert to newtonsoft.json because of all of the functionality in our app about 2 functions are not working.
@ericstj I’m glad you take this seriously and have created a new issue as requested: #41089.
@klogeaage I might be off-track here, but check the serialization options you use in the 3.1 serializer. For what I recall, Newtonsoft (de)serializes into
camelCase
by default, while System.Text.Json - intoPascalCase
. There is also different treatment of numbers - Newtonsoft happily accepts"10"
as a numeric field, while System.Text.Json does not (it complains about the quotes and expects a bare10
).In short, check the incoming text and if you’re using any options for serialization.
Let’s try to keep this issue just for Xamarin and not .NET Native since there are separate issues.
The .NET Native issues are caused by its linker removing “unreferenced” assemblies.
what the hell? So this package isn’t compatible with iOS at all?
Yes, It will be nice to mention not to use this package where AOT is enabled? We too switched using NewtonSoft Json for our company xamarin mobile app project for now.
FWIW there is a fallback today to just use standard reflection which is currently enabled in source-only builds (not the “inbox” builds).