tzeejay icon

About

Archive

Github

The Missing Workhorse Mac

The Missing Workhorse Mac

Processing intensive workflows are higher in demand than ever, but the Mac lineup is missing a crucial piece to help pro customers of Apple.

AVM Fritz WiFi Mesh

AVM Fritz WiFi Mesh

AVM Fritz WiFi Mesh kam unerwartet ist aber ein Segen für den deutschen Markt

Turning iOS Extensibility to 11

Turning iOS Extensibility to 11

iOS is amazing but is lacking productivity basics

Monodraw Licenses Giveaway

It may come as a surprise to some, but I am doing something good just because I can and it will make me happy to see other people happy.

A little while ago the developer of the wonderful iOS Reddit client Apollo Christian Selig and I had a public exchange on Twitter about ASCII art in one of Apple’s new OSS projects. To my surprise this caught the attention of a few people. Christian & I talked about how fun it would be to launch a little giveaway, not to gain followers or sell anybody anything. Do something fun on the internet with strangers after two absolutely awful years just because I can. I ended up doing exactly that and got into contact with the Monodraw developer hoping I could purchase the licenses in bulk but ended up with ten free ones to give away.

How To Enter The Giveaway

I have decided that I will give away the licenses at random to people on Twitter leading up to Christmas. I don’t care if you follow me or not and it’s not a requirement, I just want to hear what you’re up to or what you’d like to use Monodraw for. There are bonus points if you are a student and if it would help you with class work or in a paper that you have to write, but that is also not a requirement. To enter simply mention @tzeejay on Twitter or send me an E-Mail. I prefer Twitter as I want to publicly share what you’re up to but it’s not a requirement.
If I think you’re doing something cool I will send you one of the licenses. No strings attached!

(If you think the app is cool and end up missing out on the giveaway, just treat yourself to a license. It’s only $10 and well worth the money)

Terms (?)

I was generously given the ten licenses, two of which I will give away every Advent, the first one being tomorrow 2021-11-28, and the remaining ones on Christmas (that is the 24th for y’all Americans).

Whatever holidays or festivities you observe during this time of the year, I hope you catch a break and have some free time to have some fun drawing some ASCII art. We all deserve it.

27.11.2021


Boring Tech: No-Touch Foamy Soap Dispenser

You can file this under “2021 hitting hard, man”.

The day has come that I am publishing something on my website not just about soap, but a soap dispenser. To be very honest with you though, this was a purchase initiated by my girlfriend that I am really enjoying.
I am usually the type of person that likes and defends mechanical systems of any kind as way too many things in our lives are either electric now for absolutely no reason, or even worse want to be connected to the internet at all times (to collect & sell data about you). I have now been working from home for many years and very regularly wash my hands, even pre-covid hand-washing hype, and therefore made heavy use of our previous soap dispensers which can be described as “fine”. They were nothing I would write a blog post about but they also did nothing wrong.

This dispenser is something else though. The packaging is not very reassuring at all, as it comes in a plain white cardboard box barely big enough to keep the dispenser inside, but the way this thing operates is very satisfying.

  1. It reacts very quickly
  2. I have never had to wiggle my hand underneath the sensor/nozzle to make it recognize that I am trying to use some soap
  3. The dispenser moves the soap very quickly. I would say that it isn’t slower than taking one to two pumps with a manual soap dispenser.

Getting these basic feature so right totally won me over and we now have two. The battery came pre charged in both and the package includes a little USB-A to USB-C cable to charge it through the rubber sealed USB-C port at the back. Neither had to be recharged since we got them and neither the soap extrusion speed or any other indicator that it might be low(-er) on battery has decreased so far.

I would assume that you can buy suitable watery soap in bulk refill packs but as per their instructions, watering down liquid soap with the viscosity similar to honey works too. They recommend a 2:1 water to soap ration but I’d recommend using more like 3:2. It’s soap, it doesn’t need to be an accurate science.

I am sure that the same dispenser is sold around the world under different nameless brands but here are amazon.de & amazon.com links.

24.11.2021


Making Your Mac App Launch on Login (An iOS Developers Opinion)

I have been a Mac user for quite a while now and while I understand how some underlying technologies work because I had played with them in the past, actually writing your own Mac app gives you an entirely different point of view. Today I had quite the “you have got to be fucking with me” moment.

