Grappling with software development on an iPad Pro

Lincolns Rock from Wentworth Falls Lookout
Pana GX7, Pana 12-32mm, 2020 Wentworth Falls, NSW Australia

Software development on an iPad Pro is possible but not straightforward. Here’s how I set up a Raspberry Pi companion device for software development on the iPad Pro.

I’ve tried a variety of ways to do software development on my 2018 iPad Pro. I have almost every coding editor available, a Linux shell emulator, Pythonista and more. Nothing comes close to a laptop development environment. Even using cloud compute for test and run activities, development directly on the iPad just didn’t cut it. In the end, there were two key issues:

  1. There are some great text editors available for the iPad, but excluding iVim, none allow you to do search/replace across a project. Refactoring (e.g. rename a function) is consequently a nightmare. iVim is OK if you can deal with vi/vim modal editing and a mostly text-driven UI, but that was a step too far for me.
  2. The kicker is that all of the browsers on the iPad are based on Apple webkit and don’t include any inspect or debug capabilities. If you’re building a web application, it becomes impossible to test or debug.

My solution was to use a Raspberry Pi 4 as a companion device, as popularized by TechCraft on his series of YouTube videos.

My portable setup

portable setup

The iPad powers and connects to the Pi via USB-C. I drive the Pi interface with Jump Desktop which allows me me to use the iPad screen as a trackpad and is generally pretty friendly for portable useage. My parts list:

  1. Apple magic keyboard (mine is the older version)
  2. Incase Origami keyboard cover/stand (Studio Neat has the Canopy for newer keyboards)
  3. Raspberry Pi 4 (4GB) with 128GB Samsung EVO SD card and Raspbian in an Argon Neo case
  4. 15cm (6”) USB-C cable (USB-2 spec). Until recently, Pi 4 devices like mine had an error in the USB-C wiring, and can only be powered by USB-2 spec cables. USB-3 spec cables don’t generally work.
  5. The headmelted build of VS Code for ARM.

I made two changes to /boot/config.txt on the Pi:

  1. enable ethernet over USB
  2. Set the screen resolution to match the iPad Pro aspect ratio and give reasonable default font sizing:
# enable ethernet over USB
dtoverlay=dwc2

# force a console size for use via VNC
framebuffer_width=1600
framebuffer_height=1200

I also locked down the VNCConnect connections configuration a little, since VNC is not a particularly secure protocol:

  • Connections from the iPad via USB are permitted
  • Local connections are permitted, allowing ssh tunnels to work from other sources
  • Other connections are rejected

Adding power

To charge the iPad while connected, I added:

  1. A USB-C hub with power delivery (mine is from blupeak, cost ~AUD$55 (~USD$35))
  2. A 15cm (6”) USB-A to USB-C (USB 2.0) cable to connect from the hub to the Pi
  3. A logitech M238 wireless mouse (easier to drive the UI and worthwhile for the portable setup too)

powered setup

A few notes are worthwhile:

  • The Pi power + network only works via the Pi USB-C port, hence the USB-A to USB-C cable connecting the Pi
  • Hubs with an ethernet port don’t work: the network connectivity to the Pi works by having the Pi masquerade as a USB ethernet adapter and a hub ethernet port effectively hides the Pi.
  • You have to connect the Pi last when you set this up. The powered hub and its “master” (the iPad) negotiate power delivery to the USB-A ports when you connect to the master. This causes power to fluctuate at these ports and the Pi reboots without a clean shutdown (bad).

With an external monitor

If I have an external monitor (e.g. at the office) and a mini-HDMI to HDMI cable, I can connect the Pi to the monitor:

desktop setup

Notice that as long as Jump Desktop has the current focus on the iPad, keystrokes on the iPad keyboard are passed through to Raspbian. Having Jump Desktop as a slideover app is sufficient, which means I can fairly easily switch between coding on the Pi and local apps on the iPad. I could connect a second keyboard directly to the Pi but this takes a bit more desk space and means more to carry when I’m heading to a remote office.

