Bei einem Kaltakquise-Anruf gibt es diesen Moment: Der Hörer ist abgenommen, der andere spricht, du nickst. Aber innen herrscht Stille. Kein Wort verstanden.

Besonders, wenn am anderen Ende ein Brite mit einem speziellen Akzent sitzt oder ein Inder, der sehr schnell und sehr selbstbewusst spricht. Beides war meine Realität in den ersten Wochen als Makler in Dubai.

Ich bin Designer. Ich kann komplexe Systeme entwerfen. Ich verstehe Produkte. Aber ein Telefongespräch mit ungewohntem Akzent ist eine eigene Fähigkeit, die nicht durch bloßes Wollen entsteht.

Ich hätte einfach üben und warten können. Ich beschloss, ein Werkzeug zu bauen.

Was ist CallCoach?

Eine native iOS-App in Swift mit Apple Intelligence und Live Translation.

Während des Anrufs erkennt sie die Sprache des Gesprächspartners in Echtzeit und zeigt den Text direkt auf dem Bildschirm. Sie analysiert das Gesagte und gibt Hinweise: was antworten, wie weitermachen, welche Frage stellen.

CallCoach in Xcode zum Starten des Simulators und der Tests

Das ist keine Transkription um der Transkription willen. Es ist ein Gesprächsleitfaden-Assistent, der genau dann auftaucht, wenn er gebraucht wird — im laufenden Gespräch, ohne Verzögerung.

Warum Swift und Apple Intelligence?

Ich hätte jeden beliebigen Web-Stack nehmen können. Aber das Web bietet nicht die nötige Geschwindigkeit und native Integration mit Mikrofon und System-APIs.

Apple Intelligence ist eine lokale Sprach-Engine direkt auf dem Gerät. Keine Cloud-Anfragen, keine Verzögerung, keine Abflüsse von Gesprächsdaten. Alles auf dem Telefon.

Live Translation kommt mit akzentgeprägtem Englisch in der nötigen Genauigkeit zurecht. Genau das Richtige für das multinationale Dubai.

Arbeit an der App in Codex — das Fünfstundenfenster für Tokens ist abgelaufen, jetzt warten wir auf das nächste

Wie das die Arbeit verändert hat

Wenn man den Text dessen sieht, was der andere sagt, schwindet die Angst. Man verschwendet keine Energie mehr auf „Was hat er gesagt?“, sondern denkt darüber nach: „Was antworte ich?“.

Vom Überlebensmodus in den Dialogmodus. Ein grundlegender Wandel.

Ich entwickle weiter. Der nächste Schritt ist eine Skriptbibliothek für verschiedene Situationen: Erstgespräch, Einwand, Budgetklärung, Terminvereinbarung. Hinweise, die nicht bloß als Transkription erscheinen, sondern als intelligente kontextbezogene Antwort auf einen konkreten Satz.

Warum ich das erzähle

CallCoach zeigt, wie ich über Produkte nachdenke.

Nicht „Welche Technologie ausprobieren?“, sondern „Welches Problem lösen?“. Das Problem war konkret und persönlich. Die Lösung: nativ, schnell, ohne unnötige Abhängigkeiten.

Ein Designer, der Code schreiben kann, ist kein Entwickler. Doch manchmal verhindert genau das, dass eine Idee in der Warteschlange zur Umsetzung stirbt.

Technische Umsetzung

Technisch habe ich CallCoach als echtes Arbeitswerkzeug gebaut, nicht als Konzept.

Zuerst habe ich Idee und Architektur mit ChatGPT ausgearbeitet: die Produktaufgabe und den Nutzerablauf formuliert und einen umfangreichen Startprompt für Codex vorbereitet. Er sollte ein grundlegendes Swift-Projekt anlegen, Abhängigkeiten einrichten und das erste lauffähige App-Gerüst bauen.

Als das Tokenfenster von Codex erschöpft war, übergab ich das Projekt an Claude Code. Der eigentliche, gehaltvolle Teil der Entwicklung lief dann dort mit Opus 4.7.

