My Blog: Coding 💻

I love building all kinds of software using different languages and frameworks. This is where I share my learnings.

A composition showing screenshots of the new streaks feature on both Apple Watch and iPhone.

Streaks Feature, Updated Widgets and Core Data

Tuesday, 18 April, 2023

I just pushed a Zenitizer update to TestFlight earlier today which includes a brand-new feature that I hope to be a great source of motivation for your regular meditation practice: “Meditation Streaks”

Each day you hit your meditation goal, your streak grows. In order to keep your streak, it is sufficient to simply meditate as little as one minute a day - even if this is below your goal. While this will not increase your streak it will prevent breaking the streak. Only if you do not meditate at all on a given day the streak will be reset to 0.

With this behaviour, I was hoping to find a good compromise between motivating you to build a regular practice but without putting too much “pressure” on “achieving goals” (mindfulness meditation should be calming and not adding more stresses to your life, after all 🧘).

I’d love to know what you think about this approach and how the feature works for you personally, so please don’t hesitate to reach out and let me know!

New Streak View + Updated Widgets & Complications

The screenshot above shows the new UI elements for displaying streak progress in various forms and contexts. The “week view” is a custom SwiftUI view that can (and will in a future update) be extended to show larger time spans (e.g. one month at a time). This will allow revisiting the meditation history laid out like a calendar.

Design Considerations

I wanted the StreakView to have a “call for action” title like “Grow your 42 Day Streak” or “Keep Your 42 Day Streak” (unless you already reached your daily meditation goal). The week view primarily serves to see at a glance how you’ve been doing this week (+ may allow revisiting previous days’ meditation history details in the future) and there’s a small indicator of your personal record to date.

After a couple of design iterations I’m pretty happy with the result but I’m sure I’ll make tons of tweaks before Zenitizer makes it to the App Store 🙈 Please let me know if you have any suggestions or questions about the feature as well as the design!

Under The Hood & New Learnings (Core Data)

The majority of the work, however, was focussed on what is not visible: the underlying data and persistence layers! So far, all of Zenitizer’s persistence needs were covered by NSUserDefaults as all the meditation history itself was exclusively written to and read from Apple Health.

Now in order to properly support streaks and efficiently query meditation history and streak data I needed my own on-device persistence solution and after a bit of research I decided to go with Core Data.

You can tell that the framework has its roots in the “Objective-C days” and I personally prefer Swift structs and other value types as well as Swift’s strict handling of Optionals in favour fetching and passing around NSManagedObject references because the former will often force you to address issues at compile time instead of (hard to find?) runtime issues you may get with NSManagedObjects and NSFetchRequests… In the end of the day though, each framework, tool or solution has its pros and cons and, all things considered, CoreData is working really well for me and I am definitely starting to embrace it… 🤓

Donny Wals’ book Practical Core Data was a fantastic resource on my journey to familiarize myself with Core Data. I bought it quite a while ago and it was just sitting in my Gumroad library because I never got around to reading it… Finally, I was forced to work my way through it and it has really helped a lot!

In addition, I would also highly recommend this Apple developer video to anyone getting started with Core Data in modern apps!

A screenshot of my conversation with ChatGPT that taught me how to use evaluateJavaScript to click elements inside a WKWebView

Building a ChatGPT App With the Help of ChatGPT

Thursday, 29 December, 2022

When I started prototyping Chatterbox for ChatGPT, I decided - as an experiment - to utilize ChatGPT in the process. I know, so meta, right? Here are some of my observations, thoughts and takeaways from that experiment.

Getting Started

I wanted to build the native UI with SwiftUI (+AppKit where necessary) and I knew I’d want to embed the actual ChatGPT website in a WKWebView. I asked ChatGPT how to interact with HTML elements from the surrounding Swift code and learned about the evaluateJavaScript method of the WKWebView class. This allowed me to prototype the app and start experimenting with different ideas and features.

ChatGPT as a Mentor 🧑‍🏫

As I was building the prototype, I continued to ask ChatGPT in order to learn about topics, I have not encountered before (while most of my SwiftUI experience was transferable to macOS, I did learn quite a few new things about AppKit in the process). In a way, ChatGPT played a role in the development of Chatterbox - it helped me learn the skills and techniques I needed to bring the app to life. When it worked, it got me there faster than searching Google and/or Stackoverflow, but I will say that, quite often, it gave results that were either slightly wrong or completely wrong and made up.