I have tried to make Guardian Firewall for Mac, which is still in beta, launch on login/boot. The solutions I have found kept getting worse and worse and user interaction in any way seemed to not be required at all. Coming from iOS with it’s very locked down OS and requiring external user input for basically anything at this point because some developers just have to be terrible and abuse every little bit of API platform, I just couldn’t believe the state of the Mac at the moment when the solution to this problem is seemingly so obvious.

There are many ways to add launch items on Mac but the “oldest” way to accomplish this that I know of is by dropping a .plist file into ~/Library/LaunchAgents/ (or /Library/LaunchAgents for all users of the Mac). You define a few keys and values in the file and move on with your life. There are also other ways to do this but this variant is quite easy to explain and very flexible as it is just a plaintext file.

To me, the way to actually solve this problem from an app POV interacting with APIs would be to call a NSApplication method with a completion handler, similarly to how you ask for permissions on iOS or macOS to access location data. This way both sandboxed and non sandboxed apps can easily adopt this new API and the user is presented with a little modal alert containing a short explanation by the developer asking them for confirmation. Behind the scenes macOS creates a .plist file with a reference to the app and the drops it into ~/Library/LaunchAgents/.

This solution would offer a few key advantages:

  1. It guarantees backwards compatibility & existing apps will continue to function
  2. With the correct permissions (or by being root) a script or any sort of automation tool can still accomplish the same task
  3. All Mac developers get access to a supported & predictable API in an already established format
  4. Compatible with sandboxed or non sandboxed apps
  5. Going forward the user will have a clear expectation about the interaction
  6. API adoption can be enforced for sandboxed apps (I would absolutely endorse the app review enforcement in this case)

The current possibilities as for example described here, which include a little helper app that has no UI but is yet another target that needs to be included in the bundle and codesigned properly sound like nobody has had the chance to give all of this enough thought. Especially given the changes Apple has made over time to the Mac sandbox.
Making this change would make the Mac a more secure platform without limiting power users in any way.

18.11.2021


Support E-Mails are Fixed in iOS 15

Back in March I wrote about how an update to iOS 14 had completely turned our very simple support inquiry strategy onto its head and I wrote about my frustrations while trying to adopt the, old at this point, iOS share sheet. It is still completely broken and impossible to pass along any kind of formatted text into certain fields in a predictable way. As far as I was able to follow the breadcrumbs with iOS 15.0.1 or iOS 15.0.2 Apple at least fixed the mailto:// links they had broken in iOS 14.6 to address a 0-day (I am failing to find the links now but here is the Security Update Disclosure).

In order to send details about the state of our app we allow customers to opt into sharing details via simple UISwitch-es. We receive data in a somewhat predictable format as well as a written message with context about the problem and our customers have the ability to verify and edit which details are being shared with us.

Guardian Contact Technical Support UI Guardian Contact Technical Support Formatted E-Mail

Our goal is to make things as convenient as possible for them to share crucial information with us to help them, but not beat them over the head with it by forcing anybody to share something they don’t feel confident in sharing. We prefer having to ask for more details over collecting any data automatically without the users input or explicit acknowledgement. Discipline and restraint will win you long-term trust in this situation and it is always worth it in my opinion.

To give a concrete example, this is what a support inquiry formatted on iOS 14.8 looks like:

<BR><BR>Please describe in detail the issue you are experiencing <BR><BR>###<BR><BR>VPN Hostname<BR>sanjose-ipsec-4<BR><BR>Subscription Type<BR>Quarterly<BR><BR>AppStore Receipt<BR><BR><BR>App Version<BR>2.2.4 (4)<BR><BR>iOS Version<BR>14.7.1<BR><BR>iOS Timezone<BR>America/Los_Angeles<BR><BR>Network Type<BR>WiFi<BR><BR>Cellular Carrier<BR>REDACTED<BR><BR>Subscriber Credential<BR>REDACTED<BR><BR>Issue<BR>App doesn't work (Not Guardian)

I think it is obvious to anybody why receiving such messages would suck. Yes we could setup triggers or webhooks to clean this up and simply replace all instances of <BR> with \n but we shouldn’t have to do that in the first place.

Thanks to iOS 15 being such a solid update and the great adoption rate we are seeing, these E-Mails are less and less common. Instead we are now receiving support inquiry E-Mails looking like this:

###

Please describe in detail the issue you are experiencing 

###

VPN Hostname
frankfurt-ipsec-10

Subscription Type
Pro

AppStore Receipt
No App Receipt Available