Es erwies sich gerade über lange technische Strecken als sehr stark: Es denkt viel nach, verbraucht viele Tokens, hält dafür die Architektur gut zusammen, schreibt sorgfältig zusammenhängenden Code und hilft, die App in einen funktionierenden Zustand zu bringen.

Danach wechselte ich regelmäßig zu Xcode: Builds erstellen, Tests ausführen, Abstürze aufspüren, Fehler an Claude Code zurückgeben und gemeinsam die Problemstellen beheben. Einige Änderungen machte ich direkt in Xcode, wo ich auch Codex und Claude als Assistenten vor Ort angebunden hatte.

Wie die App-Logik aufgebaut ist

Die App ist um die lokale Sprachverarbeitung auf dem Gerät aufgebaut.

Im normalen Modus kann CallCoach den Mikrofonstream hören und eine Live-Transkription anzeigen. Die entscheidende technische Lösung war jedoch die Trennung der Stimmen.

Das Hauptproblem war, dass das Mikrofon bei einem Anruf über Lautsprecher beide Seiten zugleich hört. Dadurch vermischen sich in der Transkription beide Gesprächsseiten, und sie wird fürs Coaching unbrauchbar.

Um das zu lösen, habe ich zwei Betriebsmodi gebaut.

Modus 1 — System Audio

Das ist der Hauptmodus und die empfohlene Variante.

Über ScreenCaptureKit erfasst die App die Systemaudioausgabe, also nur das, was an die Lautsprecher geht. So wird gezielt die Stimme des Gesprächspartners transkribiert, ohne meine eigene Mikrofonstimme aufzunehmen.

Zusätzlich wird das Flag excludesCurrentProcessAudio = true, um die Töne der App selbst auszuschließen.

Beim ersten Start fragt macOS nach der Erlaubnis zur Bildschirmaufnahme — ohne sie lässt sich Systemaudio nicht erfassen.

Modus 2 — Microphone + Push-to-Mute

Das ist das Ausweichszenario.

Er verwendet die normale Mikrofonaufnahme. Wenn ich selbst spreche, kann ich jedoch eine Taste gedrückt halten und die Übertragung von Audiopuffern an die Transkription vorübergehend unterbrechen.

Die Logik ist ganz einfach: Ich spreche und halte die Taste, bin fertig und lasse los, die App hört wieder dem Gesprächspartner zu.

Was im Code umgesetzt wurde

Architektonisch besteht die App aus mehreren separaten Managern, die jeweils einen Teil der Verarbeitungskette verantworten.

AudioCaptureManager

Verantwortlich für die Audioaufnahme über AVAudioEngine.

  • verwendet installTap auf inputNode
  • startRecording() gibt zurück: AsyncStream<AVAudioPCMBuffer>
  • der Pufferstrom wird ohne Probleme mit Folgendem weitergereicht: Actor-Übergängen (actor crossing)
  • parallel wird der Signalpegel über RMS- und dB-Messung berechnet
  • UI-Aktualisierungen werden gesendet an @MainActor über Task

SystemAudioCaptureManager

Eine eigene Klasse, die ich zur Erfassung von Systemaudio über Folgendes ergänzt habe: SCStream.

Erst sie ermöglichte, dass nur die Stimme des Gesprächspartners aus den Lautsprechern in der Transkription landet statt des gesamten akustischen Umfelds.

TranscriptionManager

Diese Schicht nimmt den Audiopufferstrom entgegen und übergibt ihn an SpeechAnalyzer aus dem Speech-Framework.

Anschließend durchläuft sie AsyncThrowingStream<SpeechTranscriptionResult>, trennt vorläufige und endgültige Transkriptionen und steuert explizit die Wechsel zu @MainActor.

Es geht also nicht mehr nur darum, „Ton zu erkennen“, sondern Streaming-Transkription sauber in eine lebendige Oberfläche einzubauen.

