Is there any alternative to achieving serialising and deserialising of objects in Xamarin.iOS (Monotouch) using protobuf-net other than this method:
http://www.frictionpointstudios.com/blog/2011/3/31/using-protobuf-net-serialization-in-unity-iphone.html
Reading around some people claim they have managed it (without giving evidence), but my understanding is that [iOS JIT==NO] so does not quite make sense.
If the only possible solution is to fully AOT all relevant classes what might a suitable pre/post-build event command line be to perform this AOT for any relevant assemblies automatically?
I've heard a good number of people have success via that route, but I too can't give documented evidence.
That method is a bit out of date - I've simplified a few steps; there is a standalone pre-compile tool that should work:
create a project/assembly for the DTOs that you want to serialize that references the appropriate version of protobuf-net; presumably CoreOnly/ios, ideally with that dll set to copy into the output directory (it just makes life easier)
run
precompile "SomePath/YourDto.dll" -t:MySerializer -o:MySerializer.dll
(maybe with a mono before that to get mono to host the exe)
this should resolve the framework and compile a MySerializer.dll that you can reference, which involves zero JIT (MySerializer.dll will reference your dto dll and the version of protobuf-net that your dto dll referenced)
now reference your dto dll, the serializer dll, and the protobuf-net dll, and it should all work just by using new MySerializer().Serialize(...)
when you compile your solution, the projects should all AOT nicely
I'll be happy to offer guidance, but currently I am mac-less, so I can't check right now. If you get any problems let me know. If it can't resolve the framework, you can add -f:{path to the framework assemblies} to give it a clue.
I got protobuf-net 2 working on Xamarin-iOS by using the netstandard1.0 dll. You can get this dll by extracting the nuget package. No changes were needed.
Related
I have a Win8 app that is purely native (c++) and I've already used a library that is written using managed code AFAIK. No issues there, I created objects and addressed them using C++/CX with ref counted pointers etc.
I need to add a new library, I referenced it as I did previously, but when I declare and object and try to address it I get:
error C3624: 'System::Object': use of this type requires a reference to assembly 'mscorlib'
Using #using <mscorlib.dll> is not a solution obviously, because WinRT does not support #using of a managed assembly.
When I look up the definition of the class I'm using in Object Browser I see that it's inherited from System::Object. The previous library had a class that was inherited from Platform::Object which is valid for C++/CX.
I already contacted the developers of current library I'm trying to use, but it takes a lot of time for them to respond.
Can I work around this issue? What are the possible courses of action?
UPD: Can I ask the developers to rebuild a library for C++/CX?
I do not believe this is going to work in the general case, unless the C# library is a PCL (portable class library). If it leverages anything that is not in the WinRT .NET client profile, it simply will not work.
If it is a PCL, what you can do is write a C# Windows Runtime Component that itself has a reference to this third-party library and wraps the necessary functionality. Then you reference that C# Windows Runtime Component from your C++/Cx application.
Say you have:
Portable Class Library where you have most of your ViewModel code
You are using reactive-ui in that class library (and thus have nuget reactiveui-core in there)
What can be the source of thread marshalling errors (e.g. The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)))?
While you have included the nuget package reactiveui-core, perhaps, in your main application, you need to also include the "reactiveui" nuget package. This package can't be used in a PCL, but it must be included in your main application. Without it, the platform specific code that fills RxApp and other platform-specific items in the library will not work. Unfortunately, in reactiveui, this is a silent failure. And you can chase your tail for a few hours before figuring this out. :-)
This was discovered in the reactiveui v6 beta.
It seems that when I reference AutoMapper v3.1.0 in my Xamarin.iOS project, the build fails with this error message:
Error MT2002: Failed to resolve "System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)" reference from "System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" (MT2002)
When I roll back to the revision before I added this, it all works fine.
Unfortunately, I've already done quite a bit of work with AutoMapper in my unit tests and it would be problematic to remove it now. I guess that's a lesson to learn: just because it works in a test doesn't mean it works in Xamarin.iOS.
I would be very grateful if anyone has any ideas.
Edit: I have now discovered a MonoTouch directory in the AutoMapper package, but referencing the AutoMapper.dll and AutoMapper.iOS.dlls found within does not solve the problem.
Edit #2: This issue only occurs when building for the device - I guess the MSIL to native converter doesn't like AutoMapper for some reason. I'm trying to find a way to "hint" to this compiler that we need these symbols, which is what I think the purpose of the LinkerPleaseInclude.cs file is.
This issue is temporarily resolved - I had to hack out the offending symbols in AutoMapper and recompile it. Please see automapper issue #429 for more information on what symbols I removed. Until AutoMapper is updated to fix this problem, that's how you have to solve it for now.
The reason for this is explained concisely in another StackOverflow question - basically there are subtle differences between the .NET and Mono frameworks that in this case are incompatible with AutoMapper.
This answer previously stated that you should turn off linking to work with AutoMapper. While you can do this for development, it's not suitable for production use as it will yield a massive binary and you will not be able to submit your app to the app store.
Can you use the InternalsVisibleTo assembly attribute in a AssemblyInfo file of a MonoTouch Library to allow MonoTouch Unit Test (Touch.Unit) access to the internals of the MonoTouch library?
This is something that is great to use in non-MonoTouch world to allow testing of internals without having to jump through hoops. However I am not able to get it working with a MonoTouch Unit Test. So before I go any futher I figured I would ask if it is even possible, since this is an iOS Application that is the test runner, so not sure if an iOS application which is compiled to native code can even do this.
Yes, it should (or it's a bug) even if I do not recall trying it myself.
The key point is that [InternalsVisibleTo] is mostly a compiler trick and it is supported by the C# compiler (smcs) shipped with MonoTouch (as it's used inside the BCL). As such there's no reason why it should not work from a Touch.Unit-based application.
Now keep in mind that all other rules still applies. E.g. if the the managed linker is enabled when all unused code will be removed (even if marked with the attribute).
I am experimenting with ServiceStack's JSON engine. I grabbed the MonoTouch binary build, v2.20. Works fine from simulator, but from the iOS device (iPad2, iOS5) I get an exception thrown by the type initializer for JsonWriter (and not much other than that). I am using MonoTouch 5, MonoDevelop 2.8.1, and targeting iOS 5. I have disabled library linking because I am getting an error when enabled.
I created a sample and uploaded to https://github.com/t9mike/ServiceStack-JSON1.
I'm trying to determine whether the issue is my compilation options, Service Stack, or MonoTouch. Thanks in advance.
A quick partial answer that might help:
I have disabled library linking because I am getting an error when enabled.
The current (5.0) managed linker can eliminate some unused (from a static analysis point of view) code from your application. This generally occurs when using Link all option, i.e. where user code gets processed by the linker.
One alternative is using the Link SDK assemblies only that won't touch the user code (only the code shipped with MonoTouch itself will be processed by the linker).
Another alternative is adding [Preserve] attributes on your code to ensure the serializer requirements are still met after the linker has processed your code. More information about the linker and [Preserve] attributes can be found here.
The next (5.2) release of MonoTouch will include a bit more sophisticated step in the linker to ensure the basic XML serialization and DataContract requirements are not broken. Not sure if this will solve this specific case (ServiceStack JSON) but I'll have a look into it.
As for the rest of your question I'll try to build this myself and duplicate your issue.
I ended up grabbing the ServiceStack.Text sources from GitHub, version 3.0.3. I created a new MonoTouch library project. I had to tweak ServiceStack.Text/JsConfig.cs slightly to conditionalize away the System.Drawing.Color bits. I'll send a patch and MT csproj to the authors.
After using this new assembly, my sample MT app ran fine on the device. I have updated my sample at https://github.com/t9mike/ServiceStack-JSON1 with the new ServiceStack.Text dll.