Compatibility - Visual Studio Mac and targets (Modern, Full)

I’ve been using VS2019 on the Mac.
Here’s my experience with various versions of CBL and .Net. I’ve put together a small test app as my test bed (a replacement for the old CBL Viewer so that I can dig into my data). I’m wondering if anyone has any comments on what I might be doing wrong/right, or can explain what I see.

According to this doc, CBL 2.5 (and 2.15 before it) are .NET Standard 2.0 libraries, and so should work with .NET Core Mac 2.0.
According to this blog, NET Framework 4.7.2 is the first version that is fully compatible with .Net Standard 2.0 (at least with minimal issues).
The Visual Studio Mac target named “Full” uses Xamarin.Mac (currently at V5.8) - which has been compatible with .Net Standard 2.0 since 3.8

In all… I am led to believe that CBL 2.15 and 2.5 should work with Xamarin.Mac using the “Full” target in Visual Studio, with .Net set to 4.7.2.

The “Modern” target is a different beast, and is similar to Xamarin.iOS apparently. It definitely does not work.

Here’s my findings:
CBL 2.1.5
Full with 4.7.1 or 4.7.2 works. Can retarget with no errors. Apps compile and run*
CBL 2.5
Full with 4.7.1 or 4.7.2 do not run.Retargeting works fine. Apps fail with “The type initializer for ‘Couchbase.Lite.Sync.HTTPLogic’ threw an exception”.*

*Note that all apps, whether they run or fail, generate a couple of SimpleInjector exceptions when starting.

The “HTTPLogic” exception has been mentioned here before as often a symptom of not running the appropriate “Activate” function. I can assure you that is not the case. Activate is definitely called:

public override void DidFinishLaunching(NSNotification notification)

Weirdly, the apps that run perfectly on my dev machine (CBL2.15, Full target with 4.7.2) will not run on other macs - I get the same HTTPLogic exception. I have tried two other machines - both 10.14.

Any thoughts from others doing Mac development using C# and Visual Studio would be much appreciated.

I have not heard of this mode yet, but I imagine it uses mono under the hood as its runtime. This is not a supported way of running Couchbase Lite nor do I intend it to be. mono has issues with identifying the OS it is running on sometimes and so the Activate() call has a potential to fail as it tries to follow the “Windows” path.

I’m confused as to what this is about though. You mention .NET Framework but show code snippets for Xamarin iOS.

These are caught and handled. SimpleInjector throws exceptions when a non-registered interface is requested.

Just re-read this and completely missed Xamarin.Mac here!!

I remember experimenting with Xamarin.Mac back in the day, and I couldn’t get it to work very easily. I’m not sure if a regular dylib can be used inside of a Xamarin.Mac app. If it has similar restrictions to iOS, then it will need LiteCore built as a framework. It will at least need the dylib to be present in the app bundle and not somewhere in a nuget package or something.

Here are the options inside VS:

From this document you can see that

  • Modern* (was called Mobile) is a subset of Xamarin.iOS.
  • Full is similar to the Desktop .Net BCL (now at 4.7.2), and
  • Unsupported is mono.

So I would have thought that Full would work since it implements .Net Standard 2.0. It does work, but only 2.1.5, not 2.5.

The code snippet is from my Mac app (and the image above is from the options for that mac app).

There is something weird going on, on the Mac anyway.


No problem.

I can tell you that iOS works perfectly… 2.1.5 and 2.5, on many devices and versions.

As to your comment about LiteCore being built in, I have checked that LiteCore is being added to the application package. Adding it as a framework makes sense. I’m hoping someone else with more experience of VS on the Mac has done this and can point me to a simple solution.

Thanks for your feedback.

There must be some magic going on for running in VS Mac. I am amazed that it works because none of the tell tale signs are there. There is no link to the LiteCore shared library from the generated executable, I didn’t include libLiteCore inside of the app package, I moved the app package and deleted the original bin directory but still it refused to fail. I’m willing to bet that the issue you are facing is that libLiteCore.dylib is not in the place where it is being looked for (though I am not entirely sure where that would be…for iOS actually it works at just the top level). Somehow it is magically in some special place on your (and my) dev machine, but when it is moved it is no longer accessible.

You are correct.

It seems that libLiteCore.dylib is being copied to the bin/Debug folder during build, but is not being copied to the App folder. Therefore I cannot copy the App to another machine and have it work. If I copy libLiteCore.dylib to the folder, then everything works.

The app works when copied around on my dev machine because I have a copy of libLiteCore.dylib in /usr/local/lib (perhaps because of previous installs of Couchbase Server?)

So if I understand this (which is uncertain), then the question is:
Should the App be self-contained, and therefore include libLiteCore.dylib, OR should libLiteCore.dylib be a separate install into /usr/local/lib?
Isn’t that under your control in the specs for the nuget package?

BTW - I’m not sure what version is in /usr/local/lib. otool -L reports 0

$ otool -L /usr/local/lib/libLiteCore.dylib
    @rpath/libLiteCore.dylib (compatibility version 0.0.0, current version 0.0.0)

Apparently this is not unusual.


Taking this a step further… I have been unable to get CBL 2.5 to work, even in the debugger.
BUT if I do the following (with nuget packages for CBL 2.5 loaded into the project)

Build Clean,

cp bin/Debug/libLiteCore.dylib bin/Debug/

We do not have a target for Xamarin Mac, which makes all of this conversation experimental. Xamarin Mac apps, as far as I know, should definitely not be making use of any custom libraries outside of the app bundle (same as iOS rules) so it should be bundled with that app. While it’s easier to have them work that way than on iOS, that’s a sure way to get rejected from the app store. The reason that it is happening this way is because basically Nuget is taking the wrong package since the build tools are attempting to emulate .NET Framework. NetDesktop support is meant for .NET Core and .NET Framework, not Xamarin Mac. Xamarin Mac is not one of our supported platforms so there is no “right package” to replace it with.

libLiteCore.dylib has no relation to Couchbase Server, but if you tried to build it with CMake before and happened to run make install it might have ended up there. As far as the version goes, I don’t make any specific attempts to have it versioned as part of the CMake build but if you happen to know how to make that happen I’d be happy to incorporate it. You could build a small command line program that linked with it to find the version via c4_getVersion if you are curious though.

Also just in case you haven’t seen this for some reason, here are a list of platforms that Couchbase Lite works on including those that have official Couchbase Support and ones that are just known to work (but not officially supported):

Thanks for this. I dont really have a choice here - I have a mac app that has used Couchbase lite since 1.x, so I’ve had to make this work on Xamarin.Mac (and it does by the way, which is impressive). And yes to your other post… I’m familiar with that chart of supported versions. It gave me much angst when I was debating the move to CBL 2.x :slight_smile:

I dunno how libLiteCore.dylib got onto my /usr/local/lib - I’ve never built the server. I’ve removed the file, and have added an extra build step to ensure libLiteCore.dylib gets into the .app bundle.

Just wondering - there must be other Mac devs out there using CBL, and they must have run into the same problem.

Thanks for your patience and pointers.

I only know of a few and they were using mono in 1.x, and are using .net core in 2.x. You are the first one I have heard of that is using Xamarin Mac. I wish you luck. As you said, as long as the “sandbox” requirements are met, there is no reason that it should not work.