CoachingEngine

Eine eigene Logikschicht, die eine gewöhnliche Transkription in ein nützliches Gesprächswerkzeug verwandelt.

  • processNewTranscript(_:) verwendet ein Debounce von 1,5 Sekunden
  • der vorherige Task wird abgebrochen, wenn ein neuer Sprachabschnitt eingeht
  • LanguageModelSession wird einmal pro Sitzung erstellt und danach wiederverwendet
  • der Kontextverlauf bleibt erhalten
  • der Parser verarbeitet Antworten im Format [TYP]: Text mit Rückfall auf .phrase
  • die Gesprächsphase wird anhand von Schlüsselwörtern ermittelt
  • an das Modell gehen ungefähr die letzten 300 Wörter statt des gesamten Transkripts

Zusätzlich habe ich Kontext für den Markt in Dubai eingemischt: Emaar, DAMAC, Binghatti, ROI, Reservierung, Treffen, Zoom und andere typische Gesprächssignale.

ContentView

Hier wird alles zur Benutzeroberfläche verbunden.

  • .task fragt beim Start die Mikrofonberechtigung ab
  • .onChange(segments.count) löst aus: coach.processNewTranscript
  • toggleSession() übergibt Stream und Format an startTranscription
  • Fehler der Manager werden über separate Handler angezeigt: .onChange

Diese Schicht macht die ganze App lebendig: Audioquelle wechseln, Sitzung starten und stoppen, Stummschaltungslogik, Fehlerbehandlung und Hinweise in Echtzeit aktualisieren.

Wie ich die Hinweise trainiert habe

Zusätzlich habe ich das System mit praktischem Kontext gefüttert.

Für Kaltakquise nutzte ich echte Verkaufsskripte: Begrüßung, Gespräch halten, grundlegende Kundenqualifizierung, Budget klären, Zweifel behandeln und auf ein Treffen oder ein ausführliches Zoom-Gespräch abschließen.

Das waren keine abstrakten Vorlagen aus dem Internet, sondern die Logik, die uns bei der Agentur SPI Dubai beigebracht wurde.

Dadurch wurden die Hinweise praxisnäher. Nicht bloß „Antworte irgendetwas Höfliches“, sondern das Gespräch in der richtigen Struktur und in der richtigen Phase fortsetzen.

Zweites Szenario: Vorstellungsgespräche als Produktdesigner

Parallel habe ich einen zweiten Einsatzbereich desselben Ansatzes entwickelt: Vorstellungsgespräche für Produktdesigner.

Dafür trainierte ich das System mit meinen Projekten, Fallstudien und meinem Portfolio. Es sollte nicht bei Kaltakquise helfen, sondern bei Gesprächen, in denen man Fragen zur eigenen Erfahrung schnell, sicher und strukturiert beantworten muss.

Damit wurde CallCoach im Grunde mehr als eine Speech-to-Text-App: ein universeller Gesprächsassistent, der sich an konkrete Kommunikationssituationen anpassen lässt.

Wie der tatsächliche Entwicklungsprozess aussah

Und ganz ehrlich: Für mich ist das auch ein wichtiges Beispiel dafür, wie echte Produktentwicklung heute aussieht.

Die Idee entsteht aus einem eigenen Schmerzpunkt.

Die Architektur wird mithilfe von Sprachmodellen schnell aufgebaut.

Der anspruchsvolle Code entsteht zusammen mit Agenten.

Der letzte Feinschliff erfolgt von Hand in Xcode — durch Builds, Abstürze, Debugging und wiederholte Iterationen.

Keine „Magie des neuronalen Netzes“, sondern ein normaler Engineering-Prozess, durch neue Werkzeuge lediglich beschleunigt.


Änderungsprotokoll / wie CallCoach entstand