App Version
2.2.6 (20211103.5)

iOS Version
15.1

iOS Timezone
Europe/Berlin

Network Type
WiFi

Cellular Carrier
T-Mobile

Subscriber Credential
REDACTED


Exceptions Log
REDACTED


Issue
App doesn't work (Not Guardian)

Critical details like the app version are glanceable again reducing the support overhead significantly. Looking for details in an ocean of <BR> once is easy. Do that all day and you will quickly look for alternatives.

I hope that we are able to inspire more developers to adopt this kind of support ticket system as plain-text will work with any regular E-Mail account as well as more fancy systems like Zendesks and the like.

07.11.2021


Setting Up Automated E-Mail GoAccess Reports via systemd

Despite the, to me, obvious drawbacks of client side website analytics libraries like Google Analytics etc. people insist on including it on their website since they “need the data” or whatever and think that there is no other way to achieve that. I disagree.
GoAccess is a great command line tool to generate web server reports directly in the terminal which lets you quickly interact with the data to answer questions you may have, but it also happens to output a, all included in a single static file, HTML report. The out of the box styling for the static HTML file is great and enables you to quickly glance at a report, or even send it to colleagues to help support their efforts. I really recommend giving it a try and I strongly recommend tearing privacy invading client side libraries out of everything you have control over. While the early 2000s of the internet were a really cool place to be, Google Analytics is one of those relics that should have died a decade ago.
Most web server logs hold tons of interesting information sent by the visitors web browser, which can then be analysed asynchronously by a tool like GoAccess in a privacy respecting way. You will miss out of a few things but nobody is sitting in front of the Google Analytics dashboard frantically optimising their website for every possible viewport height & width pixel by pixel.

I have been using this setup for over a year now but recently ran into some trouble with my cron automation, which this Raspberry Pi executed based on a file in /etc/cron.daily/. If you don’t know, placing files into those directories is a little tricky because various requirements need to be met and sometimes things just stop for inexplicable reasons, oh and there are no logs about anything.
I was finally over it and simply ignored the reports for a while, thinking that it’ll either fix itself again or that I would fix it myself at some point. Recently though I ran into a great blog post about setting up systemd timers to run automations. I have since converted various things in my life into these systemd timers and have not looked back. Some of y’all don’t quite understand the powers of systemd or don’t like it fundamentally, but it is quite compatible with my brain and getting worry free logs which are instantly available, query-able and sort-able via journalctl makes it all even better in my eyes.

The last remaining puzzle piece in this entire chain of events is the transfer of the GoAccess report into my E-Mail inbox. I looked at a few of the common recommendations on the internet but ended up using a great OSS project fittingly called eMail. It does a few fancy things, but it tries to get out of your way and simply be a good *NIX tool. There isn’t too much to say about it and that is a good thing. I can wholeheartedly recommend using it!

Post installation of GoAccess one would usually get started by running something like these commands to generate static HTML reports (drop the -o static-report.html to checkout the analysis in the terminal first)

zcat -f /var/log/nginx/access.* -f /var/log/nginx/error.* | goaccess -o static-report.html

You could even start excluding some paths that you do not care about in the GoAccess report by running it through grep for example

zcat -f /var/log/nginx/access.* -f /var/log/nginx/error.* | grep -Ev '/admin|/wp/login/' | goaccess -o static-report.html

This however will not work with systemd, nor will it work if you throw it all into a shell script which systemd is then executing for some reason. GoAccess will give you scary sounding nonsensical errors and gzip will complain about broken pipes.

Aug 05 09:15:56 raspberrypi systemd[1]: Started GoAccess Report generation script.
Aug 05 09:15:56 raspberrypi bash[22837]: GoAccess - version 1.5.1 - Jul 19 2021 17:11:41
Aug 05 09:15:56 raspberrypi bash[22837]: Config file: /usr/local/etc/goaccess/goaccess.conf
Aug 05 09:15:56 raspberrypi bash[22837]: Fatal error has occurred
Aug 05 09:15:56 raspberrypi bash[22837]: Error occurred at: src/goaccess.c - initializer - 1459
Aug 05 09:15:56 raspberrypi bash[22837]: No input data was provided nor there's data to restore.
Aug 05 09:15:56 raspberrypi bash[22837]: grep: write error: Broken pipe
Aug 05 09:15:56 raspberrypi bash[22837]: gzip: stdout: Broken pipe

