My (Limited) Experience with Xamarin
Categories: Mobile Apps,
I have been developing a companion app for The Rise NYC, a free outdoor fitness group in NYC. If you’re curious, my summary page for the app is here. I had decided to develop the app for Android simply because I have an Android phone; I could test the app out during our workouts without buying a used device. However, I sort of regretted jumping right into the app development process on Android without looking into any cross-platform solutions that would allow me to develop an app for both Android and iOS relatively quickly.
Thus, I decided to look into whatever options were out there. One option is Apache Cordova, which allows developers familiar with HTML, CSS, and Javascript to start writing code for multiple platforms, including iOS and Android. Another choice was Facebook’s React Native, which seems to primarily targeted towards web developers who are familiar with the React framework and want to start writing UIs for native mobile apps in a similar way.
These both seemed like good options, but I felt I needed a least a little experience in web development to get the most out of these tools. Soon after I came across Xamarin, a program that allows one to develop applications in C#. Having just written a ton of Java code for my first Android app, the idea of using a C-style language to do everything was extremely appealing.
So I decided to check it out!
But C# is a M$FT Language
This is a silly thought that was generated by my brain in 2003 and has stuck with me into the year 2017. Back then, Microsoft was called M$FT by middle schoolers (me in 2003!) who made fun of the company for releasing virus-prone operating systems and charged a boatload of money for products you could easily download online for free. I think Microsoft still deserves the hate for not developing a Unix-based OS like its (superior) competitor Apple, but they have come a long way and we’re no longer in the era of the ILOVEYOU worm.
But C# is just a language. It’s connected to the .NET framework, which is patented by Microsoft, but there are open source implementations of this framework (such as Mono), and you can use it on any OS for free. So why all the hate? No reason at all, other than the fact that C# may not be as popular as other C-based languages like Java and C++. So I have since abandoned this way of thinking.
Xamarin Studio
Xamarin is a company out of Silicon Valley founded by the creators of Mono, an open source implementation of C#. It is now a subsidiary of Microsoft, which acquired Xamarin last year. Their product for developing apps is called Xamarin Studio, which looks very similar to Microsoft Visual Studio. My understanding is that Xamarin was originally a plugin for other IDEs, but after the Microsoft acquisition it was given a standalone IDE modeled after the community edition of Visual Studio.
Anyway, it’s a sleek looking product! And the documentation online is absolutely fantastic. But the main purpose of this post is to talk about my experience rewriting my Android app in C# via Xamarin. I have just started learning Swift to develop an iOS version of my app, and I will try porting it after I write a totally native version.
Xamarin Enforces Model-View Separation
Every application with a user interface has some sort of underlying principle of design. It is important that the view and the model are separated in code. That way, background tasks can be run on their own thread, and the view can be updated to reflect new information once it comes in. One specific architecture is MVC, which stands for “Model-View-Controller”. The controller is what the user interacts with to induce a specific behavior of the model, and the view is updated accordingly.
Xamarin rewards developers who detach the user interface from the core of the code – reusability! In Xamarin, you can create what is called a Shared Project between different platforms. See the picture above, where there are three folders:
- Shared
- TheRiseAndroid
- TheRiseiOS
The first folder is where I put code that is not platform-specific. There is no reference to Android or iOS libraries. The second and third folders are for platform specific code. That is, no classes in the Android folder can be used by the iOS app, and vice versa.
While it is true that Android and iOS apps are structured totally differently in the way views are presented, for example, the underlying behavior being modeled should be generic. For example, my Rise app contains a workout timer. The acts of increasing a time counter and determining what to do when a certain time is reached should be modeled without any dependence on the user interface. However, when it comes time to update the screen based on new information, one will need to use platform-specific libraries to do so.
So in short, Xamarin encourages good programming habits! The more code you are able to share between projects, the less platform-specific code you need to write.
However, it is worth mentioning that one can include platform-specific code in the Shared code section if one uses compiler directives. This is code that will only be processed by the compiler if the correct platform is being used (otherwise it is totally ignored). This looks something like
// we're in some class...
var rnd = new Random();
// pick file from 0..99
var quoteFile = 'quotes' + rnd.Next(0,100).ToString() + '.txt';
#if __iOS__
var quoteDir = '/some/ios/specific/directory/';
#endif
#if __ANDROID__
var quoteDir = '/some/android/specific/directory/';
#endif
var quoteLocation = quoteDir + quoteFile;
// ... load file into string
So the only thing that differs for each platform is the location where the relevant file is stored. This code should really be shared, and the compiler directives will take care of the directory.
Writing Android apps in C# is Fun!
I can’t emphasize enough how pleasant it is to write code in C#. I love Java, but C# addresses some annoyances I’ve encountered when developing my app in Android Studio.
Properties = automatic getters and setters
In Java, one generally creates protected or private instance variables, and only allows outside access via getter and setter functions. So something along these lines:
public class TennisBall{
String company;
public String getCompany(){
return company;
}
public void setCompany(String company){
this.company = company;
}
}
But in C#, this is made easy using properties!
class TennisBall{
public string Company {get; set;}
}
And you can access this property using dot-notation, as though it’s an instance variable. In the random quote example from the previous section, note that I modified the get method so that it does something other than return the current value. In addition, I did not specify a set method, as this is not a property one should be able to set.
Event handlers and listeners are easy peasy.
One of the more annoying aspects of writing Android code in Java is dealing with event handlers (admittedly since Java 8, there are cases where this can be made quite concise using lambda notation). At one time, setting a listener on a button, for example, required writing an interface that implemented a mandatory method to handle the event of clicking on the button:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("debug", "Button clicked");
}
});
Using lambda notation in Java 8, this becomes much nicer:
button.setOnClickListener(v -> Log.d("debug", "Button clicked"); );
But in C#, this is even cleaner!
button.Click += delegate {Debug.WriteLine("Button clicked");}
C# is the clear winner for interfaces that implement more than one required method. For example, in Java,
implementing a listener for changes in text is a nightmare:
textField.addTextChangedListener( new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0){
textField.setText("");
}
}
});
So you need to implement all three methods, even if you only use one! In C#,
you can implement each individually:
textField.TextChanged += delegate {
if(s.Length != 0){
textField.Text = "";
}
}
Beautiful.
Emulating through Xamarin is a bit slow
Compared to Android Studio, emulation in Xamarin is a longer process. Compiling takes longer, which is understandable for a cross platform tool like Xamarin. In my experience, the emulator can be a bit laggy. Either that or I’ve written my app much more inefficiently than I did before! It typically takes between 30 seconds and a minute to compile and load my Rise app, which isn’t bad at all! But it’s much faster in Android Studio.
I still haven’t finished the Xamarin version of my app, and I have lots of debugging to do. I will likely have more to say when I get through that process.
Conclusions
Xamarin is a pretty solid piece of software, and I must say that despite what middle school me would think, C# is a fantastic language for Android development! It’s similar enough to Java that there isn’t much more to learn, but it removes some of the annoying boilerplate code that can make Java development so time consuming. So I have a new language under my belt and had some fun learning it.