knuspermagier.de
Er bloggt noch? Krass!

Dinge, die mich aktuell an Swift und SwiftUI nerven (und teilweise Lösungen)

Gerade baue ich mal wieder ein bisschen an der Tagebuch-App, da ich sie, seitdem sie eine Swift-App ist, tatsächlich gerne benutze. Ich versuche also das ein oder andere, was die Webapp schon kann nachzurüsten und komme auch langsam voran, aber manche Dinge nerven mich aktuell schon ein bisschen:

Xcode gibt mir kein wohliges Gefühl mehr

Damals, als ich noch beruflich Objective C schrieb und mich sehr viel in Xcode aufgehalten habe, fand ich, dass es der beste Editor ist. Mittlerweile hat sich einiges getan und ich lebe quasi in PhpStorm. Jede Berührung mit Xcode tut seitdem ein bisschen weh, da es langsam ist, die Code Completion immer noch blöd ist und es sich teilweise dumm verhält. Außerdem gibt es kein automatisches Code-Formatting.

Ja, es gibt mit Ctrl + I das automatische re-indent, aber gefühlt geht das nicht so weit, wie das Formatting in PhpStorm und man muss vorher den Code markieren

Folgendes kann man tun um dem etwas entgegen zu wirken:

  • Im Theme die Font zu Jetbrains Mono wechseln, dann sieht es immerhin etwas bekannter aus.
  • SwiftFormat installieren. Damit erhält man ein tolles Tool, das einem die Dateien vernünftig formatiert, einrückt und sogar ein paar Fehler automatisch fixt. Ich hab mir Format File auf den gleichen Shortcut gelegt wie in PhpStorm.

Das “Live-Preview” ist nett gemeint, aber ziemlich unbrauchbar

Wenn man SwiftUI-Views baut, hat man rechts so ein Fenster, das einem Live alles anzeigt, damit man direkt sieht, was man da gebaut hat. An sich toll, auf der anderen Seite stürzt es bei mir öfter ab und braucht um die dreißig Sekunden, bis es wieder läuft. Oder, es pausiert wegen eines Syntaxfehler und wenn ich es ent-pausiere läd es wieder für dreißig Sekunden. Ich habe ein sehr teures Macbook mit einem sehr schnellen M1-Prozessor, das könnte alles schneller gehen.

screenshot-2024-02-26-at-14.30.09.png
Typische Ansicht des Preview-Fensters

SwiftData ist cool aber auch etwas beschränkend

Ich habe wirklich keine Lust jetzt etwas anderes zu lernen als SwiftData, aber dieser ganze Quatsch mit den #Predicate-Dingern, die irgendwie vom Compiler übersetzt werden sorgt dafür, dass ein paar Sachen noch nicht vernünftig gehen, weil in der Closure vom Predicate nur wenige Anweisungen erlaubt sind. Hier und da wünschte ich mir, ich könnte einfach SQL-Queries (bzw WHERE-Conditions) schnell selber tippen, statt sie in das Predicate-Konzept zu quetschen.

Für den “Alle Beiträge am gleichen Tag, aber in verschiedenen Jahren”-View muss ich z.B. schauen, ob der Monat und der Tag vom Erstellungsdatum der Einträge dem heutigen entsprechen. Man könnte also hoffen, dass man sowas gehen würde:

#Predicate<Item> { item in
    Calendar.current.dateComponents([.month, .day], from: item.timestamp) == dateComponentsNachDenenIchSuche
}

Geht aber nicht, da ich die Funktion in dem Predicate nicht aufrufen kann. Ich hab leider nach zehn Minuten googeln keine Lösung gefunden und speichere nun beim Erstellen der Einträge halt noch das Datum als MM-dd extra ab um danach zu selektieren.

Im Vergleich dazu, kann ich im Backend ja einfach folgendes machen:

$query->whereRaw('strftime("%m-%d", date) = ?', $filter['day-of-year']);