I ended up fixing this by creating a working directory for my GoAccess executing script and defining a bunch of files which I create, use while logs are being analysed and finally deleted once the report was sent out.

# mkdir -p /usr/local/goaccess-reports
# touch /usr/local/goaccess-reports/excluded-paths.txt
# touch /usr/local/goaccess-reports/goaccess-report.sh

Once that is set you can populate the files accordingly and start receiving daily reports about the traffic on your web server, straight into your inbox.

/usr/local/goaccess-reports/goaccess-report.sh

#! /bin/bash

OUTPUTFILELOCATION="/usr/local/goaccess-reports/"
OUTPUTFILE="todays-report.html"
TMPLOGFILEFULL="/usr/local/goaccess-reports/tmp-full.txt"
TMPLOGFILECLEANED="/usr/local/goaccess-reports/tmp-cleaned.txt"

echo "Assembling report from Nginx logs"
zcat -f /var/log/nginx/access.* -f /var/log/nginx/error.* > "$TMPLOGFILEFULL" 

echo "Cleaning the log"
grep -v -f /usr/local/goaccess-reports/excluded-paths.txt "$TMPLOGFILEFULL" > "$TMPLOGFILECLEANED"

echo "Analyzing the log"
goaccess -f "$TMPLOGFILECLEANED" --log-format=COMBINED --http-protocol=no --http-method=no --ignore-crawlers -a -o "$OUTPUTFILELOCATION$OUTPUTFILE"

echo "Sending report with eMail"
email -b -s "Website Report For $(date +"%Y-%m-%d")" -attach "$OUTPUTFILELOCATION$OUTPUTFILE" johndoe@example.com

echo "Deleting today-report.html file"
rm "$OUTPUTFILELOCATION/$OUTPUTFILE"

echo "Deleting tmp-full.txt"
rm "$TMPLOGFILEFULL"

echo "Deleting tmp-cleaned.txt"
rm "$TMPLOGFILECLEANED"

echo "Done for today"

#### /etc/systemd/system/goaccess-reports.service ~~~shell [Unit] Description=GoAccess Report generation script

[Service] ExecStart=/bin/bash /usr/local/goaccess-reports/goaccess-report.sh


<br  />
#### /etc/systemd/system/goaccess-reports.timer
~~~shell
[Unit]
Description=Timer for Daily GoAccess report

[Timer]
OnBootSec=300
OnUnitActiveSec=1d

[Install]
WantedBy=multi-user.target

Finally remember to start and enable the systemd timer

# systemctl start goaccess-report.timer 
# systemctl enable goaccess-report.timer 

You can check on the status of your timer and when it’ll be executed again via

# systemctl status goaccess-report.service

07.08.2021


A Developer's POV: App Store: The Schiller Cut

I’ve been deeply involved with the Apple developer community since the 1990s. There has always been conflict between developers and Apple. Over the balance of fixing bugs versus adding features to the platforms, over the quality of documentation, over the tools, over everything. But the relationship has clearly turned for the worse during the App Store era, and the reason, I think, is money.

This excellent paragraph misses one key thing in my opinion that nobody seems to be able to put into words and I am still struggling a little bit.

John Gruber’s excellent piece of the current sentiment in the developer community towards Apple and him circling around Phil Schiller’s E-Mail of what could have been, sent many years ago regarding App Store policies, are all spot on. I recommend reading the entire piece first if you haven’t yet before continuing to read my (poor) attempt at articulating my thoughts on the topic.
The quoted paragraph above is what lead me to write this blog post, and while I have disagreed with many of John’s opinions over the last two-ish years specifically, I believe that disagreeing is a good thing.



> ..., and the reason, I think, is money.

As much as this conflict is about money, it isn’t about money at all. It also isn’t about any of the stated friction points in particular. For example Xcode is the best and the worst development environment that I have used so far. It does so many delicate and complicated tasks in a very effortless feeling Apple-y fashion, but as much as it sometimes feels like magic it also fails in a very Apple-y fashion, and you know exactly what I mean by that.
I still get signing credentials for Guardian and my other apps manually because I was burnt so badly by the automatic tooling in the past that I am not yet willing to trust it again.

