portrait picture

TIMO ZIMMERMANN

balancing software engineering & infosec

Unit testing command line applications in Swift

posted on Wednesday 13th of February 2019 in

A joke I hear since the release of Swift 2 is “Swift is production ready, except when it is not” and it feels like I ran into one of the parts where this might be true. I decided to write a small command line application last weekend and since I wanted to see how it feels like working with Swift outside of iOS I took the opportunity and fired up Xcode. Oh, if I would have only know what a wild ride and confusing internet search session I had ahead of me.

The most important reason for me to keep up with Swift outside of the iOS platform is the hope to use it for server side development one day. While it feels like Swift is getting more complex with each release and might suffer from feature creep one day, I still like using it and it feels like an elegant and powerful tool in the toolbox, most of the time.

Starting the application is pretty straight forward. Open Xcode, select command line applications and press “Run”. Easy enough. The first thing that might catch your eye is the fact that no test target was created. But this requires only a few clicks, so that is quick to fix, even if it is a bit inconvenient. As usual when setting up tests I imported the project and asserted a random structs static value. Just a sanity check to make sure everything is wired up properly.

Undefined symbols for architecture x86_64:
  "Token.eof.unsafeMutableAddressor : Swift.String", referenced from:
      implicit closure #1 : @autoclosure () throws -> Swift.Bool in XRI.XRITests.random() -> () in TokenTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

So, um,… okay? I have to admit I have not seen this one before. Or I can at least not remember it. There are various solutions you get when searching for this error thrown by the linker, but most of them are not as helpful as you would hope.

I spare you the journey of discovering what the actual error is, to make it short: You cannot test a Swift target compiling to an executable. Technically getting rid of main.swift does the trick, but this might be a bit inconvenient for programs that are, well, build to be executed.

The workaround I am currently using is creating an ordinary library and adding two targets, one for testing and one for running the code. You can take the easy way out and simply add all source files to your target to run the code or you create a proper library like someone who actually cares about abstraction and design.

I clearly have some catching up to do with macOS development, I think the last time I worked on a serious project on this platform was around the transition to OSX. I really hope my solution is not the correct one, even if you find it in various places when searching the web, but simply me not being up to date on how to properly start a project like this. Otherwise I would really have to question the Swift advocates who praise Swift for server side or tooling development, because this is clearly not the way to go.



Screen recoding on iOS

posted on Sunday 10th of February 2019 in ,

When I wrote about Apple revoking enterprise certificates I complained that they missed a unique chance to make a strong statement for their users privacy. Now, a few days later, they actually did exactly this when telling companies to either disclose or remove screen recording from their applications. Except citing App Store review guidelines they point out the importance of protecting users privacy and commit to taking immediate action if necessary. This is exactly the kind of strong statement I asked for.

Looking at the timing I have to assume that some engineers will have a pretty bad weekend thanks to this. They have 24 hours to comply or the app will be removed from the App Store. While I already hear people chanting “they knew what they shipped, they deserve this!” – please keep in mind that not everyone is in the favourable position to freely change jobs with the same frequency as their underwear. There is even a good chance some of the people who now have to fix this did not even know of its existence or consequences. While this should not be understood as a general excuse of developing or shipping products that invade a users privacy – or other questionable things – it should serve as a reminder that there are a lot of grey areas in this discussion we should not plainly ignore.

Having worked on internal and public applications, B2B and B2C, even featured in the App Store I can tell for sure that the amount of times I wished I had a screen capture of everything the user is doing to either improve the app or fix a certain bug is exactly zero. We obviously always had proper bug and exception tracking and custom information attached to crash logs. But they never left our control and private information were scrambled. I can think of two instances where unscrambled user input would have saved us an hour QA time, but this would not have been worth the price every user would have had to pay. And I am talking about “submitted” input, not things that happened and were undone / changed before the user pressed a button. There are a lot of reasons various departments in a company might want screen recordings of user interactions, but not a single one of them will be “to improve the user experience”.

And based on Glassboxs marketing website, companies seem to understand that it might turn out unfavourable being associated with screen recording. Comparing the “who we work with” on archive.org with the one currently live a lot of customer logos disappeared. Guess why.


The Apple Watch that finally won my heart

posted on Saturday 9th of February 2019 in

It was nearly three years ago that I blogged about the Apple Watch. Back then I basically had to get one to start an exploration of how we could leverage the Apple Watch for our app at FlightCar. I was nearly sure I would not like it very much, but I tried giving it a fair chance. Results were pretty mixed. I primarily used it as a fitness tracker when working out. But product development continued and the watch became more appealing to me.

