📜 ⬆️ ⬇️

We work with Xamarin: development experience on two projects

I want to share my development experience using Xamarin (sounds like Zamarin) on two major projects. The first project was under the Windows Store and iOS, the second only under Android, but using Xamarin.Forms. Xamarin is developing rapidly, so some of the points described here might have become irrelevant. For example: back in the summer we were worried about wild memory consumption on Android and even manually calling the garbage collector in some places, but at the end of the summer there was an update that closed many of our memory problems.

image

When to use Xamarin and Xamarin.Forms


I don’t want to seem like Captain Obvious for some, but I repeat, what has already been repeatedly discussed at Habré and various forums: there is no point in using Xamarin in “normal” mobile applications. By “normal” mobile applications, I mean applications that have the following characteristics:

Here I will not touch on a huge layer of games, this is my world.
')
The main motivation to use Xamarin should be the presence of a large amount of code that works on different platforms and is easier when it is written in one language, using a cross-platform framework. We wrote a retail app for Windows and iOS. In this project, only the calculation of the price of goods took several thousand lines of code.

Xamarin.Forms is the Xamarin part that allows you to cross-platform to create a user interface using XAML. You can use Xamarin without Xamarin.Forms, creating an interface using wrapper classes over native classes. Xamarin without Forms cannot be used for cross-platform user interface creation.

The choice between Xamarin and Xamarin.Forms is proposed in the documentation according to the following scheme.

image

What type of project to choose


In Xamarin, there are two ways to create a project in a solution:

  1. Shared Project
  2. PCL Library .

The first is the implementation of Xamarin, an analogue of the shared project in Windows Store applications, when the project is not compiled into a separate assembly, but rather, as it were, embedded in the main project in which the application is launched.

image

The main lesson for us was that there is no reason to use the marinated type of the Shared Project (.shproj) project, but to use the .NET PCL (Portable Class Library). The main disadvantage of the Shared Project is that you can write code in it that will not work on other platforms, and it will compile, and when you start developing for another platform, you will be surprised to find that a lot of code is not supported in this platform. PCL is deprived of this. When creating this type of project, you need to specify which platforms should be supported. If you want to use, for example, something from Android, it simply will not compile and will not allow adding unsupported references to the project. As a bonus, you get additional confidence that no one in the team can be tempted to write something in a common project quickly, but natively, rather than correctly, but with great effort, for example, by bringing the native code to a native project, and connecting it to PCL via Dependency Injection.

Be prepared for memory leaks


An unpleasant, but by no means, unexpected moment was a memory leak in iOS. The world of iOS and the world of Xamarin are different worlds. In one, the memory is cleared by reference counting (automatic reference counting), and in the other, the garbage collector does it. Therefore, when we call something in the world of Xamarin, which has a connection with the world of iOS - and this is work with almost any native control - a link is created from that world to a comfortable managed world that the GC cannot clear, because it does not know this link or not. To deal with this has a very ugly way. When you close the page, you have to assign null to all external objects, and unsubscribe from event handlers. Lesson is quite a chore.

In iOS, Apple Instruments can be used to profile memory. For Android, this is not possible, standard utilities can work only with native applications. Xamarin also released a beta version of the Xamarin Profiler tool. We will try to use it for Android in the coming weeks.

In Android, everything is much better, but you still need to keep in mind that two garbage collectors are working at the same time. One in the world of Android Runtime (up to version 5.0 of Dalvik Runtime), the other in the world of Mono Runtime. A similar situation may arise when neither one nor the other can remove unused resources. However, after installing the latest updates, we did not notice any significant leaks when working with the user interface, controls. On the little things, something is always happening, trying to find out the underlying causes, in conditions where the next update can change everything, is not reasonable. Therefore, in all of our pages, when going to the next page, we call such an ugly code:

this.Content = null; 

When navigating to a new page, we create an instance of it again. This method allows you to deal with difficult to debug memory leaks, sudden unreasonable drops, etc. Someone might be shocked by such a method, however, if you look at the forums and blogs devoted to memory problems, you will understand that in the Xamarin world this is normal. At the same time, performance suffers, but there are no significant, visible delays when opening pages.

MVVM experience without Forms


