Getting Real Work™ Done on an iPad Pro
This is a Medium.com article by Edd Morgan
TL;DR: For certain workflows, it is 100% possible to be a write software on an iPad with as much efficiency as on a Mac. Here’s how I do it.
Did you know there’s a whole subculture of people who are determined to live in their vans? Like, exclusively. They eschew the burdens of living between bricks to adapt their vehicles into a simple, often minimal, “good enough” environment in which to eat, sleep and not bathe.
Well, get ready for the tech equivalent of living in your van: working on an iPad.
This is not a new thing. Many already do employ a tablet as their primary (or only) work device. iOS 11 and its greatly improved multitasking helped a lot with that, and PadLifers such as Federico Viticci and CGP Grey are championing the cause. But they’re writers, and video content creators. What of today’s code monkeys? Are we doomed to be shackled to our laptops until AI makes us irrelevant like every other occupation?
No, I say! I recently was inspired to see if it was possible to do my job (writing software) on an iPad Pro with a keyboard attached. Though I guess even the keyboard is unnecessary, but strongly recommended.
I’ve always wanted to be productive on an iPad. I mean truly productive. Not just “replying to emails with a single sentence” productive, I mean really writing software on it. The focus of the iPad (and iOS) has always been so attractive to me – it’s just a rectangle with nothing but your current app to steal your attention. It’s a peaceful environment, save for notifications flying onto your screen, but they can be easily tamed (my notification settings for iOS are minimal). The primitivity of multitasking has been a feature of iOS for a long time, and the new additions in version 11 have simply made it more convenient to use multitasking – it fortunately retains the limitations of working with no more than two apps at a time.
On my Mac, I mostly live in a terminal window. I write code, I run and test that code, and when I’m finished I push that code to a central git repository – all in a terminal window. Sure, there’s also web browsers, email apps and group chat clients that consume 200x more memory to fill my display with emojis than it took to send a robot to an alien planet. But my core productivity happens in a terminal. I wished I could have that same environment on an iPad, so I decided to see how far I could go to make that dream a reality.
The Development Machine
Somewhere deep below the surface, an iOS device is a Unix machine. Just like a Mac. Unfortunately there’s no way to access that layer. I can’t fire up a terminal and start working. That’s a clear non-starter, so I realised pretty quick I would have to host my development environment remotely. Two options presented themselves to me. I could:
- Remote into my MacBook Pro. This would require it to be powered on and available over the network (preferably over the Internet) whenever I wanted to work. This approach has its benefits, but ultimately I just couldn’t guarantee that availability. So, my other option was to:
- Host it on a remote server. A VPS perhaps. Yeah that sounds pretty good.
It would incur an additional cost (more on cost mitigation later), but knowing that machine would almost always be online and ready to go is more important than you might think. It also gives me the ability to scale the machine up or down as needed. I could have a development machine with 2GB of memory, then up it to 32GB in a matter of seconds, then back down to two when I was done with that particular task. Can’t do that kind of bidirectional vertical scaling with a laptop.
And so it was decided. But where should this machine live?
The Hosting Platform
Why, DigitalOcean of course (observe my seamless affiliate link integration). I host a number of things there anyway. I know their platform and offerings well enough. AWS, Linode, Vultr – there are a number of perfectly good alternatives. Don’t yell at me because I’m not using your favourite.
A 2GB machine at DigitalOcean will run me about $20 a month. That’s not going to break the bank by any means, but it feels weird to be paying for a machine I’m only using approximately eight hours a day. I guess that’s why they offer per-hour pricing.
Of course, I can’t just power the machine on and off when I’m not using it. Cloud hosting platforms will almost always still charge you for a powered-off machine. Therefore, for a true pay-as-you-go pricing model for my development environment, I would have to delete and recreate this virtual machine as and when I needed it. That’s when things get trickier.
Obviously I don’t want to have to log in to DigitalOcean’s management panel every time I want to get some work done to spin up a server, set it up, secure it, install everything I need and then get going. That’s absurd. I had to automate that. Is iOS capable of such automation?
It is, silly! Workflow (recently acquired by Apple itself) is an app that provides a graphical programming environment meant to automate common tasks you perform on your iOS device. It can also make HTTP requests, meaning I could use it to interact with the DigitalOcean API!
I had to build a workflow that did the following things:
- Provision a new virtual machine
- Reimage that machine so that it is identical to the previous development machines I have used
- Attach a known, constant IP address to it so it is always available at the same address (optional, but super helpful)
- Power the machine off when I was done
- Take a snapshot of that machine to restore on new machines at a later time
- Delete the machine so I didn’t get charged for it any more
And I did. Here’s the workflow for you to import and use (you’ll need a DigitalOcean API key).
Now, with a single tap (and maybe 30–45 seconds of waiting – I’d like to reduce that, but it’ll do fine) I can spin up my development server in the exact state I left it in when I was last finished with it.
Note: if you want to do this, you’ll need to create a “floating IP” on DigitalOcean to assign to your machine. You create these per-datacenter, and as far as I can tell, these per-datacenter IPs can only be reserved through the API, not the web UI. Once a floating IP is created, you can assign it to whatever machine you want within that datacenter.
I use a 64-bit Ubuntu 17.10 image. All the SSH public keys I need (basically those of my iPad and my MacBook Pro) are authorised to connect without a password, all I need to do is type mosh eddbox in my terminal app to connect to it.
Wait, what? Terminal app?
Yeah, terminal app. There aren’t many of them on iOS unfortunately. Promptby Panic is a popular one, but it has some serious flaws that make it unsuitable for me:
- It doesn’t persist connections. You basically have to keep the app open and active for as long as you’re using it. You can’t switch to another app, lest you risk losing your session.
- It doesn’t support remapping of keys. This is a weird quirk that is surprisingly important. It’s common practice these days to remap your caps lock key to “escape”, especially for vim users. I have trained myself over the years to hit capslock when I mean escape, and that’s muscle memory you just can’t easily unlearn, especially when you only need to unlearn it when in a certain context. Also there’s not even an escape key on the iPad keyboard, so, yeah.
That first one is really a limitation of SSH, and is rectified by mosh, which Prompt is actually legally unable to implement because it’s not open source. Another app, Blink, is open source (it has a $20 price tag on the App Store, which you can get around by compiling it yourself, but I encourage you to pay it to support the developers). And it can remap capslock!
Mosh – “Mobile Shell” – is fantastic. It’s the shell for the mobile age. It keeps sessions open for me, which means I can switch apps with abandon and even switch networks (great for when working in coffee shops, over LTE, across VPNs, or on a plane over Mongolia). Without it, and the Blink client, the PadLife dream is dead. Combine it with tmux, and I have a basically uninterruptible terminal session. I can even resume the same session on my Mac if I wanted to.
Mosh also deals with latency very well, for when I’m on a slow network. The rate at which my client updates is not closely tied to the rate at which I can receive those updates to the server.
I use Docker to package, manage and isolate services that support individual apps and projects I work on. And what’s more, it’s Linux! So no need to run these services in a virtual machine like on macOS, meaning native performance (slow I/O plagues my Docker experience on Mac).
A single rectangle on my desk with nothing but some tmux panes. I’m on some zen shit right here.
The Native Apps
No offline working. Yeah this is kind of a big deal, but that deal is decreasing in size all the time as fast internet access becomes more ubiquitous. For now, I’ll have to bring my MacBook Pro if I foresee having to work offline. Which is fine, I’ll deal with that for now.
Are there are other issues around this setup that I’m missing? I have run into very few problems so far, but maybe there’s some dealbreaker I have yet to experience.
All in all, it’s a very freeing feeling. Maybe I’ll get bored of it and stop using it. And if I do, that’s fine. It’s been a fun experiment.
Back in high school, some of our computer rooms didn’t have real computers, but thin client terminals. They were cheap and the experience was excruciatingly slow – as dozens of kids were all projecting their desktop experience running on the same server to their displays.
I feel like I’ve come full circle.