Migrate Xamarin Forms PCL Apps to .net standards
Of course you have already heard of .NET standards , otherwise have a look at the link. So it’s not a question WHETHER you migrate, it’s a question WHEN you migrate. More and more nuget packages are already migrated, so I decided it’s about time to migrate my app. Asking friends before migration, Tobias referenced James Montemagnos short explanation How to Convert a Portable Class Library to .NET Standard and Keep Git History, but I don’t want to migrate a portable class library, I want to convert an App. Glenn proposed to manually migrate it into a new project. That’s of course no bad idea, because there I could exactly see where the errors appear. Additionally I might get rid of some unused packages which I still reference but do not need anymore. So let’s create a new Xamarin Forms App using .netstandard 2.0.
Create a Xamarin Forms App with .netstandards 2.0
In Visual Studio (I’m doing in on Mac, but it’s quite the same for windows of course), select “File” -> “New Solution” or click “New Project” on start screen. Any idea why it’s “Solution” in File-Menu and “Project” on start screen? ….
Anyway. Select “Blank Forms App”. On “Organization Identifier”, make sure to select the same name as in your current project, because we want to replace the existing app in the store later on. Therefore the bundle identifier has to be the same as before. Check Info.plist or Android Manifest if you are unsure about your current package name.
Also update version numbers in Android Manifest and info.plist because later on you want to update the existing app in the store so it’s a good idea to increase version numbers now already.
Once your app is created, in most cases there is already an update available for Xamarin.Forms Package, and maybe also Xamarin.Android Packages. So go to all 3 projects and update all packages. Check whether your empty app is running fine.
If you get “Error type 3. Error: Activity class {yourapp/MainActivity} does not exist.”: Close Visual Studio and check whether your app already exists on the emulator. If so, delete it from there.
Start adding nuget Packages
Now you could start adding the nuget packages. It’s helpful to have both projects open and go through each package. (If you want to open Visual Studio multiple times: Open Terminal and run: open -n -a “Visual Studio” )
So in your common project, go to “Dependencies” and right-click on “NuGet”. Select “Add Packages” and start adding all the packages you are currenly using.
Here are some other things you might also notice in your own migration:
- With some packages you might see warnings like this:
Package ‘modernhttpclient 2.4.2’ was restored using ‘.NETFramework,Version=v4.6.1’ instead of the project target framework ‘.NETStandard,Version=v2.0’. This package may not be fully compatible with your project.
Fortunately that’s just a warning, not an error. - I had a lot of these errors after I’ve imported my files from my old project:
The name ‘InitializeComponent’ does not exist in current context.
For whatever reason, when I selected “Add Existing Folder”, Visual Studio only added my “.xaml.cs” files, but not all the “.xaml”. So I used “Add Files from Folder” but whenever I close and reopen my projects, my XAML Files are not shown anymore. Only the .xaml.cs files are shown, but no .xaml anymore…. I ended up manually creating each XAML page from scratch and copy and paste all the content from my existing solution…. Took some time, but worked fine. - After upgrading the default Android packages, I got the following error as soon as I want to add any other package to my Xamarin Forms Android app:
Version conflict detected for Xamarin.Android.Support.Compat. Reference the package directly from the project to resolve this issue.
MyApp.Android (>= 1.0.0) -> Xamarin.Android.Support.v7.MediaRouter (>= 27.0.2.1) -> Xamarin.Android.Support.v7.Palette (>= 27.0.2.1) -> Xamarin.Android.Support.Compat (>= 27.0.2.1)
MyApp.Android (>= 1.0.0) -> MyApp (>= 1.0.0) -> Plugin.Share (>= 7.1.1) -> Xamarin.Android.Support.CustomTabs (>= 25.4.0.2) -> Xamarin.Android.Support.Compat (>= 25.4.0.2).
The last line shows, that plugin Plugin.Share has Xamarin.Android.Support.CustomTabs as a dependency. Add this to your Android project, and you could continue adding plugins to Xamarin Forms Android. - After adding all plugins, I got the following error when I build my app:
/Users/kai/.nuget/packages/xamarin.forms/3.1.0.583944/build/netstandard2.0/Xamarin.Forms.targets(44,3): error XF002: Xamarin.Forms tasks do not match targets. Please ensure that all projects reference the same version of Xamarin.Forms, and if the error persists, please restart the IDE.
So I took the easy way first: Restart Visual Studio. That fixed it 🙂 - On Xamarin Forms iOS I got the following error when I build my app:
Error: NuGet packages need to be restored before building. NuGet MSBuild targets are missing and are needed for building. The NuGet MSBuild targets are generated when the NuGet packages are restored.
Restoring (or updating) nuget packages did not help, but restarting Visual Studio fixed it. - Copying the image assets via file system did not work for me. It look ok first, but Application Loader had several of these errors when I tried to upload my app to the appstore:
ERROR ITMS-90032: “Invalid Image Path – No image found at the path referenced under key ‘CFBundleIcons’: ‘AppIcon60x60′”
ERROR ITMS-90022: “Missing required icon file. The bundle does not contain an app icon for iPhone / iPod Touch of exactly ‘120×120’ pixels, in .png format for iOS versions >= 7.0.”
So I had to manually assign them again.
Add local DLLs to .netstandard Project
Yes, I know, James’ Contacts Plugin is not supported anymore. But I’m still using it to read contact details from local addressbook. As there is no nuget package, you have to add the local DLLs. But the new .netstandard project has no folder “References” so where could I add the local reference? Just do a right-click on “Dependencies”. The first option is “Edit References”. Go to tab “.Net Assembly” and add the local DLLs. So new .netstandard projects also work fine with local DLLs.
Add new project to Source Control
Don’t forget to add your new projects to your source control. If you want to use git, e.g. using Visual Studio Team Services (VSTS), have a look at my previous post How to add initial code from Xamarin Studio to git at VisualStudio.com for an easy step-by-step guide.
Helper for .csproj
Nils pointed out, that this site from Kristoffer Berge helped them migrating their .csproj file. I did not use this tool yet, but please have a look on your own. Works fine.
Reduced Size of the app
I guess it’s not only related to migrating to .netstandard but also removing lots of unnecessary packages: The size of the apps decreased a lot. On Android it’s down by 2/3, on iOS by 1/2. Another nice advantage 🙂
Deployment
And hopefully you don’t run into this when you want to deploy your .netstandard Xamarin Form iOS App for the first time…..