I have over 35 years of experience in programming on environments varying from mainframe, midrange, small systems to PC’s but never have I met so many problems in one development process.
The past 6 months I’ve been developing just 1 app for Android and iOS and it has been an experience that gives me mixed feelings about mobile development. Don’t get me wrong I just love programming in general but this… this was different.
This is what the app is supposed to do:
- Register the device with UserId and Password via a webservice.
- Enter a TAN once for the registration and verify it via a webservice. This authenticates the device with the server just once.
- Add an Application (website) one wishes to verify. There are 5 websites notifications can be received for.
- Accept push notifications from the server via Firebase when a user wishes to authenticate for a website.
- When a notification is received:
- When received from a webbrowser on a PC start a QR code scanner and scan the code that is shown on the webpage. When the information in the QR code equals the information in the notification accept the verification.
- When received from a mobile device show buttons ‘Accept’ and ‘Cancel’.
- When ‘Accept’ is clicked tell the server the authentication is accepted via a webservice.
- When ‘Cancel’ is clicked tell the server the authentication is not accepted via a webservice.
- The user must be able to add more websites to the registration.
- The user must be able to remove websites from the registration.
It was decided that the app would be built with MvvmCross with native code and not Xamarin.Forms A consultant from a external softwarehouse told us that as long as you stay with the controls provided you’re ok but when you need something extra you would have to write your own renderers which is a pain. And of course he knew MvvmCross very well. For the record, I had more experience with XAML at that time and favoured Forms. Also bad experiences with third party UI controls had influence on the decisions made.
It was also decided we would use PCL for the Core functionality. I would have liked to go with .Net Standard but that was not covering all needed functionality at that time.
MvvmCross forces you into the MVVM pattern which is a good thing. You have to think about reusability of code all the time and separate generic functionality and device specific code as much as possible.
Learning MvvmCross was a first. It’s a good concept and overall works pretty smooth. The MVVM pattern was not new to me which gave me a headstart. The difficulty with PCL in combination with native code is the communication between the libraries. You can access PCL from native but not (easily) from PCL to native. MvvmCross bridges that gap easily using Inversion of Control (as Forms would have done). With the help of the consultant MvvmCross was learned quickly. It does however have some perks. Because of late binding the linker sometimes does not know that you’re using certain functionality and does not add it to the endresult which leads to confusing situations. But once you get the hang of it you’ll recognize these situations pretty fast. A pitfall is debug and release mode. In debug mode the linker adds everything all the time but it does not do so in release mode causing the app not to work correctly in it’s final release.
Because Xamarin is under constant development you’re on the bleeding edge and because you have to conform to two (or more) different platforms you better be prepared to meet frequent crashes and hangs, wrong builds without any clues why, slow performing builds, frustrating provisioning issues with Apple’s paranoid and absurd complex protection system in combination with wrongly cashed information, differences in layout, OS versions, screensizes of the individual devices you’re building for, etc.
Documentation is sparse, incomplete or deprecated and very often not applicable for your development choices. A lot of the examples come from websites like Stackoverflow but are for a plethora of applicable development choices. You can have examples for Swift, Objective-C and C# for Apple in combination with explanations for Xamarin Studio, XCode, Visual Studio on PC or on Mac. Very often you can deduce from the Swift and Objective-C examples what it should be in C# because luckily the interfaces written very often follow the same name conventions but sometimes it’s not clear or just plain difficult. Without the community development would have been very very difficult if not impossible. Solving everything on your own is very time consuming and sometimes very frustrating.
Using the Xamarin designers needs a lot of getting used to. I really had trouble understanding the constraint system used on iOS devices. I’ve been tearing my hair out why a design was shown correctly in the designer but not on the simulator or device. I finally got the hang of it but It’s been a struggle. The designers are not stable at all. For XAML I was able to grasp the syntax in XML quite quick but the XML of iOS views is hugely complex and I still haven’t got that in my skillset so I rely on the designer heavily. The XML of Android views is quite concise and easy to understand so I hardly ever use that designer. For data binding Android views with MvvmCross you have to edit the axml by hand (at least I’ve not found a way via the designer yet).
Bugs, bugs, bugs
Sometimes development progress comes to a grinding halt when again some kind of problem with the development environment crops up. I’ve had hangs during solution loads, during debugging and deployment. Sometimes deployment becomes impossible and you’re stuck being unable to test your app on a device. One day, because I was using my own Samsung S6, I really had to factory reset my it to be able to deploy to it again and I was forced to completely setup it up again (sigh..). Emulators (or simulators as Apple calls them) are a good solution for straightforward development and deployment to them is pretty fast. But not all functionality a real device can do can be done on an emulator. For instance Firebase is not supported in emulators. It is therefore imperative your final tests are on a device. This also causes difficulty. Who of us has all the variations in devices being used in the world? We use an iPad Pro for iOS and a Motorola G Play for Android testing. It has iOS 10 but we do not have a iOS 9 device. Some code is specific for these devices (Firebase) so how do we test that? Xamarin offers a service with lot’s of devices but that is pretty expensive to use.
You can be faced with the situation that the day before everything was working perfectly and the next day (after a fresh boot) everything seems broken. Builds just aren’t stable at the moment. Sometimes you end up with the situation having to clean up and rebuild your solution. Sometimes even that does not help and you have to manually remove all ‘obj’ and ‘bin’ directories just to get going again. In my experience changing something in PCL will cause wrong builds so you better be cleaning and rebuilding when changing something in PCL. And it takes a lot of time.
Turnaround times are just plain bad. Every build and deployment using a fast computer with a SSD and lot’s of memory still takes at least up to three minutes for a complete build(depending on the size of your solution of course) meaning that the a small change can take a relatively long time before it can be tested. For iOS development you have to have a Mac. We use a 2012 refurbished Macbook and it is pretty fast. All communication goes through a network connection and the Mac only has a 100Mbit port. Even designing a view in the Xamarin designer causes a generation process to start on the Mac. Although this is a bottleneck builds on a Mac are faster than the local builds for Android. Deploying to a real device is slower than deploying to an emulator for both iOS and Android. Frustrating is the fact that when you loose connection to the Mac everything just stops working. I very often loose connection and reconnect does not always work. You’ll have to restart Visual Studio to be able to reconnect.
Debugging is pretty good. There are limitations however. You can not edit and continue and you can not change the position of the current execution point. Because you’re testing against native code you’ll very often see that you’re in external code rather than in your own code when an exception occurs but that is not uncommon in other development too. The logs on the devices help a lot during debugging. You will have to filter out logging for your app because when you run on a device with a lot of installed apps logs can become very bulky. Stacktraces are very often native too (Java on Android and Objective-C on iOS). You’ll have to learn how to interpret these but most of the time it is pretty clear although I’ve seen some pretty confusing errors being thrown that put you off track. To quote a very famous Britisch detective: “If you can’t find the solution in the explainable investigate the unexplained.”.
Mobile development with Xamarin is time consuming and thus expensive. The platform, although it has been around quite a long time, is not stable. Because of the many different Development environments, Platforms and Programming possibilities the amount of knowledge and skills needed is huge making the learning curve pretty steep. Documentation is sparse, incomplete and often deprecated. The community is huge and very active. Before deciding about Development environment and architecture (Forms or Native, MvvmCross, PCL or .Net Standard) one should investigate the (im)possibilities very thorough. Once you have made you choices and head on with development it is hard to change.