I still do not consider it a watch, at the end of the day it is either an extension to my phone or a stand alone mini version of it, depending on the current usecase. I am not a fan of the “always available” mentality, so when going out with friends for dinner I usually leave my phone in DND and in my jacket and wear a real watch. I obviously have some people on my VIP list that can call through the DND setting, emergencies exist. But responding to an emergency does not happen very often and I rather have a nice conversation while happily munching Sushi than checking Slack to see if anyone pushed a new commit at 2am PST. My favourite watch right now for a casual evening is a Bruno Söhnle Glashütte.

Bruno Söhnle Glasshütte watch

The Apple Watch 3 with the LTE option paired with the AirPods changed the game. I could walk the dog, be reachable and listen to music, without carrying my phone with me. And not carrying a 1200€ phone with me while playing with my 62kg dog actually puts my mind to ease a bit, collateral damage is far less severe. I nearly never carry my phone with me when working out at the gym, except for when I am on call. With the Apple Watch LTE with me I was actually able to get an emergency call for an incident while I was not on call, but was able to help resolving it an hour earlier than I would have otherwise. Again, this does not happen very often, but when it does I am glad to be available and have a chance to engage as needed.

After getting the Apple Watch 3 with LTE I started wearing the watch more often, but still only during certain activities were I did not want to bring my phone. It just did not feel great wearing it all day. And since I do not really bother with counting calories it does not make a difference to me to not know how many I potentially burned.

The same way the Apple Watch 3 changed the game, the next iteration changed it again. When watching the keynote for the Apple Watch 4 I was not really impressed.

“Oh nice, it is a bit smaller. And a bit larger. Biiiiiiig deal.”

Since I had the chance to pass on my Apple Watch 3 and get my hands on the potentially useful new sensors I was interested, but did not really expect any significant change. Ohh, was I wrong. The new form factor actually makes it way more pleasant to wear the watch. I did not expect a few millimetres here and there to make a big difference, but it actually does for me. The slightly larger “edge to edge” display looks great and gives a more well-rounded look to the device and the overall responsiveness helps a lot to make the watch feel better when using it, the dimensions are clearly the defining factor for me. Weight actually went up a tiny bit, but I really cannot claim I have noticed the difference.

Another very important change was the availability of Apple Pay in Germany. Yes, we actually did it, even a year earlier than I predicted. What an amazing feat for a digital development country. Not only being available for the people I want to be available for, but also being able to leave my wallet at home is another improvement of my day to day life. By now I actually wear my Apple Watch nearly the whole day, except when going out – then I still have a phone in my jacket and a real watch at my wrist. Nothing beats the feeling of looking at a fine piece of mechanical craftsmanship.

Something I also learned when starting to wear v3 for a longer time (and really noticed with v4) is the difference in wristbands. You often hear people claiming a cheap third party wristband is as good as an expensive one from Apple. To make it short: no, it is not. I would try to compare a Nike sports band vs a 10€ no name one – but this would not only be unfair, but also completely pointless since there is no comparison. With one you already start sweating putting it on while the other keeps your wrist in a decent state during a whole workout. And the same goes for the nylon bands. Being cheap on your wristband is basically the same as being cheap on the case for your 1200€ phone. Sure, it kind of works, but it still sucks if your sense of touch if not completely distorted.

Apple Watch and sport wristband

Being actually happy with the Apple Watch made me reevaluate my opinion on what device I would actually like to see from Apple, but I came to the same conclusion – an Apple Wristband. Slightly longer, not square, integrated in a nice fabric for the actual band which I can wear on my other arm so the very useful device does not compete with my watch. I enjoy using the Apple Watch on a daily basis, but it will not get a permanent spot on my arm. A wristband on the other hand would.

(As a general note: I will also not start wearing two watches, even if one of them is a mini computer – for the same reason you will never see me carrying two phones. I am so not important enough for that.)


On Apple revoking certificates – I would have hoped for more

posted on Tuesday 5th of February 2019 in ,

Apple was on a roll last week. They first revoked Facebooks enterprise developer certificate used to provision applications outside of the AppStore within a company and a day later Googles. This obviously caused some discussions around the applications mentioned in the article, the walled garden Apple built and our all time favourite – who owns the devices we are using.

Both, Facebook and Google, basically shipped an app we would regularly call spyware. Those applications would have never made it – or only would have by mistake – through the AppStore review process. Especially considering Apples stance on privacy and Zuckerbergs displeasure with it.

Who controls the device you pay for and you own? This is a discussion as old as the AppStore, but what happened here is Facebook paying 13 year olds $20 for get an insight into their lives Facebook and no other company should ever have. End of discussion. Thanks to Apples control over the ecosystem they were able to shut this down. While we can make very good points for freedom of choice vs a walled garden, having someone being able to shut an application like this down was a very good thing. This time.