Ja, ich weiß, wahrscheinlich liegt es auch einfach daran, dass das hart unperformant ist, wenn man eine Million Tagebucheinträge hat. Jedes mal irgendeine Funktion aufrufen sorgt natürlich dafür, dass die Query einen Full Table Scan machen muss und nicht auf einen Index zurückgreifen kann, von daher ist es wahrscheinlich gar nicht dumm, hier vorzeitig zu optimieren

Versions-Wirrwarr

Es ist weiterhin so, dass sich zwischen den Swift-Versionen so viel getan hat und die Stack Overflow-Antworten teilweise uralt sind. Die Guten wurden irgendwann geupdated und sehen dann so aus:


UPDATE 3: Swift 6
[…]

UPDATE 2: Swift 3 - 5
[…]

UPDATE: Swift 2
[…]

Swift 1:
[…]


Viele aber auch nicht. ChatGPT ist ja leider auch schon etwas älter und liefert daher oft Code aus, der in aktuellem Swift einfach nicht mehr funktioniert. Leider konnte ich die ChatGPT-Dinger, die extra auf die aktuelle Doku trainiert wurden noch nicht testen, das sind glaub ich so custom GPTs, die man nur in der Bezahlversion bekommt? Hat das mal jemand getestet?

Xcode hat kein Copilot

Damit verbunden: Xcode hat kein Github Copilot-Ding. Seeehr nervig. Wobei ich auch nicht weiß, wie gut der Copilot wäre, vielleicht würde er an dem gleichen Problem scheitern, wie ChatGPT?

(Es gibt zwar so ein Projekt auf Github, das ist mir aber nicht ganz geheuer)

Der async/await-Support ist lückenhaft

Weiter kleine Nervigkeit: Noch nicht alle Apple Frameworks haben support für async/await, was ziemlich nervig ist, wenn man z.B. kurz mal ein paar Reminder mit EventKit rauspulen will. Schön wieder completionBlocks, nee, nee!

Fazit

Man muss schon sagen, dass das aktuell mein erfolgreichstes Abtauchen in die SwiftUI-Welt ist. Die App funktioniert gut, ich nutze sie täglich und ich bekomme es halbwegs schnell hin neue Features einzubauen.

Der größte Spaß kommt allerdings eher beim benutzen der App und weniger beim Entwickeln, weil ich ständig anecke, irgendwo warten muss, oder mich durch verwirrende Stack Overflow-Posts wurschteln muss. Letzteres wird natürlich irgendwann wegfallen, wenn ich genug Erfahrung habe und einfach alles weiß, aber bis dahin ist sicher auch schon Swift 8 und 9 raus und alles geht von vorne los!

Ich bin bei Sideprojects ein großer Quick’n’Dirty-Verfechter. Ich habe keine Lust hier Stunden zu verbringen um eine App, die nur ich benutze, perfekt zu optimieren und fehlerfrei zu bauen. Mit den ganzen Web-Technologien funktioniert das supergut, mit Laravel baue ich in wenigen Stunden alles, was ich brauchen könnte als Prototyp zusammen. In Swift bin ich was das angeht leider (noch) sehr langsam, was mich tierisch nervt. Aber das ist eher ein persönliches Problem.

Immerhin fühlt sich das Ergebnis, eine native App, am Ende so gut an, dass es mich genug motiviert, weiter zu bauen und weiter SwiftUI zu lernen, dass meine fehlende Erfahrung zumindest nicht mehr der Roadblock ist.

Kollaps - Das Imperium der Ströme 1

John Scalzi

Musste mal wieder etwas spannenderes dazwischen schieben. Dieses Buch hat mich sehr unterhalten, fand aber, dass ein bisschen zu viel "ficken" vorkam. Im englischen steht da sicher "fuck", was ich irgendwie angenehmer gefunden hätte, das klingt irgendwie schöner. Naja.

Google Sheets als Datenbasis

