When you develop for Xamarin.iOS, you are faced with the annoying fact that you have to use a Mac to build and debug your iOS applications. There are of course no technical reasons behind this requirement, it’s just Apple being Apple and forcing their hardware on every iOS developer (one can wonder how loud people would scream if Microsoft was forcing everyone to use PCs to run Windows…). Anyway, it is what it is and we have to comply.
There are multiple ways to setup a development environment for Xamarin.iOS. One fairly popular manner is to use a Mac laptop with a virtualization software (such as Parallels) to run both Windows and Mac on the same machine. This way you have access to Visual Studio for the development (including the visual designer, as well as any other tool you might be using for C# development such as Resharper, Nuget etc), and you have the Mac OS which is compulsory for the build process and the simulator. The main advantage of this method is that you need only one machine. But there are also a lot of disdvantages:
- The Mac needs to be a pretty good machine to run both the Windows and Mac OS at the same time. It cannot be a cheap (if there is such a thing as a cheap Mac) or old hardware.
- Virtualizing Windows is not 100% like running the real deal on the bare metal.
- The keyboard is not a Windows keyboard and so you have to learn new key combinations.
- The hardware is not for everyone. I don’t like touching a Macbook. They are cold (metal everywhere), and the edges are too sharp. Every time I open my Macbook it literally hurts my fingers. It’s not a friendly computer for me.
- No touch screen. Once you learn to develop on a touch machine, it’s impossible to go back. And in spite of what every Mac user will tell you, a touchpad is not a replacement for a touch screen.
- I just don’t want to give (a lot of) money to Apple.
With the profusion of great Windows hardware such as the Surface Pro 3, the Lenovo Yoga and more, it’s not too hard to see why many prefer to stay on a PC for Windows. It means that we need an external machine to run as a build server. Now to be clear, you don’t need a good Mac for that. It can be a Mac mini, or like in my case an old second (or third?) hand 2010 MacBook Pro is sufficient. You’re not going to use this machine for much, except for building iOS apps and running a simulator. In fact you don’t even need to use the keyboard or even the touchpad because you can use a remote solution like TightVNC. This has the huge advantage of allowing you to use the iOS simulator with your fingers, like it is intended to be, instead of having to compromise and use a mouse.
Of course it also means that when I am travelling and I know that I am going to do some iOS development, I need to pack the Macbook. When you are used to travel with a Surface Pro 3 only, that thing is big and heavy, and I have been looking for ways to leave it at home whenever possible. Now, when I am home, I already do that and leave the Mac in my office in a remote corner where it doesn’t bother me. My interaction with it is limited to turning it on and off. The rest of the time, I am anywhere in the house and connect to it remotely through the Xamarin Build Host and use TightVNC to visualize the screen (mostly I reduce the window size to the minimum needed around the iOS simulator.
The VPN solution
A few weeks ago I connected to our office VPN in Seattle. We don’t use it very often but we have some shares that are only accessible when on VPN, and so from time to time I connect to it and download the documents I need. And suddenly, as I was looking at the list of computers on the network (and all these Seattle machines), I realized that a way to leave my Mac at home even more often was to use a VPN connection. This way I could connect to my home network and the Mac would never know that I was, in fact, in Seattle, Beijing or Sydney.
I started looking on the web to see how I would setup a VPN server on the Mac. Keep in mind that I am an electrical and software engineer, and by no means an IT Pro person. So it took some time until I figured it out. Disclaimer: It is very possible that I misunderstood some of the settings. If I made a mistake in the description below, please let me know!
Pretty fast I realized that I had two options. The best one, the one that Scott Hanselmann describes in his recent article “Setting up a VPN and Remote Desktop back into your home with a Synology (from an iPhone)”, is to use a NAS server as the point of entry for your VPN. This way, your whole house is accessible. It is very attractive because you can also use the NAS server as a networked storage medium, media library (with Plex for example), and much more. In the long term, I will probably install something like this too.
For now however I wanted something simple and fast, without any additonal hardware. This is when I found this article describing how to run a VPN server directly on your Mac. This sounded exactly like what I needed.
The issues… and the solutions
Of course this requires a few steps. Notably, you need to configure your router to route all the incoming VPN traffic to the Mac machine. Also, there is the problem of the IP address of your house router: unless you pay for a static IP, it is going to change from time to time, and you don’t really know which IP to connect to if your ISP decides to change it. Finally, even within your own home network you want to assign a static IP address (192.168.XXX.XXX) to the Mac running the VPN server. This way, you configure once and it’s ready.
Setting up the VPN server on the Mac
Let’s start with the VPN server itself. Every Mac is able to function as a VPN server but the configuration is pretty complex and frankly unfriendly. This is why I decided to use iVPN, which is a UI based VPN solution for Mac OS. It provides a friendly UI that even I was able to understand and use. It is a commercial solution, but I am happy to pay 10 bucks for the privilege of not having to enter obscure UNIX commands in a console. iVPN also has a comprehensive support page where I was able to find the answer to all of my questions.
You need some information to setup iVPN but it is really very easy. First you need to setup the start and end range of the IP address of the machines that connect to the VPN. What it means is that my SP3, when connecting to the VPN server, will get a different IP address than when I connect directly to my router (in which the SP3 has a fix IP address). It’s probably not going to be an issue, but you want to avoid IP collisions with machines that are already running on your home network. In my case I assigned 192.168.1.100 – 192.168.1.200 which gives me plenty of room. I couldn’t find a way to assign static IP to the SP3, so let’s just run a dynamic one.
Another information you need to setup is the type of VPN you want to run. There is L2TP or PPTP. If I understand correctly, L2TP is more secure than PPTP but not every system connecting to the VPN server supports it. Thankfully you can easily run both in iVPN, which is what I did.
If you want to run L2TP, you need to enter a secret 64 bytes key which the client will also use to secure the connection. A good place to auto generate such a key is at grc.com. Every time that you refresh the page, a new key is generated. Simply copy/paste the key in the corresponding field in the iVPN dialog.
Once this is done, you need to configure one more setting: The username and password that your users (aka myself) will enter in the connecting device. You can do that by pressing the “Edit Accounts” button in the iVPN dialog, and enter any number of username and password.
After you are all done, you can easily switch the VPN server on/off from the title bar of the Mac OS as shown below. The icon will also light up green when a client is connected, and a notification is shown. You can easily find out who is connected to your server, and their IP address. I am not planning to run the VPN server all the time, as it is a point of entry to your home network. Anyone able to crack that is identified as pretty much yourself and has access to all your files and applications. So be careful with that.
Setting up the client
In order to configure the VPN connection on the client (in my case my SP3), I need three pieces of information: The username and password that I setup in iVPN above, and the point of entry to the whole thing. This is conveniently provided to you in the iVPN dialog shown above, with the legend “VPN Host Name”. Simply copy this value from iVPN into your SP3 and use this when you create a new VPN connection.
Here we hit the problem that I mentioned before: this value can change in time, unless of course you paid your ISP to buy a static address for your home network. I didn’t, and so instead I went for the next best thing: DynDNS.
This service provider is quite popular because it allows you to select a static URL for your own network. If the ISP decides to change the IP address, DynDNS will observe this and map the URL you chose to the new IP address. All your configuration (which is using the static URL) does not need to change!
DynDNS is not a free service, but it is again something I am quite happy to pay for to avoid having to remember to write down my IP address every time that I leave home, or having to call home in a rush and ask them to boot up a computer and check ipconfig /all. The minimum service that DynDNS offers is quite affordable at 5 USD per month. There is also a 14 days trial period which allows you to make sure that this is really what you want.
In fact I found out that my Swisscom-provided router and its configuration dialog even has support for DynDNS directly built in. That of course gives me confidence that it is a fairly solid solution for my needs.
After you are done configuring DynDNS, you can copy the Host Name value into the iVPN “VPN Host Name” field.
Setting up a fixed IP in my home network for the Mac
Long time ago I assigned a fixed IP address in my home network for all my important machines (print server, my SP3, the Macbook, my media server etc). Not having to look for or remember a new IP address every time I need to access a machine is making life easier. Every router has a different configuration panel, but just for reference, this is where you do this in the Swisscom router:
Setting up port forwarding
The last thing I needed to do in my router settings is setup the port forwarding. This is needed because you have only one point of entry to your home network. Depending on the type of traffic, it needs to be forwarded to the correct machine behind the home router. For instance, I have a Plex server setup on my media server. When I am out of the house and want to watch a video on my Plex server, the client connects to my home router and says “hey I want Plex stuff” (which means it says “connect me to port number so and so”). The router checks its rules and sends the traffic to my media server.
For VPN servers, you need to forward four ports: 500, 1701 and 4500 (for L2TP) and 1723 (for PPTP).
Connecting to the remote desktop
The last thing you need is to allow remote desktop connections to your Mac. This way I can not only connect to the Xamarin Build Host but also run on the simulator and visualize the results on the SP3. Like I said, I set this up long time ago so I almost never need to touch the Mac, and also to get touch control on the iOS simulator. To do this, you need to go on the Mac OS in the System preferences, and follow the instructions from this page.
Once I set this up, I installed the TightVNC client on my SP3. Setting it up is super easy: Simply enter the IP address of the Mac you want to connect to. And here we have the beauty of the VPN server: Since my SP3 is connected to the VPN, I can access all the 192.168.XXX.XXX IP addresses within my home network, and so I don’t need to change the value in the TightVNC client, even when I travel.
Then I can connect and run stuff on the Mac, for example the iOS simulator:
When talking to my good friend Corrado Cavalli about this solution, his first question was about performance: How good is the connection to the Xamarin Build Server, and is it really usable?
I ran only simple tests so far, by connecting my SP3 to my mobile phone (to simulate that I was outside of my home), and connecting to the VPN. As far as I can tell in these near ideal (4G) conditions, the connection is fast enough to allow serious work. Even opening a (simple) Storyboard is not that bad, though it is of course slower than when everything is on the same physical network. The real test will be this week and I try to connect to the VPN from the US, and especially from a hotel room with a crappy WiFi (I expect). I’ll make sure to report my experiences here. To be clear: it is possible that it just isn’t good enough. And it doesn’t mean that I will never ever travel with my Mac anymore. In some cases where intensive iOS work is needed, I will probably take the machine with me.
But for casual usage, and if your connection is good enough, it might prove a “good enough” solution which could prevent me from dragging around the heavy Macbook.