Based on the reports I have seen the reason for the revocation was a violation of the enterprise developer agreement. We might be able to speculate if this truly was the driving factor or if other factors lead to the decision as well, but we have to stick to the official statements and reasoning we have seen.

I would have hoped for more. Especially considering Apple is strongly advertising privacy on their platforms and using it as one of the reasons why they want to retain such tight control over iOS and the applications you can install. This was a unique chance to make a very strong statement.

They have chosen the easy way out claiming a breach of ToS and decided to not take a strong, public stance against Facebooks and Googles “business practices”. From a legal perspective this might make a lot of sense. It is likely the easiest, provable violation of the enterprise developer agreement and with my limited understanding of (international) law I assume it would be hard to impossible to define privacy violations in a legally binding document, especially when you factor in potential “consent”.

A company like Apple that focuses so much on privacy could have made a very strong statement. “Not on our platform – our users privacy is a top priority!” Facebook reached peak impudence paying 13 year olds to give them full access to their lives. We cannot tip toe around this anymore and revoke a certificate based on a ToS violation. We need a loud and clear voice telling companies like Facebook “no, you will not get away with something like this”. And Apple is in a unique position to be one of this voices, one of the loudest possible. But they decided to play it safe, which is very disappointing.


Migrating (back) to WordPress

posted on Wednesday 30th of January 2019 in

I am blogging for some time now, I think I started somewhen in the late 90s. Back then I used a self written Perl script which appended content to itself when you published a new post. At some point I migrated to S9y. It just came out, so it had to be somewhen around 2002. Two or three years later I moved on to WordPress which, back then, was the new hotness. But as we all know WordPress was not the pinnacle of software engineering or security. I briefly thought about writing a CMS in Django – as I did a few times in a professional setting – but decided to go fully static. And as everyone with some free time I wrote my own static site generator in 2011. I also took the opportunity for a fresh start. Before that I was blogging primarily in German, but being in software engineering it made sense to switch to English. I still got my old posts in a backup, some day I should put them on a subdomain. While there might not be a lot of value in them, I like looking back to see where it started – and sometimes to question how I could have ever thought $x is a good idea.

I already talked a bit about static site generator burnout. Early December I looked at a bunch of drafts in my blog directory, some actually nearly finished, and I had a feeling of not wanting to publish them for the already outlined reasons. So I set out to find a new home for my blog. And also do some necessary housekeeping.

Evaluating software which will power your blog is a bit like shopping for a new car. Every single checkbox looks appealing. Every. Single. One. It should be fast. And support off road trips, just in case. Maybe I will have to tow a trailer. I do not smoke, but the smoke package makes sense, I could use the cigarette lighter to power devices I do not own and do not charge in my car. The list goes on. You can nearly always justify why a certain feature might make sense at some point. Practically you will likely never use it. So my checklist became pretty small.

This does not sound too crazy to me. Especially with two out of five points being “nice to have”. The problem is that nearly every second blog engine in existence checks those boxes. Thinking a bit about my requirements I added an additional one. I wanted something with a hosted offering.

I have to mess with infrastructure on a regular basis and make sure things stay online. I have been doing this for nearly two decades now. But what I really wanted for my blog was something where I log in, write, hit publish and that is it. Some people argue about the cost of hosted services. Those people either do not factor in time, see time as something disposable or simply enjoy hosting things in their free time. All of those are legitimate approaches to hosting, but none of this is true for me.

With the requirements set, it came down to Ghost vs WordPress. Ghost is an interesting one. A lot of money went into the Kickstarter. They still break macOS / iOS spelling correction and the mobile experience is horrible. WordPress is, well, WordPress. It actually got better, especially if you drop all plugins but one for caching and add a CDN in front. What I did not expect back then was how stupid the new editor will be in version 5, but thankfully the old one is still around.

Housekeeping was pretty straight forward: consolidate all my online presences on timo-zimmermann.de, redirect all existing domains and make sure redirects for old content are setup. I think most time went into tagging old content. Thanks to the best hosting provider ever all of this but tagging was taken care of for me. There was a bit back and forth which domain to use, my wife took care of the design based on my absurd requirements and some surprises with WordPress’ URL handling. “/2019/01” and “/2019/1/” are the same. I disagree, but it works and drastically reduces the amount of redirects needed. Good ol’ WordPress, never ashamed of doing stupid.

While not all content is online, I have a working blog and all domains are being taken care of. It is actually quite enjoyable to be honest. With all excuses gone for not blogging on a regular basis I am looking forward to see how much I will be publishing in 2019.