In a project for Windows Store and iOS, we have common logic, but user interfaces are written natively. Since for Windows, we wrote on XAML, then we decided to use MVVM, and iOS will call the existing View Model. Admittedly, the idea is not entirely justified. The approaches to the organization of the user interface in iOS and Windows were so different that I had to write separate View Model for Windows and iOS. To somehow fumble the code between them, I had to use the Command pattern very widely. Code such as validation, service calls, business logic calls, parameter preparation and processing of results - moved into ICommand implementation classes that were reused in different ViewModel. The latter was a thin layer between the Model and View, for binding, using the Command set.

A specific example: the user selected a product from the list and assigned a discount. In Windows, in accordance with the UX guidelines, the selection and application of a discount was made on another page. In iOS, a pop-up window appeared on the same page. The application of the discount to the product was in the ApplyDiscountCommand class. ViewModel for Windows opened a new page where this command was invoked. The ViewModel for iOS opened a pop-up window where the user chose a discount and ApplyDiscountCommand was called in the same ViewModel.

Working with MVVM in iOS turned out to be inconvenient and not natural for this platform. In particular, it was necessary to prescribe all the bindings in the code manually, and call the commands also in the code using Execute (). The use of converters was also inconvenient.

Also an unpleasant moment was the lack of full support for System.Xml.Linq in iOS. It was necessary to be limited to obsolete classes from the System.Xml: XmlDocument, XmlElement, XmlAttribute namespace.

We used Xamarin in conjunction with the MvvmCross framework. I generally liked him. Logical and understandable support for Mvvm, lightweight implementations of such things as IoC, Messenger, a bunch of cross-platform plug-ins, for example, working with Http. A misunderstanding is caused only by the implementation of passing parameters while navigating to another page. This requires that the class of parameters consists of properties of simple types (int, bool, string), since it is then serialized into the URL. An amazing decision to serialize something that is passed through a single process and thread! I can safely recommend this library as a cross-platform MVVM framework.

Pitfalls Xamarin Forms


We are currently working on another project using Xamarin.Forms. The decision to use Xamarin.Forms was made by the architects of the customer who wanted to achieve cross-platform, and it was impossible to cancel it. Probably, the decision to use Xamarin Forms should have the following motivation: a lot of screen forms and unwillingness to support 3 versions for different platforms.

I often heard that it was supposedly a marketing myth that using Xamarin Forms, one would not have to master a native development sooner or later. Our example shows that this is not a myth, and even developers who are not familiar with how to create native interfaces successfully cope with the tasks.

When we first started working with Xamarin.Forms, a small amount of controls was a big disappointment. We were shocked to learn that the following controls do not exist by default in Xamarin.Forms:

Their absence is explained by the fact that there are no such controls in iOS, and other visual elements are used for similar tasks.

Of course, it was possible to use custom renderers of these controls, but we basically did not want to bother with writing code for different platforms, so we wrote our versions of these controls completely cross-platform! We used the primitive XF controls, including BoxView and Line, to collect the ones we needed. In Android, these controls do not look alien, especially in the context of a general style.

image

Another shock: the lack of the MaxLength property of the text field (Entry). It is suggested to set the maximum text length using the Behaviors mechanism or simply by cutting off the excess in OnTextChanged. Why can't XF add such a basic property and force me to write my own control? The question is rhetorical.

Also, not all controls have bindable properties, for example, DatePicker and TimePicker.

Deliver small pop-up jigs, for example, an application periodically drops when several controls are tied to the same property. It took only a day and a half to identify the source of this hard-to-reproduce bug! I had to create a copy-property and bandage to different properties, then the drops stopped.

Support for gestures and complex interface is quite backward. We have a page that allows you to choose the time faster than the standard TimePicker. It is made in the form of an analog clock, where the user can move the hands in different directions and choose the hours and minutes. Alas, it could not be implemented on Xamarin Forms and this is the only page in our application that is written natively. In fact, only two gestures are available in Xamarin Forms: pressing and double-clicking. Such gestures as a long press, holding your finger left / right are not supported.

Interface performance is insufficient, especially the display lists. Lists in which list items have texts of different sizes and colors slow down when scrolling. Pages also open with some delays, despite the disabled animation. We have to simplify something for the sake of performance, to rework screens drawn by designers. Where this fails to be done, all that remains is to accept and hope that Xamarin will improve performance in future releases.