Im Wiki gibt es jetzt eine Seite auf der ich unsere Everdell-Spielergebnisse in einer kurzen Statistik präsentiere. Doch woher kommen die Daten dafür? Aufmerksame Leser:innen wissen jetzt schon Bescheid!

Natürlich habe ich keine Lust, die Punktzahlen hier im Kirby in zu pflegen, sowas gehört natürlich in ein Spreadsheet, damit man da wichtige wissenschaftliche Auswertungen fahren kann. Glücklickerweise hat Google Sheets ein tolles “Im Web veröffentlichen”-Feature mit dem man eine Tabelle über einen Link teilen kann, und zwar in verschiedenen Formaten, unter anderem als CSV! Das Beste: Die CSV aktualisiert sich regelmäßig, wenn man etwas am Sheet ändert.

step1.png
Hier klicken…
step2.png
…und fertig!

Der everdell-results-Block vom Wiki schnappt sich also einfach die CSV-Datei, läd sie herunter und zeigt die Daten schick an! Juchu!

(Diesen Trick hat mir mal ein Kollege aus meiner damaligen Firma gezeigt, danke Micha!)

Posts, die ich niemals schrieb (1)

Ich habe eine Ich habe eine viel zu lange Liste von möglichen Ideen für Posts in diesem Blog und manche sind so unspezifisch, dass ich gar keine Ahnung mehr habe, was ich eigentlich schreiben wollte. Teilweise sind die Sachen auch einfach so alt, dass sie gar keine Relevanz mehr haben. Da ich ungern etwas wegwerfe, gibt es hier eine spannende Liste:

  • Mein plötzliches Interesse an Turnschuhen

  • Webpack, Vue.JS und moderne Webentwicklung

  • Warum ich Webentwicklung hasse

  • Die großen fünf Trash-TV-Formate, die ich trotzdem gerne gucke
    (???)

  • Warum ich gerne ein iPad Pro hätte, aber noch keins habe
    (habe mittlerweile eins)

  • Was ich mir von der 6D Mark II erhoffe, und warum es wohl meine letzte DSLR sein wird
    (habe niemals eine 6Dm2 gekauft)

  • Der Youtube-Report 2017

  • 5 Jahre ohne Windows

  • Wie man mit 25 Jahren Autofahren lernt

  • Schwimmen für Anfänger

  • Minimalismus und oder her, Fotobücher müssen sein

  • Manche Dinge können weg

  • Warum mich der neue Fluch der Karibik-Film nicht interessiert obwohl Paul McCartney mitspielt
    (habe ich den mittlerweile überhaupt gesehen?)

  • Die großen drei Batterien, die man immer im Haus haben sollte

  • Warum Redmine scheiße ist, aber doch ganz ok

  • Meine neue Jacke
    (Sie ging nach einem Jahr kaputt)

  • Warum es so schwer ist schöne Schuhe zu finden und was man dagegen machen kann

  • Warum hier solang nichts passiert ist - Bloggen im Jahr 2017 und First World Problems

  • Soundbar vs 5.1

  • 10 Jahre Instagram

Wenn euch einer der Titel interessant vorkommt und ihr unbedingt einen Artikel dazu lesen wollt, sagt Bescheid.

MessageSifter

Letztens beschwerte ich mich ja, dass ich es nicht mehr schaffe, leicht per sqlite3-Befehl meine Nachrichten aus der iMessage-Datenbank zu exportieren. Irgendwann in den letzten Jahren hat Apple anscheinend angefangen, die Nachrichten lieber als NSAttributedString zu speichern, statt im Klartext.

Da ich trotzdem gerne weiterhin diverse Informationen, wie zum Beispiel gesendete Links oder Everdell-Ergebnisse exportieren wollte, musste ich mir also schnell eine Applikation bauen, mit der ich die Datenbank öffnen und die NSAttributedStrings dekodieren kann. Zum Glück konnte mir ChatGPT und das Internet helfen ein paar Zeilen Code zu schreiben, die ich mal bei Github hochgeladen habe, falls jemand ein ähnliches Problem hat.