The first case is not an issue (IMO) because I only consult it for pointers on “how to get started with something” rather than copying and pasting whole blocks of code verbatim, so fixing minor issues on the fly while implementing a solution is easy enough most of the time. The problematic part is when ChatGPT gives a completely false and made up answer but does it in a way that sounds fully confident and professional. On some occasions it hallucinated completely non-existent APIs (which sounded plausible enough). There’s something particularly disappointing about that experience because I always get my hopes up about this “super convenient magical API that would be a perfect fit for my problem” 🥲

ChatGPT as a Rubber Duck 🐤

Are you familiar with the term “rubber duck debugging”? If not, you should read up on it because it is an absolutely brilliant technique! While developing Chatterbox, sometimes I would ask ChatGPT for help when encountering errors or problems. While the responses where often pretty generic and not too helpful, sometimes the mere act of formulating my question and seeing it reflected in ChatGPT’s response was enough for me to realize what the problem is 💡

Will ChatGPT become my go-to rubber duck debugging companion? No, because:

  1. Formulating questions in writing is tedious (I enjoy typing and think I’m pretty fast too, but just “talking to myself” is quicker)
  2. Anika the Radar Plushy (one of my dearest “souvenirs” from my time at Apple) would be really sad to be replaced by an AI chatbot. She’s such a loyal coding companion, never complaining and always listening to me blabbering on about all the random issues I encounter during my work ❤️

“A photo of Anika, an ant-eater plushy sitting on my desk acting as my “debugging rubberduck”

Summary

Ultimately (like many of you, I’m sure), I have come to the conclusion that ChatGPT is quite impressive and can be very useful, but it is just a tool after all - and a flawed one at that. Used as a research, learning and debugging companion (while reflecting critically about its output) it can speed things up and make you more effective. But it can also be distracting and outright confusing by “teaching you” things that don’t actually exist while sounding absolutely confident, often requiring to “manually double check with Google” after all…

It has certainly earned its place in my toolset (and is always at hand with Chatterbox’s global hot key) and I’m curious to see how it develops and how I and others will continue to find creative uses for it and ways to integrate it into our workflows. Feel free to reach out if you’d like to share any cool use cases for ChatGPT that you discovered for yourself.

Why I Moved From Drupal to Jekyll

Friday, 20 March, 2015

📜 Archived

When I started to learn about web development it felt to me as if everyone was suggesting to use a CMS for everything. Back then I have chosen to get started with Drupal after considering also Wordpress, Joomla and a few others and I have to say that it served me well all the time.

Nevertheless I have become tired of the amount of maintenance that a full blown CMS demands.

No matter how well the update mechanism is designed (Drupal’s drush up is super convenient), it is still a somewhat tedious procedure. Things may break. Thus one has to create, maintain and, in the worst case, re-deploy backups.

Another critical aspect is the fact, that security updates often allow for no more than a few hours to pass until vulnerabilities are widely exploited. This may not be a problem for companies capabable of paying staff all around the clock to react quickly in such scenarios, but it surely is a challenge for individuals like me running their own websites.

Keep It Simple

I basically wanted to get rid of two things: The database and all server side code.

Databases Are Cumbersome

Not relying on a database makes various things so much easier. One can quickly migrate to another host by uploading a bunch of files without even bothering to export/import SQL or change database credentials in some configuration file. One of the most outstanding advantages for me is the fact that, without a database, your complete website can be tracked using a version control system.

So Why Do You Want to Get Rid of PHP?

The simple answer is: Because I can. Given the type of content I provide on this website, there simply is no necessity for dynamic, server side code. PHP only imposes superfluous performance and security drawbacks, which I hereby avoid.

The Jekyll Workflow

I personally consider Jekyll’s workflow another major selling point for this system. Other CMSs come with heavy web interfaces for content creation, which often feel sluggish and are anything but a pleasure to interact with. In the worst case you may end up waiting for the post you have been typing for the past 2 hours to be processed just to find that the system decides to give you a timeout instead and discard your data (been there).

Jekyll uses plain text files formatted in Markdown. Therefore you can use your editor of choice to compose your posts. Simply type jekyll serve in the corresponding directory and it processes your files and even hosts a local web server to test your page. Setting up a web development environment has never been so easy.

Conclusion

There are many valid examples for projects that demand CMSs, databases and server side logic. It took me a while to realize that my personal website is not one of them, but now I am very content about the new found simplicity that Jekyll offers.

In the end of the day there is no such thing as the “best CMS”, as it all boils down to the maxim of choosing the right tool for the job.

More Topics