Nevertheless, I really like the fact that Forms has full support for styles and templates. I consider it a very strong point in XAML, and it’s good that it is present in Xamarin. Also, one of the nice moments is the powerful features of XAML, which, of course, lag behind WPF, but are about the same as XAML for Windows Store applications. Developers who are used to working with XAML will be comfortable enough in Xamarin Forms. Binding, commands, converters - all this is supported and you can fully use MVVM. Taking into account, of course, poor controls and various glitches, as in the above example, but which are gradually corrected.

Xamarin develops, there are often updates. For example, we had a bug: when you repeatedly click on the list, the application crashed. We immediately decided that this was a Xamarin bug, and that we wouldn’t spend time correcting it, but wait, maybe Xamarin will fix it. And indeed, after 2-3 months with the next update, the bug is gone.

What is the development environment?


Xamarin badly messed up Visual Studio, which in general is a great development environment, renowned for its convenience and reliability. No, no, I did not pay Microsoft for advertising "I see", just here the case as in the saying: what we have - do not appreciate, having lost - cry. Below I will list the main difficulties that have arisen in the first place with the toolkit.

Visual Studio with the Xamarin plugin often hangs, often predictably. For example, it periodically hangs while editing a XAML. The workaround found in Runet’s space is to delete the suo file (project’s user settings), then you can edit the markup for a while. But the next day will freeze again. Sometimes it hangs up to three times a day, sometimes it pleases with “reliability” a whole working day.

Also, for no reason, the project may cease to deploy to the phone. Here a second ago I started and everything was OK, and now Package Deployment Failed. You open Xamarin Studio, you launch there, it is quietly deployed, then you come back to VS and continue to work. Sometimes it happens that you are self-forgetting to program something once it is frozen. In order not to interrupt the flight of thought, without blinking an eye, you switch to XS and continue there, since you can set up the same color scheme of the editor as in VS. XS is generally more reliable, but it’s always impossible to work there, because no TFS support. So sooner or later you have to go back to VS.

Another unpleasant moment was that Ghost Doc stopped working in Xamarin-projects (it does not support shproj-projects). And on the XS it is not set. Well at least StyleCop for XS is available.

A big disadvantage I consider the fact that VS has lost the ability to adequately display unhandled exceptions. Now the standard window with information about the exception and the place where it occurred is not displayed. A window appears, as in the screenshot, and the Stack Trace and the place where you fell, you have to look in the Output window, which is inconvenient. The XS is a bit better, but also uncomfortable.

image

Also, in VS, when opening a XAML file, the designer always tries to boot into the floor of the screen. He is unable to do this even in theory, and he has to close it. Which again is extra mouse manipulation. Unfortunately, he does not remember the last used form of editing. How to disable the download designer, I have not found anywhere. In XS, this is no problem, the code immediately opens.

IntelliSense in VS lives its own life: it works and disconnects according to its own unknown rules, and VS does not always help rebooting. In addition, it does not see the newly added classes. Often the addition of a new class and breaks IntelliSense. In XS, in my opinion, IntelliSense is implemented worse, but it works stably.

All these shortcomings reduce productivity and against the background of the fact that XS is more stable, in the next outburst of indignation, they paranoid thoughts of a global conspiracy: as if in this way Xamarin forces us to abandon VS in favor of XS.

All summer I have been tormenting Google with questions about when VS 2015 will be released, because there Xamarin support is already embedded. Finally, having waited for the official release, I rather launched our project in it. Microsoft, as always, remained true to himself, in order to try new features, you need to install their latest OSes. VS 2015 works in the seven, but to try to build a Shared project, Xamarin needs at least Widows 8.1.

Thus, if you start a project with Xamarin, I advise you to work with Windows 8.1 + VS2015. If you are still sitting on the seven and do not switch to 8.1 at all, consider the possibility of working only with Xamarin Studio using git or SVN, but not TFS.

Xamarin was often blamed for not having enough documentation and articles on the Internet, few questions on stackoverflow. Perhaps now everything is much better and there are already quite a lot of questions on both stackoverflow and Xamarin Forums.

Conclusion


In conclusion, we give some main conclusions from the material:


By artur_g

Source: https://habr.com/ru/post/270051/


All Articles