Einmal kompilieren und dann kann man es wie folgt ausführen:

./MessageSifter "pfad-zur-chat.db" [Anzahl der Nachrichten]

Es werden dann alle Nachrichten, nach Datum abwärts sortiert ausgegeben und können mit grep oder so weiter durchsucht werden.

sifter.png
Ziemlich sinnloses Bild, wenn am alles zensiert!

Wahrscheinlich sollte man den Code aber anpassen, denn aktuell hängt da noch ein WHERE handle_id = 1 mit drin, das dafür sorgt, dass nur die Nachrichten zu einer bestimmten Person ausgegeben werden. Entweder löscht man das noch raus, oder man sucht in der Datenbank mal nach der passenden ID.

Für den unwahrscheinlichen Fall, dass das irgendwer braucht: Viel Spaß!

Homescreen, Februar 2024

homescreen.jpg

Mein Homescreen im Februar!

Neu dabei ist Home Assistant, dass ich tatsächlich gerne benutze, seitdem ich gelernt habe, wie man ein schönes Dashboard baut. Ansonsten habe ich mir Reminders noch hin gepackt, bin damit aber noch nicht so richtig zufrieden, denn mit dem Widget und Remind Faster habe ich damit quasi dreimal die gleiche App auf dem Homescreen. Naja.

Neu ist bejou24, was jetzt endlich nativ ist aber noch ein appigeres Icon braucht und Tabspace, woran ich natürlich seit dem Blogpost nichts gemacht habe, aber es funktioniert auch einfach ausreichend und das Icon ist einfach so schön.

Das Dock ist quasi seit Jahren unverändert, auch mit dem Kindle-Icon rechts, das ich seit Monaten nicht angetappt habe. Immerhin erinnert es mich daran, dass ich lieber mal ein Buch lesen sollte, statt meine Zeit mit anderen Dingen zu verschwenden. Leider recht erfolglos.

Mein Todo- und Notizsystem 2024

In den letzten Jahren benutzte ich viele Apps um alles was mit Todos und Notizen irgendwie zu tun hat zu sortieren. Eine meiner Lieblingsapps war Things. Es war und ist eine wunderschöne App!

Ich legte dort alles mögliche an, diverse wiederholende Sachen, den ganzen Hausputz als wiederkehrende Projekte und vor allem alles mögliche, was mir einfiel, was ich irgendwann mal machen wollte, als abhakbare Todo. Nach einer Zeit merkte ich, auch mit Hilfe diverser Artikel und Freunde, dass das ein Fehler war. Der wichtigste Satz ist für mich seit dem: Nicht alles braucht eine Checkbox.

Im Folgenden möchte ich mal die vier Grundpfeiler meiner aktuellen Selbstorganisation vorstellen.

Weiterlesen →

Die Serie startet sehr... langsam und mit vielen Charakteren, die ich nicht mag. Das CGI ist teilweise underirdisch, dafür, dass es eine Apple Serie sein soll. Trotzdem hatte ich öfters Gänsehaut und es gibt schon einen Spannungsbogen, der mich bei der Stange hält. Abgesehen davon sagen alle, dass es später noch mega gut wird!

Tolle Home Assistant Dashboards in drei einfachen Schritten

Seitdem ich mir vor ein paar Jahren Home Assistant installierte, schob ich eine Sache erfolgreich vor mir her: ein schönes Dashboard zu bauen.

An und für sich war ich mit der Software schon sehr zufrieden. Alle Geräte, die ich einbinden wollte funktionierten tadellos und ich machte auch schon einigen Kram damit, zum Beispiel meine Kiosk-App, mit der ich schnell Kram auf den Sonos-Boxen abspielen kann.

