A bit of background...
SQLite is an open source C++ library compiled for multiple platforms. There are several commonly used C# wrappers for this library on several different platforms. Some of the common ones are:
https://github.com/praeclarum/sqlite-net.git
https://github.com/mattleibow/Mono.Data.Sqlite.git
https://github.com/oysteinkrog/SQLite.Net-PCL.git
Here is my one which is a stripped back fork from SQLite.Net-PCL.
https://github.com/MelbourneDeveloper/SQLite.Net.Standard.git
There are multiple versioning issues around SQLite on the different platforms, but recently, a big version issue came in to play on the Android platform. You can read about it here:
http://ericsink.com/entries/sqlite_android_n.html
According to Xamarin:
Note: Due to a change by Google, Android N will now only permit linking to NDK-provided native libraries. libsqlite.so is not an NDK-provided native library. Consequently, existing apps using e.g. Mono.Data.Sqlite.dll will crash when running on Android N. This may include other SQLite-using assemblies, not distributed with Xamarin.Android.
Xamarin.Android 7.0, which is part of Cycle 8, updates Mono.Data.Sqlite.dll to include a custom built version of libsqlite.so, named libsqlite3_xamarin.so.
https://developer.xamarin.com/releases/android/xamarin.android_7/xamarin.android_7.0/
So, my questions are: which Android C++ library should we be using for Android? Does the version depend on the version of the Android OS installed? Where do we get the C++ library from?
It sounds as though Google will only allow a customized version of the library. I guess this means that they will only accept signed libraries and the one compiled from Xamarin will be accepted. If this is the case, how do we get this library and package it up in a .NET Standard DLL, or include it in an Android app package?
I ask this question because this issue has been pointed out in my library here:
https://github.com/MelbourneDeveloper/SQLite.Net.Standard/issues/5
I feel like this is connected to the versioning issue. Anything that can shed some light on this would help. In my repo mentioned above, I have created a branches called Issues/5 which uses a different C++ library called libsqlite3_xamarin which seems to be bundled with Mono.Data.Sqlite but I still get the above issue when my phone goes to sleep.
Related
Can a C#/.NET application be compiled to native binaries using .NET Native without being a UWP application? For example, a 4.5 console app? I've watched over 2 hours of video on .NET Native and also read docs but they did not clearly answer this question.
There are not a perfect solution for this but serveral alternatives:
Native AOT, formerly called 'Core RT', which supports full native compilation from managed dlls to binary executables on the target platform(OS and CPU Arch), but it is still marked as 'experimental' (Update: merged into the mainline since .NET 7 preview) with a lot of features missing.
IL2CPP, which is developed and used only by Unity.
CrossGen, which is a part of CoreCLR and could generate .ni.dll files which contains precompiled (native code on specific platform) code rather than IL code in normal managed dll, making it faster loading. But it still requires the runtime because it is basically still a managed dll with JIT compilation already done (AOT).
Note that .NET Framework is going to be obsolete with .NET Core becoming the unified .NET, and you can easily hear from some news about native compilation support if you keep watching .NET Core things
To be clear, I follow the MVVM pattern, and I want to structure my project such that I can share my model code between a UWP app and a standard WPF app. The code I want to share has no UI. I don't relish the thought of finding new tools to replace the ones that I've been using for years that take care of certain tasks like logging, connecting to a document oriented database, etc.
I attempted to start writing a UWP wrapper around some code I already have and reference the model project directly. Visual Studio refused to let that happen, showing me an error message that says "Unable to add a reference to project 'ACK.Model'". The same thing happened when I attempted to put the model in a Universal Library and reference it from a WPF app. I'm not trying to share WPF code. Just the model layer that has no reference to UI libraries.
This is a scary proposition, because it means that if I want to do anything substantial I have to choose to either jump 100% to UWP or stay 100% WPF. NewtonSoft.JSON might have a universal distribution (ASP.NET MVC), but what about ElasticSearch.NET, and other tools needed to make important apps?
I found where the "Portable Class Library" project type was hiding. PCLs will allow me to share my code across WPF and Universal apps as that was one of the options. This solves the simple case of the Model part of my code, but I (still) can't use some of the libraries I want. There are still a large number of libraries that I need that do not have PCL available.
About a year later, with the advent of Visual Studio 2017 there is a more complete solution. If you target your libraries to .Net Standard then the library is compatible with both .Net Core apps and the monolithic .Net targeted app. The support for standard .Net libraries and APIs is fairly complete, as is the support for modern C# language features.
The general advice now is this:
Target .Net Standard for all libraries
Target the appropriate platform for your actual application. (UWP or WPF).
NOTE: if your library has to interact with C libraries or applications, you have to take extra care to make sure you load the correct version.
It appears that there is a solution, but it has to be adopted by the whole tool chain you want to use. When Microsoft introduced Windows Store apps in Windows 8, they also introduced a Portable Class Library (PCL). The purpose of the PCL is to share code between different parts of your application.
When you create a PCL in Visual Studio 2015, you can specify the types of APIs you want it to be accessible from:
Universal Apps
Mono
.Net Core 5
.Net 4.6
This of course, limits the APIs available to you but most of the ones you want to use are OK as long as it's not UI related. There are other limitations as well:
Your project can only be edited in Visual Studio 2015 or greater
You don't have access to special directories from the Environment variable (i.e. user Documents directory, etc.)
You can't link to a library designed for only one of your target platforms (i.e. libgit2sharp, etc.)
There's no way to browse the API for this subset--MSDN needs to get on the stick. MSDN has updated much of the API documentation, but it's still difficult to figure out what applies to your PCL
However, you can link any library designed for a single target platform to your PCL. It's not ideal, but it's better than nothing.
The ASP.NET MVC stack has been ported to using PCLs, so you can use NewtonSoft.JSON directly as well as any other of those libraries used by that application. However, there are several libraries that have not been ported.
This arrangement forces you to think about how you want to integrate better. The .Net Core 5 seems to be stable, but support is in it's infancy. The current generation of Universal Apps as of VS 2015 update 1 uses .Net Core 5 directly.
There are several features from Nuget that are not currently supported even though work is under way:
MS Build extensions (major changes to MSBuild and the project.json structure)
Install/uninstall scripts (related to the removal of the concept of install)
Content (related to install/uninstall, but work is in progress on this)
Content transforms (related to lack of install/uninstall)
I wish I had a more complete answer. But this is as far as I got once I discovered the PCL and how it evolved for the current infrastructure.
I'm in the process of creating a game creation toolkit that incorporates version control right off the bat. I want to be able to deploy a game as a Windows 10 app, or as a standard WPF app, but due to the libraries I'm using to integrate version control I need to create the editor as a standard WPF app. I had to be a bit creative in building the shared code and importing the correct libraries.
First, my project hierarchy:
Project.Model (Portable Class Library)
Project.Model.Versioning (standard C# library)
Mvvm.Toolkit (Portable Class Library)
Editor (Standard WPF application)
I want the core PCL to be able to load a project and deserialize the JSON encoded objects. The PCL did have access to System.IO, but surprisingly it is not the same as the one defined in the standard C# library. Here's how I had to fix things:
After adding the package reference to NewtonSoft.JSON, I had to change the target framework in the packages.config file:
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="portable-net452+win81" />
All projects dependent on my Project.Model class had to install the `system.io.filesystem' package from nuget so that the System.IO.FileInfo etc. objects were the same.
While this is definitely not a panacea, it's also not a dead end. I'm sure there are more gotchas, but this will at least help with some of the problems.
a .NET Standard library could be used to share a Model-View-ViewModel architecture between a WPF project and a UWP project.
https://www.syncfusion.com/ebooks/xamarin-forms-succinctly/sharing-code-among-platforms
https://devblogs.microsoft.com/dotnet/announcing-uwp-support-for-net-standard-2-0/
I'm writing a Xamarin.Forms application and have added a PCL project into my main solution in Visual Studio 2013. I'm having problems with using several standard .net classes. Here's a list:
System.Net.IPAddress
System.Net.IPEndPoint
System.Net.WebClient
System.Net.Sockets.UdpClient
System.Timers.Timer
System.Timers.ElapsedEventArgs
System.Net.NetworkInformation.UnicastIPAddressInformation
My question is: How do I figure out which of the above are compatable with a Xamarin.Forms app, and how do I get them to work in my project/solution?
I've contacted Xamarin support, but get vague help and not specifics...
Does anybody have a good strategy for figuring out what classes are supported and what .dlls are needed in order to use them with a Xamarin.Forms project?
Thanks a bunch for your help.
PS: I've been given the following sites for reference, but they don't seem to have any concise information:
What is supported
NuGet package info
It sounds like you don't understand what Portable Class Libraries actually are. When you create a PCL, the subset of the .Net Framework classes that are available for you to use depends on what profile you choose. A profile are the platforms your PCL can support. In Xamarin, the default profile is Profile 78. Profile 78 supports .NET 4.5, WP8, Win8, WP Silverlight 8, Win Store 8, Xamarin.Android, Xamarin.iOS. So the classes that are available to you are the classes that are platform independent, that run on ALL platforms in profile 78.
Example: Take a look at the implementation of System.Net.IPAddress. The implementation makes use of Sockets. Upon further inspection of this implementation, you can see that that System.Net.Sockets is nothing more than a .NET wrapper around the WinSock API. The WinSock API is a Windows only DLL that is specific to the Windows operating family (ws2_32.dll). So, you can now see that System.Net.IPAddress are high level abstractions of Windows Socks (built for the Windows Platform). Since the ws2_32.dll does not exist in Android, nor iOS, etc, this API won't be available to you because Profile 78 specifies that we need to support other non-windows platforms.
Another example is System.Drawing.Bitmap. That's just a .NET wrapper around GDI+, which is based on the Win32 API. Of course Win32 is not available on non-windows platforms (even Windows Phone), which is why you won't see it in a PCL.
Now with that being said, you may think that PCLs are restrictive, but you can create a good PCL library if you think about them the right way. You can also use patterns like Dependency Injection and Bait and Switch.
So in short, don't count on Microsoft "adding support for all the base class libraries" because that's not what PCLs are.
You can still use System.Net.IpAddress in your Xamarin.Forms PCL by using DependancyService. Make an interface in PCL and declare a method "GetIpAddress" in it. Then , in android /iOS project, you can implement that interface in platform specific project and easily access System.Net.IpAddress. After that, Call DependancyService from PCL project to get the result which is IPAddress of your desire.
Cheers !!!
After some additional e-mail from Xamarin Support, and comments on my additional posting, it appears that MS is quite behind in supporting all of their classes via PCL. Some are supported, but not all by a long shot.
Anyway, in order to use my existing code, I would need to put the source .cs files that I would otherwise be using to create my new PCL project directly in the .iOS project and in the .droid project and recompile that way.
This basically defeats the advantage of using a PCL, but does provide an alternative that allows me to use most of my code unchanged. It would just be nicer if all the xamarin libraries were available as PCLs.. Oh well, eventually MS will catch up and get all of their PCLs up to date so that we can use our custom PCLs more often, instead of having to duplicate code all over the place. (Maintenance Nightmare)...
Anyway, thanks to all for the help.
(Working on the bleeding edge of technology is sometimes painful... But that's why we make the big bucks !!!)
We have one application for both C# .NET and Apple iPad. This application will perform similar functionalities. For this we have one protocol layer which we are thinking to keep as common code. For this we are thinking of creating a C++ dll for the protocol module so that it can be used across both C# and iPad. For creating a C++ dll, I have a basic question:
While creating a dll project, which option should we select? We can create a dll for MFC, Win32, ATL etc. What would be the best option for my requirement?
You should not use MFC as these are the Microsoft Foundation Classes not available on iOS anyway. Probably Win32 would be your best guess - but make sure not to include any non-standard Windows header files if you want to use the DLL in non-Windows environments.
I would recommend to frequently compile your file in both environments. You might also want to take a look at multi-platform libraries like boost if you need advanced functionality.
I recommend looking at Mono for building C# apps on both Windows and iOS.
If you want to target the iPad, you need to build for iOS, not Mac OS.
You cannot build dynamic link libraries for iOS, only static libraries. Note, there are equivalents to DLLs on iOS, but only Apple can build them (or you can build them yourself if your iPad is jailbroken, but this will disqualify your app from the AppStore).
iOS is not related to Windows in any way, so Win32 libraries will not run on iOS. Your generic 'protocol module' (if you mean low-level code that can interface to other devices over TCP/IP or similar) will need to have significant differences depending on which platform it is running upon.
Is it possible to use Google APIs Client Library for .NET in a WP7 project?
I've tried to add a new reference to DotNetOpenAuth.dll and I'm getting the folowing error.
Reference cannot be added to DotNetOpenAuth.dll because it was not built using the Windows Phone runtime. Windows Phone projects will work only with Windows Phone assemblies.
Is it possible to solve?
Try Portable Library Tools from MSDN. Read about them here. Now reference Google .Net library in the portable library, also reference this portable library project in WP7 project. Now, write a small wrapper over the Google apis in the portable library project and use them from your WP7 project. Referencing works but I did not use it, you can give it a try once.
I would think it would be possible to use the Google APIs from WP7. I've not used them myself, but it looks like you use them by making HTTP requests which, if memory serves me right, is possible on WP7.
With regards to the DotNetAuth.dll it is more then likely built against the Full or Client Profile version of the .NET Framework and therefore can't be used by WP7. In order to do this, then a WP7 specific version of the assembly will be have to be compiled.