Breaking Windows, macOS, iOS, Android, and Linux since 2013
Why your Xamarin Forms 2.3.x project stopped working in Visual Studio for Mac
On May 10th, 2017 Microsoft launched the public release of Visual Studio 2017 for Mac. It is intended to be a replacement for Xamarin Studio as it integrates .NET Core along with Xamarin and cross platform game development components. From a UI standpoint it looks very similar to the latest version of Xamarin Studio, but under the hood a few key changes are lurking. The one I am concerned about is the switch from xbuild to MSBuild as the build system for Xamarin.iOS. MSBuild was optional before but is now the default system. For many projects, the transition is seamless, but for those who are using the outdated 2.3.x versions of Xamarin.Forms, a huge problem is evident: it does not support MSBuild at all. In fact, many builds of 2.4.x do not work, but the latest version guarantees compatibility. This was a rather perplexing problem that took me a while to figure out because I had no idea why the build process was failing in both Xamarin Studio and Visual Studio for Mac. Since the VS for Mac installer bundles the latest versions of Xamarin.iOS and Mono MSBuild is the default in both VS and Xamarin if you use them side by side on the same machine. Trying to build a project that uses the 2.3.x version of Xamarin.Forms will fail with a xbuild failure to start error on VS and a missing pdb file error in Xamarin Studio. This could be avoided if Microsoft warned about potential incompatibility with apps that rely on xbuild. This leaves me with two options: roll back to an earlier version of Mono and Xamarin.iOS (which is basically uninstalling everything and reinstalling Xamarin Studio which is a huge pain), or figuring out how to safely update to the latest version of Forms. This is tricky since there are many crucial packages in my solution that rely on this specific version of Forms, so all of them will need to be updated without breaking functionality or legacy code. This is the only way to ensure things will work properly in the future since Microsoft has stated that VS for Mac will be the future for Xamarin. This means that in order to stay up to date with Xamarin, we need to be using the latest version of Forms. This will not be an easy task, but who said cross-platform development was easy?
Update macOS through Terminal
Downloading updates in the Mac App Store, especially Xcode, has always given me problems. Recently I discovered that you can actually update system software and 3rd party apps via Terminal using the "softwareupdate" command. To list the updates, issue "softwareupdate -l" and install them with "softwareupdate -iva" which will install all available updates. If you want to install a specific update, just use "softwareupdate -i 'name of update'". Make sure you have sufficient user privelages before installing.
My Experience with Red Hat Enterprise Linux
I have been installing and running Linux distributions on various computers since I was in middle school. I have deployed Ubuntu, Fedora, Debian, Mint, openSUSE, and Kali on Raspberry Pis, laptops, and desktops. My website and this blog run on Apache HTTP installed on Raspbian on a Raspberry Pi 3. I am a big fan of Linux in the server space, but have never really liked in on a desktop or workstation. I tried using Ubuntu for a few months but eventually just switched to Windows and macOS for full time use. All of the software I used for work and college were on those two platforms, so I had no need for using Linux on my desktops and laptop. Recently, I discovered Vagrant and started reading more about Linux so my interest peaked again. I learned that Red Hat Enterprise Linux (RHEL) was available for free for development use. I went ahead and set it up inside of VirtualBox on my Mac mini and got a taste of Linux designed for enterprises.
The setup GUI is identical to that of Fedora because well Fedora is the community driven variant of RHEL. It was well laid out, easy to understand, and a relatively quick install. One thing I really liked was the ability to select development tools and such to be installed with RHEL so you don’t have to install all of them in post. This gets the basics such as gcc and java and such installed. I forgot to install the desktop environment, but that was surprisingly easy and fuss free in post install.
Upon first boot I was greeted with just a command prompt through which I first registered my free developers license with Red Hat, updated my packages with yum (more on that later), and installed the GNOME desktop environment. My first experience with GNOME was on Ubuntu 10.10 which, now 7 years old, is still the best Linux desktop look and feel I have used. You can get the feel of the GNOME of yesterday with classic mode which I what I use because the newer look of GNOME is not very appealing to me.
I have only used RHEL for a few days and plan on using it mainly for tinkering and learning more about the operating system. My favorite bit so far is probably the yum updater. I am used to using apt because I used Debian on both of my Pis and therefore I am also used to the issues associated with apt. Slow updating of packages, problems with update mirrors, problems with packages conflicts, etc. Maybe its just because I just started using yum, but I think it is a significant step up from apt. I found it faster, safer in terms of validating packages, and easier to use because I can check for, download, and install packages in one command versus two using apt. I haven’t really done much else so far because again I don’t really have a specific practical use for my RHEL install, but I will be updating my blog on anything interesting I come across.
A FEELING OF RELIABILITY AND FINAL THOUGHTS
Upon using other Linux distros I have always had a feeling of something will break eventually and cause me a fortnight to fix. Now I know, things will also break and cause a fortnight to fix on Windows and macOS but in general I feel most desktop Linux solutions are simply harder to maintain. You have to be very careful with everything you install and how you manage your system. Perhaps its just because I have been using Windows and macOS full time for so long and only having to deal with Linux for server administration on a very small scale. But with Red Hat, I feel like I am using a genuinely robust Linux system. It feels more like Windows Professional or macOS Server rather than Fedora. I guess its the track record and heritage RHEL has in the enterprise space. It is designed not to be stylish or user friendly, but rather secure, fast, and focussed on delivering a reliable system for the backbone of an enterprise environment. There is something almost utilitarian about it and I love it. While every other distro is looking forward on features, ease of use, and wide application support, Red Hat is looking forward on building the most reliable system possible. If you are interested in Linux or operating systems in general, I urge you to try Red Hat. Many will say that its basically a business marketed version of Fedora or CentOS, but it really isn’t. It is a very focussed operating system built to run anything from small websites and blogs to a Fortune 500 company. I guess that is the beauty of Linux, its ability to scale without loosing its open source charm.
Xamarin Tips and Tricks - Custom push notification sounds on iOS and Android
Upon the receiving a push notification, iOS and Android will automatically use the default tone for the notification (or just vibrate if your device is set to silent). Normally, you would have to change the notification tone within settings, but if you want your app’s notification tone to stand out from the default tones, you can set your own notification tone. Today we will look at how to implement this in Xamarin.Forms (you will need a dependency service for this to work since the Android and iOS solutions use platform specific code).
Before you can use your custom notification tone, you need to have it in the .caf format for it to work inside of a push notification (MAKE SURE YOUR SOURCE FILE IS 30 SECONDS OR LESS IN DURATION). To do this on macOS, issue the following command in Terminal: afconvert -f caff -d [email protected] input.mp3 output.caf. Now that you have converted the file, you need to add it to your iOS Resources directory. Inside Xamarin Studio, under your iOS solution right click on the Resources folder and click “Add files” and select your converted .caf file. Now that you have the file converted, we can build a local notification with the custom tone:
IMPORTANT NOTE: iOS limits 3rd party apps on how long notification sounds can play to 30 seconds. Banner style alerts (the default style) only allows a few seconds, so the user will need to change the alert type to “Alerts” under Settings > Your App > Notifications > Alert Style When Unlocked. You will also need to make sure your sound file itself is only equal to or less than 30 seconds in duration.
You can use a .mp3 file of any duration you see fit because we won’t actually be using the notification’s tone payload to play the sound due to some quirkiness in the way Xamarin handles custom notification tones on Android. We will actually build a notification and then use Xamarin MediaPlayer to play the tone when the notification fires. First we need to create a new folder inside of the Android solution’s Resources folder. Right click on the Resource folder and click “New folder”. Name the folder “Raw”. Now add the .mp3 file into the Raw folder. The gist below shows basic notification setup:
IMPORTANT NOTE: Before compiling, do a clean and rebuild of the project using right click -> “Clean” and right click -> “Rebuild”. This will solve issues involving the resources folder not being compiled properly. Highly recommended every time you add new files to the folder.
Setting up Vagrant
Here is a quick video I made for some basic Vagrant setup on macOS Sierra:
Xamarin Tips and Tricks - Clearing Lists in C#
Sometimes, using the built-in Clear() function on C# Lists may not always work. For example, I needed to clear a list of all its contents every time I returned to a Page view. Using the Clear() function was not clearing the list properly and thus resulting in the Page crashing. Although it may not always be the most obvious solution, if you are every getting IndexOutOfBounds exceptions when dealing with clearing a list, you may want to try doing it the old fashioned way - using a for-loop to traverse the List from head to tail and using the RemoveAt function to remove the object. Here is a snippet of the function below:
This simple function can solve some major issues regarding clearing of a list. This can really be applied to any language in any situation where the built in clear function is not doing the proper job. Thanks for reading, and stay tuned for more updates.
Xamarin Tips and Tricks - Compressing Videos in Xamarin.Forms Projects
Today I will be starting a series of Xamarin programming tips and tricks that I have learned from different projects I have worked on. Lets kick this off with platform specific video compression in Xamarin.Forms. Since media encoding is done differently on iOS and Android, we need to write different solutions for Forms projects. We will be taking a look at iOS media compression today. Our media will be picked using Xamarin's Media Plugin (Plugin.Media), which delivers the picked media in a MediaFile object. We will then pass this object into our compression method which will then send it back out as a file stream. You can view a gist of the method involved below:
Your MediaFile will have its uncompressed mov file taken out of it, encoded again with higher compression at a lower resolution using the native AVAssetExportSession, and sent back out as a stream. All of this runs in async and is fast on new(ish) iOS devices. You can change the amount of compression applied by modifying the export preset as well as change what type of object the file gets sent back out as (a stream is the easiest to work with especially if you are planning on uploading the file to a web service). These methods can be easily dropped into a platform specific class using a dependency service to call upon it when needed. Also note that you will have to create a public interface for this as well.
Fixing Raspbian apt source list
Updating via apt suddenly stopped working for me today on both my Raspberry Pis with one on Jessie and the other one on Wheezy (it got stuck on waiting for headers). Took me a while before I figured the mirror director was the problem (I guess there is a outage with one of the mirrors). Inside the apt source list, commenting out the mirror director entry and replacing it which archive.raspbian.org fixed it.