When using an external monitor, I modify /boot/config.txt and comment out the forced console size so that it will auto-detect the monitor resolution. Note that Raspbian sometimes boots twice (i.e. automatic reboot) to detect the resolution.

It is also possible to connect the monitor to the iPad via the HDMI port on the USB-C hub since Jump Desktop does quite a reasonable job of driving the external display, but the poor handling of external monitors in other iPad applications makes application switching a bit clunky.

File sharing

I’ve installed and enabled samba on the Pi so that the iPad has direct access via the iPad Files application. Installation:

$ sudo apt install samba samba-common-bin smbclient cifs-utils
$ sudo smbpasswd -a <your-pi-username>

The latter command sets a password and enables your account for SMB access.

Key config changes for /etc/samba/smb.conf were as follows:

[global]
  ...
  # lock it down so only loopback and USB connections can access SMB shares
  interfaces = lo usb0
  bind interfaces only = yes

  # I prefer to maintain separate SMB passwords
  unix password sync = no

[homes]
  ...
  # allow writes to home directories
  read only = no

The interfaces config ensures that SMB is only enabled locally (loopback) and via USB to limit security risks.

I haven’t worked out how to reliably force samba to apply new config (systemctl restart smbd; systemctl restart nmdb doesn’t seem to work reliabily). In particular authentication from the iPad seems fussy so if you have problems, disconnect the Pi in iOS Files and restart.

So does it blend?

This setup is convenient and works reasonably well but is far from perfect. Issues encountered include:

  • I’ve found that a number of dev tools and applications don’t run out-of-the-box on ARM devices. For example, a Ruby gem (therubyracer) builds a nodejs environment using the depot tools when installed. The depot version used doesn’t support ARM as a target architecture. Workaround was to use an alternative gem.
  • There are quite a lot of docker images that don’t have an ARM build (ElasticSearch, for example). Workaround is to install the app locally or build a custom image, assuming it will run on ARM.
  • The Pi 4 is sometimes slow. For example, I use jekyll to build static web sites and it takes ~20 seconds to rebuild one of my sites compared with ~2 seconds on my 2015 Macbook Pro. I/O speeds quite likely contribute, so connecting a fast SSD or NVME drive might help, but this detracts from portability. Note that the jekyll incremental build feature is currently quite buggy and didn’t work on the Pi at all.
  • The combined weight of these bits is around 2kg which makes it heavier than quite a number of lightweight Intel laptops. The iPad cover and keyboard + cover count for a big chunk of this weight, so replacing them with an Apple keyboard folio would bring us down to about 1.5kg (if you can live without a dedicated Esc key).
  • Rasbian doesn’t like having the power removed, so if you run out of juice or accidentally disconnect from the iPad before shutting down cleanly, you risk corruption of the SD card.
  • I’ve had trouble finding an intuitive keymapping for VS Code on Linux for someone coming from a Mac. The default X11 config on Armbian also grabs the Option and Cmd keystrokes for system menus. This is fixable but I haven’t got there yet.

These issues have workarounds but make it a less productive environment for coding than a traditional laptop.

Some solutions

I have plans to address most of the issues above by using cloud compute as suggested in a couple of my previous articles. The likely setup would be:

  1. Use VS Code on the Pi in remote mode for development on a cloud host or kubernetes cluster.
  2. Buy a lighter and more compact iPad keyboard/case to address the weight issues. The new iPad Pro magic keyboard looks like an awesome device and is a likely candidate, although at time of writing the weight is unknown and it’s bloody expensive!
  3. Add a PiJuice hat so that the Pi is not affected by disconnection of power. It means a bulkier case for the Pi however. The iPad Pro magic keyboard might make this less urgent since it has a USB-C port for powering the iPad (in effect a second USB-C port on the iPad).

Or I could just rub my lamp and ask my genie for a VS Code remote client and debug-capable browser running natively on the iPad! iOS 14 perhaps?

Written on April 6, 2020