Ein Dashboard zu bauen erschien mir aber immer sehr mühsam. Am Ende sah auch alles unaufgeräumt und durcheinander aus und was würde ich überhaupt anzeigen wollen? Welche Information hilft mir wirklich weiter? Muss ich wirklich am Ende YAML-Dateien editieren, weil der UI-Editor manche Sache nicht unterstützt?

Nun passierte es aber, dass mir der Youtube-Algorithmus dieses Video von simon42 in den Stream spülte. Simon, der den besten Home Assistant Kanal Deutschlands betreibt, stellt dort sein Dashboard vor und erklärt wie er es gebaut hat, im Grunde nur mit der Tile-Card und horizontalen und vertikalen Stacks. So easy!

Die Tile-Card ist ein relativ neues Element. Früher musste man dafür die Mushroom Cards als Erweiterung installieren, mittlerweile ersetzt die Tile-Card aber viele der Sachen. Ist auch vom gleichen Entwickler. Tolle Sache!

Statt weiter rumzuheulen, dass ich kein vernünftiges Dashboard hinbekomme, setzte ich mich also mal kurz hin und baute nach, was Simon erkläre und es klappte! Mit ein bisschen Übung versteht man auch schnell den visuellen Editor und wie das alles mit den Kopieren und Einfügen-Aktionen schnell funktioniert.

Nachdem das Dashboard erstmal fertig war, wünschte ich mir noch ein bisschen mehr Abstand zwischen den Spalten und da bekam ich, wie immer, einen tollen Tipp von Markus: Die layout-card-Extension. Damit kann man verschiedene alternative Layouts für das Dashboard auswählen, unter anderem eines, bei dem man einfach mit CSS Grid Funktionen arbeiten kann. Wunderbar. In dem Zuge installierte ich auch endlich das Community Repository HACS, das ich bisher irgendwie verschmäht hatte, weil es mir nicht ganz geheuer war. Ist aber Quatsch, funktioniert super und ist toll!

Mit layout-card installiert, konnte ich also folgendes in mein Dashboard-YAML schreiben:

   type: custom:grid-layout
   layout:
      grid-template-columns: auto auto auto
      grid-gap: 30px
      grid-template-rows: auto
      mediaquery:
        '(max-width: 600px)':
          grid-template-columns: 100%

Damit habe ich drei Spalten mit 30px gap dazwischen und mobil in der App ist alles in einer Spalte. Wuuuuunderbar.

dashboard1.png
Haupt-Dashboard

Wer das Video von Simon gesehen hat, wird bemerkt haben, dass er noch tausend kleine Unteransichten für die unterschiedlichen Räume angelegt hat, die sich öffnen, sobald man auf eine der Tiles drückt. Hier habe ich mich noch etwas zurückgehalten, da es in den meisten Räumen nicht mehr zu sehen gibt, als eh schon auf dem Gesamt-Dashboard steht. Einzig für den Energieverbrauch und die Internet-Geschichten habe ich testweise mal was angelegt, aber das ist noch nicht besonders durchdacht und hat eher Test-Charakter. (Hier benutze ich die Mini Graph Card, die ist auch toll!)

dashboard2.png
Internet
dashboard3.png
Strom

Ich bin super zufrieden mit meinem Dashboard und damit, wie einfach es war, es letztendlich zu konfigurieren. Mal wieder eine von den Sachen, wo man nicht zwei Jahre hätte weinen müssen, sondern es einfach mal hätte machen sollen.


Allgemein muss ich sagen, dass Home Assistant für mich eine der besten Open Source-Softwaren ist, die ich je benutzt habe. Die UX ist gut, die Lernkurve ist beherrschbar und, was man bei Open Source selten hat, es sieht halbwegs annehmbar aus. Alles wirkt sehr durchdacht und funktioniert einfach. Ich fand noch keine Sache, die nicht klappte. Toll! Ich habe mal ein Github-Sponsorship abgeschlossen um die Sache etwas zu unterstützen.