1. Die Idee formulieren

  • Ich hielt das konkrete Problem fest: Bei Kaltakquise-Anrufen mit britischen und indischen Akzenten lässt sich ein Teil der Sprache nach Gehör schlicht nicht schnell genug erfassen.
  • Ich definierte die Produktaufgabe: das Gespräch nicht nur transkribieren, sondern beim Weiterführen helfen.
  • Mit ChatGPT erarbeitete ich Konzept, Nutzerablauf und Struktur der künftigen App.
  • Ich erstellte einen umfangreichen Startprompt für Codex, um das Swift-Projektgerüst schnell aufzusetzen.

2. Erster Projektaufbau

  • Codex erstellte das grundlegende Swift-Projekt.
  • Die wichtigsten Abhängigkeiten wurden eingerichtet.
  • Die grundlegende Architektur wurde vorbereitet.
  • Ein erster lauffähiger Prototyp wurde gebaut.

3. Die eigentliche technische Umsetzung

  • Nach Ausschöpfen des Codex-Tokenfensters wurde das Projekt an Claude Code übergeben.
  • Die Hauptentwicklung ging mit Opus 4.7 weiter.
  • Über Claude Code entstand das Kernstück der App: Audioaufnahme, Transkription, Coaching-Logik und Anbindung an die Oberfläche.

4. Das zentrale Produktproblem lösen: Stimmen trennen

  • Das Kernproblem wurde erkannt: Das Mikrofon hört Nutzer und Gesprächspartner zugleich.
  • Zwei Modi wurden umgesetzt:
    • System Audio — Erfassung ausschließlich der Systemaudioausgabe über ScreenCaptureKit
    • Microphone + Push-to-Mute — Ausweichmodus mit manuellem Unterbrechen der Pufferübertragung an die Transkription
  • Hinzugefügt wurde excludesCurrentProcessAudio = true, um die Töne der App selbst auszuschließen.

5. Umgesetzte Komponenten

  • SystemAudioCaptureManager.swift — neue Klasse zur Systemaudioerfassung über SCStream
  • AudioCaptureManager.swift — Audioaufnahme über AVAudioEngine, ergänzt um isMuted
  • TranscriptionManager — Streaming-Transkription über SpeechAnalyzer
  • CoachingEngine — Debounce, Wiederverwendung der Modellsitzung, Satzanalyse, Logik der Gesprächsphasen
  • ContentView.swift — Sitzungssteuerung, Audioquellenwahl, Fehler, Schaltflächen und Oberfläche
  • Info.plist — Berechtigungen für die Systemaufnahme
  • project.pbxproj — Einbindung von ScreenCaptureKit.framework

6. Debugging und Tests

  • Build und Ausführung liefen über Xcode.
  • Bei jedem App-Absturz wurde der Fehler an Claude Code zurückgegeben.
  • Die Korrekturen erfolgten iterativ: Xcode → Absturz/Fehler → Claude Code → Korrektur → neuer Build.
  • Einige schnelle Änderungen entstanden direkt in Xcode mit angebundenem Codex und Claude.

7. Training für reale Szenarien

  • Für Kaltakquise wurden echte Verkaufsskripte ins System aufgenommen:
    • Begrüßung
    • gewöhnlicher Smalltalk
    • Kundenqualifizierung
    • Interesse ermitteln
    • Abschluss auf ein Treffen oder Zoom-Gespräch
  • Die Skripte basierten auf realer Praxis und Schulung bei SPI Dubai.
  • Parallel entstand ein zweites Anwendungsszenario: Hilfe bei Vorstellungsgesprächen als Produktdesigner.
  • Dafür wurde das Modell mit meinen Projekten, Fallstudien und meinem Portfolio trainiert.

8. Das Ergebnis

  • lokale Transkription ohne Datenübertragung in die Cloud
  • Echtzeithinweise während des Gesprächs
  • eigene Logik für Verkauf und Interviews
  • nativer Stack ohne Web-Notbehelfe
  • ein funktionierendes Produkt, gebaut mit ChatGPT + Codex + Claude Code + Xcode