The biggest problem I personally have is the general indifference towards developers. The position that we better be grateful for the opportunities they have blessed us with or else…, is simply disappointing. To further break the problem down, there is only one correct answer in my opinion to the question “who needs who?” in this relationship and it’s “both need each other”, but Apple refuses to acknowledge that. Apple wouldn’t even sell half as many of their devices without software from third party developers that elevate the devices to become an essential turning point in people’s lives. The builtin software from Apple lays the foundation and sets the tone but the third party apps are what make the platform which sells the hardware. Remember the “There Is An App For That” marketing campaign? They sure as hell weren’t referring to their own apps, or are our apps really their apps? The refusal to acknowledge this symbiosis is why it then boils down to being about the money. If they took 2% + whatever the credit card processing fees cost them I bet many would be willing to accept the current terms and call it the “I hope you choke on it” tax.

I’ve often said that Apple’s priorities are consistent: Apple’s own needs first, users’ second, developers’ third.

This is correct but overly simplified, which was the correct tradeoff by John to not get lost in a tangent in his post. Developers aren’t third and users aren’t second.
Apple is first, Apple is second, Apple is third, Apple is fourth and Apple is fifth. Users might be sixth depending on which day of the week it is and developers aren’t even in the top 20.
It has a lot of Chappelle’s Show energy.

Cook said that lawsuits were in the back of his head, but what triggered the program was worry over small businesses during Covid.

I believe the problem that many run into recently, as do I, is that the words spoken by Apple’s leadership in interviews or keynotes in the past could generally be trusted and taken at face value. I do believe that they actually care about the user’s privacy, and try their best as they run into political limitations around the world. The blatant lies in broad daylight though, both under oath in court as well as in a few recent interviews touching on these and similar topics is reputational damage that will last a generation.

Just as a brief reminder, in the beginning of 2020 as everybody was running around losing their minds while trying to adjust to huge shifts of how they were going to live their lives, Apple decided that it was a good time to force as many apps as possible into adopting the in-app purchase system, which would ensure that they get their 30% cut from many things being forced to shift to online transactions pratically over night. Many people were unsure if and how they would be able to feed their families and while they tried to improvise as much as possible, as we all did, Apple either held app updates hostage over in-app purchase adoptions or threatened with removal from the App Store. Every other day a new story was shared by a new developer, big and small. I am convinced that Apple’s leadership team was well aware of what was going on at the time and had every chance to stop it, but they chose not to.

Here is the full quote, quoting the exchange:

Rogers also expressed doubt that Apple’s Small Business Program, which cut App Store fees in half for small developers, was made out of concern for small businesses during the Covid pandemic, as Cook testified on Friday. “That seemed to be the result of the pressure accrued because of investigations, of lawsuits,” Rogers said.

Cook said that lawsuits were in the back of his head, but what triggered the program was worry over small businesses during Covid.

Rogers remarked that she had seen a survey that 39% of Apple developers are dissatisfied with the App Store. “It doesn’t seem to me that you feel any pressure or competition to actually change the manner in which you act to address the concerns of developers,” Rogers said.

Cook disagreed and said that Apple “turns the place upside down for developers.”

Even their attempt to provide them with the smallest bit of saving grace due to legal pressure completely failed thanks to it being so complicated for no obvious reason that apparently even Apple struggles to work with it based on this thread started yesterday by Russell Ivanovic.
Whether or not it is complicated due to them being greedy or due to another reason, it is not a good look and has not helped them in any way in my opinion. Not with developers and not to alleviate legal pressures. It failed so transparently that they were directly called out about it during the court hearing, not by the opposing legal team, but rather by the judge.

Image of Russell’s original tweet expressing frustrations about Apple’s Small Business Program

From the replies in the thread it appears as if many run into this problem, as they have no idea whether or not they are actually enrolled (some simply never get enrolled it seems). Many small developers which already don’t have the time to deal with this sort of nonsense, now have to spend their time trying to read the tea leaves to understand whether or not the first, second, third or fourth time they applied to enroll actually got them into the program.

Image of a reply to Russell’s tweet expressing frustations about Apple’s Small Business Program

How many more devices could Apple sell if they were to allow developers to provide the best possible experience to their customers on their platforms. By simply making it nice in every way and have not just their, but also the software written by third party developers solve all of your problems effortlessly and get out of your way. Remember back in the iOS 5 days when developers and designers on Dribbble were trying to trump each others login screens with the coolest looking, best working login screen possible on iOS? I want that but for every problem on the platform from payments to logins to modal alerts to interface idioms. Image what would be possible with some constraints lifted like Phil Schiller tried to express in his E-Mail while guaranteeing all the security upsides that currently exist for users.

10.06.2021

Archive