Microsoft Surface

Yesterday I was listening to the latest episode of ATP where one of the hosts discussed what he saw on his recent flight.

The host as many of the Apple customers has few different devices in each category. And him being an independent developer he tries doing work on the go. That's where to his flight he brought his MacBook Pro which he uses for development and his iPad Pro that he uses for everything else. And this is a real case: you can't code not on an iPad because Xcode requires a proper desktop OS, in this case Mac OS. But doing everything outside coding is more often better doing on an iPad (or tablets in general, but since Android tablets are essentially non-existent, I'm using the most successful tablet for reference).

For the flight the host took an almost $3k spec'd MacBook Pro and the most current generation bezel-less $1300 iPad Pro. And what he was doing with them? As most developers do - coding on the Mac and browsing and reading Twitter on the iPad, because the former is limited to Mac OS and requires typing via a proper keyboard and the latter is done so much better via touch on an all-screen device.

From the host's story he saw a guy next to him using a Microsoft Surface Pro or Go. And that guy used it for a while like a laptop, then flipped the keyboard and used it like a tablet, adding some pen input from the stylus. And all of that in one convertible device with a touchscreen, which starts from $500 for the Go up to only $1500 for the Pro. Whereas if you're in the Mac ecosystem, you would have to have to pay 2x-3x more and struggle with two separate devices, charging and managing them separately, etc. Even if Apple is building something for a bright future, Microsoft actually delivers something already.

I've played with the Surface lineup few times and was amazed how well built the devices are and how well-thought, well-designed and sturdy their stand mechanism is. Yes, they might not have USB-C sometimes at all, so they're less future-proof, but they are well equipped for now and who knows when. I'm in the USB-C (aka dongle) world for two years already and the transition to it is painfully slow, albeit faster than before the USB-C push from Apple with their latest laptop lineups.

Another situation was when we went to our friends and one of them was swiping pictures on her laptop. My wife was blown away with a touch screen on a laptop, since she has been surrounded with non-touch MacBooks all the time. And although a laptop with a touchscreen looks like a mess from all of those fingerprints, people actually enjoy using them, the same as everyone does enjoy using their smartphones despite them being covered with skin oil 🙂

Sometimes it feels stronger than ever that Apple lives in their own universe where people use what Apple thinks is best and not what people actually enjoy and understand using. On one hand Apple brought the touchscreens into the masses, but on the other they refuse bringing them to the laptops despite people nowadays trying to touch each screen by default and then revert to physical controls. Having an iPad in Apple's lineup helps but its OS still is very limited to let the iPad replace traditional computers.

Speaking of OSes, for me having Windows on the Surface is the big downside. I worked with both Mac OS and Windows for years and Mac OS is so much better for work. Although I would admit, with Apple's major focus on the iPhone and iOS, Mac OS becomes more and more overlooked overtime with clumsy bugs creeping in over and over again. I wish we would get a touch-based Mac OS device or a major improvement in iOS's productivity, so Apple users would be also able to get a one for all device in the nearest future. And I hope Apple's direction is not just towards the PC market at all.

Setting up Fastlane for mobile automatization on Mac OS

Fastlane is used to automatize different routines in mobile development. In this note (or serious of notes) I'll describe how to use Fastlane to automize your iOS project builds and uploads to TestFlight.

You start by installing latest Xcode tools
xcode-select --install

Next, you install Fastlane via RubyGems
sudo gem install fastlane -NV

or via brew
brew cask install fastlane

Then cd to your project and initialize Fastlane:
fastlane init

Last, edit fastlane/Fastfile to this:

platform :ios do

  before_all do
    ENV["FASTLANE_DONT_STORE_PASSWORD"] = "1"
    ENV["FASTLANE_USER"] = "<Your App Store Connect email"
  end

  desc "Build and upload to TestFlight"
  lane :beta do
        build_app(scheme: "<Your project's scheme>",
                      workspace: "<Your project's>.xcworkspace",
                  include_bitcode: true)
        upload_to_testflight
  end
end

If you want to store your password in the Keychain, just remove ENV["FASTLANE_DONT_STORE_PASSWORD"] = "1"

If you want to store your password in the Fastfile, add ENV["FASTLANE_PASSWORD"] = "<yourPassword>" into the before_all do / end section.

Now run 'fastlane beta' in your Terminal and enjoy an automatic build and upload to TestFlight 🙂

You can use this manual on your own computer. For running it on a remote machine look out for part 2 of this series.

Autostart scripts and services on Mac OS with launchd

When it comes to autostarting custom scripts/services after booting your Mac, adding stuff to start with your system on Mac OS might now be always possible via System Preferences.app -> Users & Groups -> Login Items. [1]

So in order to make your script or service to launch on start, follow my example on running a DynDNS service on boot and each 5 minutes afterwards.

First start by creating a shell script that launches your service. In my case that's a script that curl's a specific url with parameters of my current IP to assign it to the domain I'm using:
nano ~/Documents/dyndns.sh

with:

IP=$(curl ifconfig.co)
curl "https://dynamicdns.park-your-domain.com/update?host=@&domain=example.com&$

Next I create a system service plist:
nano /Library/LaunchDaemons/dyndns.plist

And enter the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
        <dict>
                <key>Label</key>
                <string>com.igor.dyndns</string>
                <key>ProgramArguments</key>
                <array>
                <string>/bin/sh</string>
                <string>/Users/igor/Documents/dyndns.sh</string>
                </array>
                <key>RunAtLoad</key>
                <true/>
                <key>StartInterval</key>
                <integer>300</integer>
        </dict>
</plist>

You can avoid the StartInterval key if what you need is just to load on start. You also might label your service something else than com.igor.dyndns

If you're launching your service via shell or you just have a shell script, you'll have to add the absolute path to it via <string>/bin/sh</string> followed by the absolute path to your script within <key>ProgramArguments</key>. If you're not using shell, you just have to specify what you're launching using absolute paths.

My personal recommendation is to specify one launch script here and enter eveything what needs to be launched to that script and not to the plist itself.

Last step is to load your custom service to launchd via:
sudo launchctl load -w /Library/LaunchDaemons/dyndns.plist


  1. Since we're here, you can visit these settings in order to remove something unwanted from your startup which might got there without your consent and might actually slow down your system startup ↩ī¸Ž

How to use PPTP VPN on Mac OS Sierra and later

In iOS 10 and Mac OS Sierra Apple removed support for PPTP VPNs from their major OSes and technically had the right for it since PPTP is not secure and outdated. But in case you still have the need to connect to a VPN that works only via PPTP and you're rocking Mac OS Sierra or later you're out of luck. Unless you try using Shimo or Flow VPN which both for me didn't work at all, you're really out of luck 🙂

Thankfully guys at Apple removed only the GUI part of the PPTP client, and you still can use the pppd daemon throught Terminal. But before that you'll have to create a configuration first:
sudo nano /etc/ppp/peers/vpn.example.com

Next, fill it with this info, replacing vpn info with yours:

plugin PPTP.ppp
noauth
# logfile /tmp/ppp.log
remoteaddress "vpn.example.com"
user "username"
password "password"
redialcount 1
redialtimer 5
idle 1800
# mru 1368
# mtu 1368
receive-all
novj 0:0
ipcp-accept-local
ipcp-accept-remote
# noauth
refuse-eap
refuse-pap
refuse-chap
refuse-chap-md5
refuse-mschap
hide-password
mppe-stateless
mppe-128
# require-mppe-128
looplocal
nodetach
# ms-dns 8.8.8.8
usepeerdns
# ipparam gwvpn
defaultroute
debug

Save the file and then start your connection via:
sudo pppd call vpn.example.com

To stop the deamon, close the Terminal with the PPTP session, open a new one and enter:
sudo killall pppd