sqlite-net
sqlite-net copied to clipboard
CreateTable does not create all columns in Xamarin.iOS unless linker set to "Don't Link"
I recently changed my Xamarin.Forms iOS build to "Link All", in an effort to to stop crashing while trying to debug.
All seemed to be working fine until I did a fresh run with no SQL file. Many or most of my tables were missing columns, particularly the first column (typically the primary key).
Thinking about recent changes I finally rolled back from"Link All" to "Don't Link". Worked. Pushed it to Link Framework SDKs Only. Everything still seems to be fine now.
I am running XF 4.8 (long story), but the absolute latest Xamarin.iOS, and Visual Studio. I develop on a Win machine, and attach my device to test to my connected Mac.
Can I got back to Link All?
Short answer, yes you can.
Long answer, I would suggest reading the documentation around the linker and trying to understand what it is doing and trying to achieve. You can read about it for Xamarin.iOS here.
When you set the linker to all, it's going to be aggressive and it is very common that it will break a behaviour in your app or in a library you are using. You can create a linker.xml file and use a wildcard to prevent the sqlite-pcl library from being touched by the linker:
<assembly fullname="SQLite">
<type fullname="*" />
</assembly>
Now this wouldn't have much benefit for you if you were trying to create as small app bundle as possible but in my experience it's more than enough for 99% of Xamarin apps.
There is also an argument to be made that you should just set your linker to Link Framework SDKs unless you really know what you are doing with the linker because it has the potential to nuke your app in production without you realising.
@Axemasta -- I am not a brave person -- I have a vague memory of having this same issue 2 years ago. So will be happy with my "link frameworks only" option. Found out this wasn't really what was causing the crash on the debugger starting (I found that deleting the hidden .vs folder fixes).
A tip I couldn't recommend enough when you are testing the linker is to apply it when you are in Debug mode. This way your app is faster to build and the debugger will catch exceptions caused by the linker, making it much faster to detect what is going on. Don't forget turn it back to off when you are just developing normally.
What you can also do, if you still want to let the linker do it's thing on your own assembly, is use a PreserveAttribute on your table class (with preserve members set to true). Details can be found here for instance: https://www.mvvmcross.com/documentation/fundamentals/linking#preserve-attribute
Xamarin.Essentials has such a PreserveAttribute builtin, but if you don't want to drag that dependency in, you can just add your own defined PreserveAttribute; the linker only checks on the attribute name and the properties set to it. Even easier, there's one in sqlite-net as well :) https://github.com/praeclarum/sqlite-net/blob/master/src/SQLite.cs#L2493